2012-04-11 15 views
5

Voglio vedere dove posso selezionare più elementi da listview e anche fianco a fianco sto cambiando il colore dell'elemento selezionato dell'elenco e salvando quell'elemento nel mio arraylist. .La mia lista è mostrata come di seguito come:Seleziona più elementi da listview e cambia colore solo dell'elemento selezionato

enter image description here

Ma quando ho usato per scorrere esso .. E mi sta mostrando 1 più voce selezionata, anche io non sto selezionando le cose come:

enter image description here

Ma voglio che solo quel colore elemento della lista dovrebbe cambiare dove sarò clicca ...

Sto usando il codice come: metodo

 private class ItemsAdapter extends ArrayAdapter<String> { 
List<String> items; 
    Context context; 
    private LayoutInflater inflater; 
    public ItemsAdapter(Context context, List<String> part_array_list) { 
    super(context, R.layout.part_list, R.id.label,part_array_list); 

    inflater = LayoutInflater.from(context) ; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     TextView textView ; 
    String item = (String) this.getItem(position); 

     if (convertView == null) { 
     convertView = inflater.inflate(R.layout.part_list, null); 

     // Find the child views. 
     textView = (TextView) convertView.findViewById(R.id.label); 


     // Optimization: Tag the row with it's child views, so we don't have to 
     // call findViewById() later when we reuse the row. 
     convertView.setTag(new ListViewHolder(textView)); 


     } 
     // Reuse existing row view 
     else { 
     // Because we use a ViewHolder, we avoid having to call findViewById(). 
     ListViewHolder viewHolder = (ListViewHolder) convertView.getTag(); 

     textView = viewHolder.getTextView() ; 

     } 


     textView.setText(part_array_list.get(position));  

     return convertView; 


     } 
     } 
     /** Holds child views for one row. */ 
      private class ListViewHolder { 

private TextView textView ; 
public ListViewHolder() {} 
public ListViewHolder(TextView textView) { 

    this.textView = textView ; 
} 

public TextView getTextView() { 
    return textView; 
} 
public void setTextView(TextView textView) { 
    this.textView = textView; 
}  

}

e in OnCreate(),

  final ArrayAdapter<String> part_list_adapter=new ItemsAdapter(AssetSearch.this, part_array_list); 
     //PartNumber_List.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 
    PartNumber_List.setAdapter(part_list_adapter); 

    PartNumber_List.setOnItemClickListener(new OnItemClickListener() { 

    @Override 
    public void onItemClick(AdapterView<?> parent, View v, int position, 
      long id) { 
     ListViewHolder viewHolder = (ListViewHolder) v.getTag(); 
     viewHolder.getTextView().setBackgroundColor(R.color.result_image_border); 

     String item=(String) part_list_adapter.getItem((int) id); 
     }); 
+0

Questo perché nell'elenco Android viene riciclato quando si scorre l'elenco. – Sujit

risposta

9

Il problema qui è che si sta impostando il colore di sfondo per la vista, quindi quando si scorre, si finisce riutilizzando quella vista a causa dell'uso di convertView. Questo è esattamente quello che dovresti fare, quindi buon lavoro lì.

Ma, ovviamente, questo significa che le voci dell'elenco vengono selezionate quando non dovrebbero essere. Per risolvere questo problema, il tuo metodo getView() deve reimpostare il colore di sfondo sul valore predefinito. Non so quale sia il colore originale, ma suppongo che fosse trasparente. Quindi, si dovrebbe mettere:

textView.setBackgroundColor(android.R.color.transparent); 

Così ora si sta impostando il colore di sfondo al suo default, ma se si scorre lontano dalla voce selezionata, poi di nuovo ad esso, avrà uno sfondo trasparente al posto del selezionato sfondo. Per risolvere questo problema, inserisci un valore ArrayList di valori Integer all'interno della classe dell'adattatore. Quando viene fatto clic su un elemento e viene attivato onItemClick(), aggiungere la posizione dell'articolo a quello ArrayList. Ad esempio, supponiamo di avere:

public ArrayList<Integer> selectedIds = new ArrayList<Integer>(); 

nella classe dell'adattatore.Poi, il metodo di onItemClick sarebbe simile a questa:

@Override 
public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 

    ArrayList<Integer> selectedIds = ((ItemsAdapter) parent).selectedIds; 
    Integer pos = new Integer(position); 
    if(selectedIds.contains(pos) { 
     selectedIds.remove(pos); 
    } 
    else { 
     selectedIds.add(pos); 
    } 

    parent.notifyDataChanged(); 
} 

Così, finalmente, nel metodo getView(), aggiungere questa riga:

textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent); 
+0

