Pergunta sobre android, android-listview – Selecione vários itens da lista e altere a cor apenas do item selecionado

6

Eu quero fazer uma visão onde eu possa selecionar vários itens de listview e também lado a lado estou mudando a cor do item da lista selecionada e salvar esse item em meu arraylist ... Minha lista é mostrada como abaixo como:

Mas quando eu costumava rolá-lo .. Ele está me mostrando mais 1 item selecionado, mesmo não estou selecionando-o como:

Mas eu quero que apenas essa cor do item da lista mude onde eu vou clicar ...

Eu estou usando o código como:

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

}

e no método 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>
Isso ocorre porque na lista do Android é reciclado quando você rola a lista. Sujit

Sua resposta

7   a resposta
10

O problema aqui é que você está definindo a cor do plano de fundo para a visualização e, em seguida, ao rolar, você acaba reutilizando essa exibição devido ao usoconvertView. Isto é exatamente o que você deveria estar fazendo, tão bom trabalho lá.

Mas, claro, isso significa que os itens da lista são selecionados quando não deveriam. Para corrigir isso, seugetView() método precisa redefinir a cor do plano de fundo para seu valor padrão. Eu não sei qual era a cor original, mas vou assumir que era transparente. Então você colocaria:

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

Então, agora você está definindo a cor do plano de fundo como padrão, mas se você sair do item selecionado e voltar a ele, ele terá um plano de fundo transparente em vez do plano de fundo selecionado. Para resolver isso, coloque umArrayList doInteger valores dentro da sua classe de adaptador. Quando um item é clicado eonItemClick() é acionado, adicione a posição do item a essaArrayList. Por exemplo, digamos que você tenha:

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

na sua classe de adaptador. Então, seuonItemClick método ficaria assim:

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

Então, finalmente, no seugetView() método, adicione esta linha:

<code>textView.setBackground(selectedIds.contains(position) ? R.color.result_image_border : androi.R.color.transparent);  
</code>
@Kanika Ei eu também tenho o mesmo erro que "Não é possível converter de AdapterView <captura # 1-de?> Para" ..e não consigo descobrir.assim plz diga-me como você tem solução .. plz ajuda .. :( Kinjal Shah
@ Kanika Eu coloquei ArrayList no adaptador e tentei acessá-lo a partir do onItemClick na classe de atividade. Mas ainda mostrando "Não é possível converter de AdapterView <capture # 1-of?> MyAdapter". Por favor ajude! user3014926
Funciona muito bem para mim! user2999943
Ei, muito obrigado pelo seu apoio .. Finalmente eu tenho a solução :) Kanika
1

Acompanhe os itens selecionados no listView na Activity. No getView do adaptador, verifique se position é igual à posição selecionada no listview e setBackgroundColor para a view lá. Isso vai funcionar.

3

Eu também encontrei este problema, e descobri que é porque a reciclagem de pontos de vista. Se eu me lembro direito de definir isso remove reciclagem e corrige o problema, mas não é a melhor opção aqui.

<code>@Override
public int getItemViewType(int position) {
    return IGNORE_ITEM_VIEW_TYPE;
}
</code>
Não, não está funcionando .. Kanika
Não, não está funcionando ... onde colocar esse método? Kanika
Obrigado @Niko pelo seu apoio .. Eu tenho a solução :) Kanika
Adicione também isto: @Override public int getViewTypeCount () {return 1; } Niko
Você substitui esse método para a classe do adaptador. Niko
1

O que quer que você tente fazer com o ConvertView no listener do itemClick, ele irá refletir em alguma outra classe, para evitar que você precise definir o plano de fundo para o titular da visualização correspondente, eu mostro uma amostra que funciona bem para mim,

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

amostra o / p

0

Você precisa definir o sinalizador quando clicar em qualquer item da lista e marcar esse sinalizador para determinar o tempo em que o item foi clicado ou não no método getView () do adaptador.

pls ajuda como implementar isso .. Eu estou preso neste problema de ontem e não obteve qualquer solução ainda :( Kanika
0

Uma correção sobre a resposta dada por @JasonRobinson:

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

A solução (ideia) deJason Robinson é bom, mas há um erro! Você não pode remover o item da ArrayList pelo seu valor !!!
O método ArrayList.remove (int) pega o índice do item como parametr!
Se você quiser usar umArrayList<<code>Integer</code>>, você precisa encontrar o índice ot item que você deseja remover. Por exemplo:

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

Ou use o métodoArrayList.indexOf(Object) para obter o índice.

E agora, como obter referência ao seu adaptador de FragmenList ou ListActivity. Basta usar a variável de classe:

<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>
Outra solução para o primeiro problema que você mencionou é usar um HashSet em vez de um ArrayList. HashSet.remove () leva o objeto em questão em vez de um índice:developer.android.com/reference/java/util/… Jabari

Perguntas relacionadas