Frage an android, android-listview – Wählen Sie mehrere Elemente in der Listenansicht aus und ändern Sie die Farbe nur für das ausgewählte Element

6

Ich möchte eine Ansicht erstellen, in der ich mehrere Elemente aus der Listenansicht auswählen und gleichzeitig die Farbe des ausgewählten Listenelements ändern und dieses Element in meiner Arrayliste speichern kann. Meine Liste wird wie folgt angezeigt:

Aber als ich es mal gescrollt habe. Es zeigt mir 1 weiteres ausgewähltes Element, auch wenn ich es nicht so auswähle:

Aber ich möchte, dass sich nur die Farbe des Listenelements ändert, auf die ich klicken werde ...

Ich benutze den Code als:

<code>     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;
 }    
</code>

}

und in der OnCreate () Methode,

<code>         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);
        });
</code>
Dies liegt daran, dass in der Android-Liste recycelt wird, wenn Sie die Liste scrollen. Sujit

Deine Antwort

7   die antwort
3

dass es sich um das Recycling von Ansichten handelt. Wenn ich mich an die richtige Einstellung erinnere, beseitigt dies das Recycling und behebt das Problem, aber es ist hier nicht die beste Option.

<code>@Override
public int getItemViewType(int position) {
    return IGNORE_ITEM_VIEW_TYPE;
}
</code>
Danke @Niko für deine Unterstützung .. Ich habe die Lösung :) Kanika
Sie überschreiben diese Methode für die Adapterklasse. Niko
Nein, es funktioniert nicht ... wo diese Methode zu setzen? Kanika
Fügen Sie auch Folgendes hinzu: @Override public int getViewTypeCount () {return 1; } Niko
Nein, es funktioniert nicht .. Kanika
0

Die Lösung (Idee) ausJason Robinson ist gut, aber es gibt einen Fehler! Sie können Artikel nicht von ArrayList entfernen, da dieser Wert !!!
Die Methode ArrayList.remove (int) nimmt den Index des Elements als Parameter!
Wenn Sie eine verwenden möchtenArrayList<<code>Integer</code>>, müssen Sie den Index des Elements finden, das Sie entfernen möchten. Zum Beispiel:

<code>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;
}
</code>

Oder verwenden Sie die MethodeArrayList.indexOf(Object) Index erhalten.

Und nun, wie Sie von FragmenList oder ListActivity einen Verweis auf Ihren Adapter erhalten. Verwenden Sie einfach die Klassenvariable:

<code>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
    }
}
</code>
Eine andere Lösung für das erste von Ihnen erwähnte Problem besteht darin, ein HashSet anstelle einer ArrayList zu verwenden. HashSet.remove () nimmt das fragliche Objekt und nicht einen Index:developer.android.com/reference/java/util/… Jabari
1

te. Überprüfen Sie im getView des Adapters, ob die Position der ausgewählten Position in der Listenansicht und setBackgroundColor für die dortige Ansicht entspricht. Das wird funktionieren.

0

wenn Sie auf ein Listenelement in der Liste klicken, und dieses Flag aktivieren, um festzustellen, ob das Element in der getView () -Methode des Adapters angeklickt wurde oder nicht.

pls helfen, wie man das umsetzt .. Ich stecke in diesem Problem von gestern fest und habe noch keine Lösung bekommen :( Kanika
10

dass Sie die Hintergrundfarbe für die Ansicht festlegen. Wenn Sie dann scrollen, wird diese Ansicht aufgrund der Verwendung von am Ende wiederverwendetconvertView. Genau das solltest du tun, also gute Arbeit dort.

Dies bedeutet jedoch, dass Listenelemente ausgewählt werden, wenn dies nicht der Fall sein sollte. Um dies zu beheben, muss IhrgetView() Methode muss die Hintergrundfarbe auf den Standardwert zurücksetzen. Ich weiß nicht, wie die Farbe ursprünglich war, aber ich gehe davon aus, dass sie transparent war. Sie würden also sagen:

<code>textView.setBackgroundColor(android.R.color.transparent);
</code>

Jetzt stellen Sie die Hintergrundfarbe auf die Standardfarbe ein. Wenn Sie jedoch vom ausgewählten Objekt weg und wieder zurück blättern, wird der Hintergrund transparent und nicht mehr der ausgewählte Hintergrund. Um dies zu beheben, geben Sie einArrayList vonInteger Werte innerhalb Ihrer Adapterklasse. Wenn ein Element angeklickt wird undonItemClick() ausgelöst wird, fügen Sie die Artikelposition hinzuArrayList. Angenommen, Sie haben:

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

in Ihrer Adapterklasse. Dann ist deinonItemClick Methode würde so aussehen:

<code>@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();
}
</code>

Also endlich in deinemgetView() Methode, füge diese Zeile hinzu:

<code>textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);  
</code>
@Kanika Hey, ich habe auch den gleichen Fehler "Kann nicht von AdapterView <capture # 1-of?> Nach" umwandeln und kann nicht herausfinden. Bitte sag mir, wie du eine Lösung hast. Bitte hilf .. :( Kinjal Shah
Funktioniert super für mich! user2999943
@Kanika Ich habe ArrayList in den Adapter eingefügt und versucht, über die Aktivitätsklasse onItemClick darauf zuzugreifen. Es wird jedoch weiterhin "Kann nicht von AdapterView <capture # 1-of?> MyAdapter" übertragen werden. Bitte helfen Sie! user3014926
Du brauchst dasArrayList im Adapter, und greifen Sie dann von deronItemClick Methode in der Aktivität. Sie können wählen, was immer Sie wollen, es muss nicht das sein, was ich wörtlich geschrieben habe. Ich würde empfehlen, eine Getter-Methode zu verwenden. Jason Robinson
0

<code>if(selectedIds.contains(pos) {
         selectedIds.remove(pos); -> **selectedIds.remove(selectedIds.indexOf(pos));**
     }
     else {
         selectedIds.add(pos);
     }
</code>
1

es wird in einer anderen Klasse wiedergegeben, um zu vermeiden, dass Sie den Hintergrund für den entsprechenden Ansichtsinhaber festlegen müssen. Ich zeige ein Beispiel, das für mich gut funktioniert.

<code>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;


     }
</code>

Probe o / p

Verwandte Fragen