Hey grazie mille per il tuo anwer ma quando aggiungo ArrayList pubblico selectedIds = new ArrayList (); nella mia classe adapter, quindi in onlistItemClick, non sta prendendo ((ItemsAdapter) parent) .selectedIds; mi sta dando un errore qui e non estrae selectIds variabile dalla classe adapter :(pls help cosa fare – Kanika

+0

È necessario 'ArrayList' nell'adattatore, quindi accedervi dal metodo' onItemClick' nell'attività.È possibile scegliere qualsiasi cosa vogliate fare, non Devo essere quello che ho scritto testualmente, raccomanderei l'uso di un metodo getter –

+0

Hey pls risolvere questo pr oblem .. Non sono in grado di ..AM non ottenendo che come un arraylist dovrebbe comunicare tra il metodo OnItemClick e arrayaspater ?? Se ho creato un arraylist nella classe dell'adattatore, quindi non sono in grado di farlo nel metodo OnItemClick ?? aiuto pls :( – Kanika

1

Tieni traccia degli elementi selezionati nella lista Visualizza nell'attività. Nel getView dell'adattatore controllare se la posizione è uguale alla posizione selezionata in listview e setBackgroundColor per la vista lì. Questo funzionerà.

3

Ho anche riscontrato questo problema e ho scoperto che è perché le visualizzazioni di riciclaggio. Se ricordo bene, questa impostazione rimuove il riciclaggio e risolve il problema, ma non è l'opzione migliore qui.

@Override 
public int getItemViewType(int position) { 
    return IGNORE_ITEM_VIEW_TYPE; 
} 
+0

No non funziona ... dove mettere questo metodo ?? – Kanika

+0

Si esegue l'override di questo metodo per la classe dell'adattatore. – Niko

+0

Non funziona. – Kanika

0

è necessario impostare flag quando si fa clic su qualsiasi elemento della lista dalla lista e controllare questo flag per determinare tempo l'oggetto è stato fatto clic o meno nel metodo l'adattatore che si GetView().

+0

pls aiuto come implementare questo .. Sono bloccato in questo problema da ieri e non ho ancora trovato alcuna soluzione :( – Kanika

1

Qualunque cosa si tenta di fare con ConvertView in itemClick ascoltatore si rifletterà in qualche altra classe, al fine di evitare che è necessario impostare lo sfondo per corrispondente vista titolare, mi presento qualche campione che funziona bene per me,

public View getView(final int position, View convertView, ViewGroup parent) { 
     System.gc(); 
     final ViewHolder holder; 

     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.albumlist, null); 
      holder = new ViewHolder(); 
      holder.albumName = (TextView) convertView.findViewById(R.id.albumDetails); 

      convertView.setTag(holder); 
     } 
     else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 


     holder.albumName.setText(albumData[position][0]); 

     holder.albumName.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       holder.albumName.setBackgroundColor(R.color.black); 


      }}); 

     return convertView; 
} 

    class ViewHolder { 

     TextView albumName; 


    } 

del campione o/p enter image description here

0

Una correzione della risposta data dal @JasonRobinson:

if(selectedIds.contains(pos) { 
     selectedIds.remove(pos); -> **selectedIds.remove(selectedIds.indexOf(pos));** 
    } 
    else { 
     selectedIds.add(pos); 
    } 
0

La soluzione (idea) da Jason Robinson è buono, ma c'è un errore! Non puoi rimuovere l'oggetto da ArrayList dal suo valore !!!
Metodo ArrayList.remove (int) prende l'indice dell'oggetto come parametro!
Se si desidera utilizzare uno ArrayList<Integer>, è necessario trovare l'indice o l'elemento che si desidera rimuovere. Per esempio:

private int getIndex(int value) { 
    int index = -1; 

    for(int i=0; i<selectedIds.size(); i++) { 
     if(selectedIds.get(i)==value) { 
      index = i; 
      break; 
     } 
    } 

    return index; 
} 

O uso metodo ArrayList.indexOf(Object) per ottenere indice.

E ora, come ottenere il riferimento all'adattatore da FragmenList o ListActivity. Basta usare la variabile di classe:

public class SimpleFragment extends ListFragment { 
    private MyCustomAdapter mAdapter; 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     mAdapter = new MyCustomAdapter(getActivity(), R.layout.row_layout); 
     setListAdapter(mAdapter); 
    } 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 
     // now you have an access to your adapter through class variable mAdapter 
    } 
} 
+0

Un'altra soluzione al primo problema che hai menzionato è di usare un HashSet invece di un ArrayList. HashSet.remove() prende l'oggetto in questione anziché un indice: http://developer.android.com/reference/java/util/HashSet.html#remove(java.lang.Object) – Jabari

Problemi correlati