2011-06-17 1 views
2

J'essaie de supprimer l'élément sélectionné d'un ListView et le problème est que lorsque je supprime le contenu sélectionné et actualise l'adaptateur, la position du contenu restant change, donc à cause de cela à un moment donné de supprimer à nouveau le contenu, il donne IndexOutOfBoundsException. Quelqu'un peut-il me dire comment résoudre ce problème?Problème dans la suppression du contenu ListView sélectionné

Voici mon code pour supprimer l'élément sélectionné.

public View getView(final int position, View convertView, ViewGroup parent) { 

    View view = null; 
    if (convertView == null) { 
     LayoutInflater inflator = mActivity.getLayoutInflater(); 
     view = inflator.inflate(R.layout.main, null); 

     final ViewHolder viewholder = new ViewHolder(); 
     viewholder.tvTitle = (TextView) view.findViewById(R.id.txttitle); 
     viewholder.imgdelete = (ImageButton) view.findViewById(R.id.imgdelete); 


     viewholder.imgdelete.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 

        list.remove(position); 
        notifyDataSetChanged(); 
      } 
     }); 
     view.setTag(viewholder); 
    } 
    else 
    { 
     view = convertView; 
    } 

    ViewHolder viewholder = (ViewHolder) view.getTag(); 
    viewholder.tvTitle.setText(list.get(position).getmTitle()); 

      return view; 
} 

Voici mon erreur logcat

 06-17 13:01:41.715: ERROR/AndroidRuntime(4284): FATAL EXCEPTION: main 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284): java.lang.IndexOutOfBoundsException: Invalid index 5, size is 5 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at java.util.ArrayList.remove(ArrayList.java:406) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at com.list.AdapterClass$1.onClick(AdapterClass.java:66) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at android.view.View.performClick(View.java:2408) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at android.view.View$PerformClick.run(View.java:8816) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at android.os.Handler.handleCallback(Handler.java:587) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at android.os.Handler.dispatchMessage(Handler.java:92) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at android.os.Looper.loop(Looper.java:123) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at java.lang.reflect.Method.invokeNative(Native Method) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at java.lang.reflect.Method.invoke(Method.java:521) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
06-17 13:01:41.715: ERROR/AndroidRuntime(4284):  at dalvik.system.NativeStart.main(Native Method) 

Répondre

3

Parce que BaseAdapter est meilleur lorsque vous travaillez avec des vues personnalisées.

Voici un exemple de code ..

public class AdapterClass extends BaseAdapter{ 

     List<MyModelClass> list; 
     Activity mActivity; 

     public AdapterClass(Activity context,List<MyModelClass> objects) 
     { 
       this.list = objects; 
       this.mActivity = context; 
     } 

     static class ViewHolder{ 
       protected TextView tvTitle; 
       protected ImageButton imgdelete; 
     } 
     @Override 
     public View getView(final int position, View convertView, ViewGroup parent) { 


       final ViewHolder viewholder; 
       if (convertView == null) 
       { 
         viewholder = new ViewHolder(); 
         LayoutInflater inflator = mActivity.getLayoutInflater(); 
         convertView = inflator.inflate(R.layout.mainn, null); 
         viewholder.tvTitle = (TextView) convertView.findViewById(R.id.txttitle); 
         viewholder.imgdelete = (ImageButton) convertView.findViewById(R.id.imgdelete); 
         convertView.setTag(viewholder); 
       } 
       else 
       { 
        viewholder = (ViewHolder)convertView.getTag(); 
       } 
        viewholder.imgdelete.setOnClickListener(new OnClickListener() { 

          @Override 
          public void onClick(View v) { 

            System.out.println("position - " + position + " size - "+ list.size()); 
            list.remove(position); 
            notifyDataSetChanged(); 
            Toast.makeText(mActivity, "deleted", Toast.LENGTH_LONG).show(); 
          } 
        }); 

       viewholder.tvTitle.setText(list.get(position).getmTitle()); 
       return convertView; 
     } 
     @Override 
     public int getCount() { 
      return list.size(); 
     } 
     @Override 
     public Object getItem(int position) { 
      return position; 
     } 
     @Override 
     public long getItemId(int position) { 
      return position; 
     } 
} 
0

u utiliser le gestionnaire de mettre à jour le listview

private Handler handler=new Handler() 
{ 
     public void handleMessage(Message msg) { 
     ArrayAdapter aa=new ArrayAdapter<String>(nextScreen.this,android.R.layout.test_list_item,mArray); 
     list.setAdapter(aa); 
     aa.notifyDataSetChanged(); 
     list.invalidate();    
} 

}; 

