Pytanie w sprawie android-listview, android – Wybierz wiele elementów z listy i zmień kolor tylko wybranego elementu

6

Chcę zrobić widok, w którym mogę wybrać wiele elementów z listy, a także obok siebie zmieniam kolor wybranego elementu listy i zapisuję ten element w mojej arraylist .. Moja lista jest pokazana poniżej:

Ale kiedy go przewijałem .. Pokazuje mi się jeszcze 1 wybrany element, nawet ja go nie wybieram jak:

Ale chcę, aby zmienił się tylko ten kolor elementu listy, w którym kliknę ...

Używam kodu jako:

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

}

oraz w metodzie OnCreate (),

<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>
Dzieje się tak dlatego, że na liście Android jest przetwarzany podczas przewijania listy. Sujit

Twoja odpowiedź

7   odpowiedzi
0

Rozwiązanie (pomysł) zJason Robinson jest dobry, ale jest błąd! Nie możesz usunąć elementu z ArrayList przez jego wartość !!!
Metoda ArrayList.remove (int) przyjmuje indeks elementu jako parametr!
Jeśli chcesz użyćArrayList<<code>Integer</code>>, musisz znaleźć indeks pozycji, którą chcesz usunąć. Na przykład:

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

Lub użyj metodyArrayList.indexOf(Object) uzyskać indeks.

A teraz, jak uzyskać odniesienie do adaptera z FragmenList lub ListActivity. Po prostu użyj zmiennej klasy:

<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>
Innym rozwiązaniem pierwszego problemu, o którym wspomniałeś, jest użycie HashSet zamiast ArrayList. HashSet.remove () pobiera dany obiekt, a nie indeks:developer.android.com/reference/java/util/… Jabari
1

Śledź elementy wybrane na liścieWidok w działaniu. W getView adaptera sprawdź, czy pozycja jest równa wybranej pozycji w listview i setBackgroundColor dla widoku tam. To zadziała.

0

Korekta odpowiedzi udzielonej przez @JasonRobinson:

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

Trzeba ustawić flagę po kliknięciu dowolnego elementu listy z listy i zaznaczeniu tej flagi, aby określić pogodę, której element został kliknięty, lub nie w metodzie getView () adaptera.

pls pomagają jak to zrealizować .. Utknąłem w tym problemie od wczoraj i jeszcze nie dostałem żadnego rozwiązania :( Kanika
3

Zetknąłem się również z tym problemem i dowiedziałem się, że to dlatego, że przetwarzamy widoki. Jeśli dobrze pamiętam, ustawienie to usuwa recykling i rozwiązuje problem, ale nie jest to najlepsza opcja tutaj.

<code>@Override
public int getItemViewType(int position) {
    return IGNORE_ITEM_VIEW_TYPE;
}
</code>
Nie, to nie działa ... gdzie umieścić tę metodę? Kanika
Nie, to nie działa .. Kanika
Zastąpisz tę metodę dla klasy adaptera. Niko
Dodaj także to: @Override public int getViewTypeCount () {return 1; } Niko
Dzięki @Niko za wsparcie ... Mam rozwiązanie :) Kanika
1

Cokolwiek spróbujesz zrobić z ConvertView w słuchaczu itemClick, odzwierciedli się w innej klasie, aby uniknąć sytuacji, w której musisz ustawić tło dla odpowiedniego uchwytu widoku, pokazuję próbkę, która działa dobrze dla mnie,

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

próbka o / p

10

Problem polega na tym, że ustawiasz kolor tła na widok, a kiedy przewijasz, ponownie używasz tego widoku z powodu użyciaconvertView. To jest dokładnie to, co powinieneś robić, więc dobra robota tam.

Ale oczywiście oznacza to, że elementy listy są wybierane, gdy nie powinny. Aby to naprawić, twójgetView() metoda musi zresetować kolor tła do wartości domyślnej. Nie wiem, jaki był pierwotnie kolor, ale założę, że był przezroczysty. Więc umieściłbyś:

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

Teraz ustawiasz kolor tła na domyślny, ale jeśli przewiniesz od wybranego elementu, a następnie z powrotem do niego, będzie miał przezroczyste tło zamiast wybranego tła. Aby rozwiązać ten problem, umieśćArrayList zInteger wartości wewnątrz klasy adaptera. Po kliknięciu elementu ionItemClick() jest aktywowany, dodaj do tego pozycję pozycjiArrayList. Na przykład powiedz, że masz:

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

w klasie adaptera. Więc twojaonItemClick metoda wyglądałaby tak:

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

Więc w końcu w twoimgetView() metoda, dodaj tę linię:

<code>textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);  
</code>
Hej dzięki bardzo za twój anwer, ale kiedy dodam publiczny ArrayList <Integer> selectedIds = new ArrayList <Integer> (); w mojej klasie adaptera, a następnie w onlistItemClick nie pobiera (rodzic) (. ItemsAdapter) .selectedIds; daje mi tutaj błąd i nie wyodrębnia zmiennej selectedIds z klasy adaptera :( pls pomaga co robić Kanika
PotrzebujeszArrayList w adapterze, a następnie uzyskaj do niego dostęp zonItemClick metoda w działaniu. Możesz wybrać, co chcesz zrobić, nie musi to być to, co napisałem dosłownie. Polecam użycie metody getter. Jason Robinson
@Kanika Jak to w końcu rozwiązałeś? Dostaję ten sam błąd i nie mogę rozwiązać problemu z jakiegoś powodu, który mówi mi, że nie można rzutować z AdapterView <przechwytywanie # 1-of?> do mojej klasy eric.itzhak
@Kanika Hej, mam także ten sam błąd, że „Nie można rzucać z AdapterView <przechwytywanie # 1-z?> Do” .. i nie można obliczyć. Plz powiedz mi, jak masz rozwiązanie .. plz help .. :( Kinjal Shah

Powiązane pytania