si tu veux mettre à jour le listview appeler le gestionnaire comme celui-ci

handler.sendEmptyMessage(0); 
+0

il n'y a pas de problème pour le problème est gestionnaire de indexoutofboundexception –

+0

je pense que u doivent supprimer l'image pour ce postion particulier ?? – kannappan

+1

je veux supprimer l'élément sélectionné de la liste –

0

Utiliser le conc Ept de Handler ici. Etape 1 Déclarer une constante octet final statique privé UPDATE_LIST = 100;

Etape 2 Appelez le gestionnaire onclick du bouton

viewholder.imgdelete.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 

        Message msg = new Message(); 
       msg.what = UPDATE_LIST; 
       msg.arg1 = position 
       updateListHandler.sendMessage(msg); 
      } 
     }); 

Etape 3 Définir le gestionnaire

private Handler updateListHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      switch (msg.what) { 
      case UPDATE_LIST: 
      int position = msg.arg1; 
       list.remove(position); 
       arrayAdapter.notifyDataSetChanged(); 
       break; 

      } 
      ; 
     }; 
    }; 

Voir ma réponse àHow to divide and load a ListView in multiple parts?

Merci Deepak

+0

toujours il ya le même problème de indexoutofboundexception –

1

Pour supprimer la liste sélectionnée ...

1) enlever notifyDataSetChanged();

2) mettre la position elle-même argument pour list.remove(position);

OU:

suivre les étapes suivantes:

1) prenez une case à cocher dans la vue liste. certainement vous avez la liste dynamiquement et montrer dans l'affichage de l'adaptateur.

2) en public Voir getView() holder.checkBox.setOnCheckedChangeListener (nouveau OnCheckedChangeListener() {

  @Override 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 

       String updateall; 
       DBConnect sts1 = new DBConnect(getApplicationContext(), "your database name"); 


       if(holder.checkBox.isChecked()){ 

        updateall = "UPDATE Sever_Contain SET setcheck = 'true' WHERE id ="+cupos; 
        System.out.println(updateall);    

       }else{ 

        updateall = "UPDATE Sever_Contain SET setcheck = 'false' WHERE id ="+cupos; 
        System.out.println(updateall); 
       } 
        sts1.execNonQuery(updateall);     
        System.out.println(map); 
        sts1.close(); 
      } 
     }); 

3) sur l'événement de suppression de clic suffit d'ajouter: del.setOnClickListener (nouveau OnClickListener() {

 @Override 
     public void onClick(View v) { 
      String deleteall = "DELETE from Sever_Contain where setcheck='true'"; 
      if(sts.isOpen()==false) 
       sts.openDataBase(); 

       sts.execNonQuery(deleteall);      
       sts.close(); 

     } 
    }); 

4) où vous commencez à cette intention de créer méthode onResume() pour mettre à jour.

Cela va vous aider.

0

ce que je fais quand je dois supprimer un élément d'une listview est: dans le onclick du listview simplement supprimer l'élément du tableau de chaînes (à l'aide que je alimenter le listview) puis appeler quelque chose comme ceci:

listview.setAdapter(new ArrayAdapter<String>(this,R.layout.listviewactivity ,your_string_array)); 

fonctionne comme un charme et pas besoin de gérer un indice sur excpetion lié ... :) elle pourra être utile

+0

tout d'abord ce n'est pas un tableau de chaînes c'est une liste il suffit de lire la ma question s'il vous plaît. –

+0

qu'est-ce que le listview contient? pouvez-vous spécifier – Nitin

0

Essayez:

viewholder.imgdelete.setTag(position); 
    viewholder.imgdelete.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

       list.remove((Integer)v.getTag()); 
       notifyDataSetChanged(); 
     } 
    }); 

Vous devez supprimer la finale mot-clé du paramètre de position. Essayez BaseAdapter au lieu de ArrayAdapter.

+0

pas mon pote de travail la liste ne se rafraîchit pas –

+0

espérons que votre "liste" variable est un Arraylist ou une autre structure Liste. Dans mon exemple, si vous déplacez viewholder.imgdelete.setTag (position); above viewholder.tvTitle.setText (list.get (position) .getmTitle()); ça marchera :) –

+0

J'ai essayé mais je n'ai pas travaillé, donc si vous voulez, je peux vous fournir ma source complète. –

Questions connexes