Listview items losing color when using the scroll bar

Asked

Viewed 396 times

0

I’m using baseAdapter:

@Override
public View getView(int posicao, View convertview, ViewGroup parent) {

    View view = convertview;
    ViewHolder holder = null;

    if (view == null) {
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.itens_lista, parent, false);
        holder.itemNome = (TextView) view.findViewById(R.id.itemNome);
        holder.itemEndereco = (TextView) view
                .findViewById(R.id.itemEndereco);
        view.setTag(holder);

    } else {

        holder = (ViewHolder) view.getTag();

    }

    Telefone item = getItem(posicao);
    holder.itemNome.setText(item.getNome());
    holder.itemEndereco.setText(item.getTelefone());
    return view;
}

But the items are "bugged":

  1. When I select an item it turns red background color, then I scroll and the color disappears back to the original, because I’m using viewHolder and the view is "recycled or reused";
  2. There are items that have a red background color other than the selected item.
  • Do you want to change the color whenever you click? That’s it?

  • Yes... I already got it, but have more problems described above are 3 problems...

3 answers

1

Hey, buddy, here’s the deal:

Every time you roll a Listview, items that "disappear" up or down are destroyed.

Then, when they are recreated again, they return to their original state, without their customization.

What you can do is create an Adapter and set that state, as in the example below:

public class MySimpleArrayAdapter extends ArrayAdapter<Item> {
  private final Context context;
  private final Item[] values;

  public MySimpleArrayAdapter(Context context, Item[] values) {
    super(context, R.layout.your_row_layout, values);
    this.context = context;
    this.values = values;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context  .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.your_row_layout, parent, false);

     TextView itemNome= (TextView) rowView.findViewById(R.id.itemNome);
     TextView itemEndereco= (TextView) rowView.findViewById(R.id.itemEndereco);
     CheckBox check = (CheckBox)rowView.findViewById(R.id.check);


     Item item = getItem(position);

     itemNome.setText(item.getNome());
     itemEndereco.setText(item.getEndereco());

     if(check.isChecked()){

      rowView.setBackgroundColor(Color.RED);
}
else{

     rowView.setBackgroundColor(Color.WHITE);

}

    return rowView;
  }
} 

The code above is just an example.

But I hope what you’ve really understood is that the items are broken down by rolling and rebuilt when they’re visualized, back to their original state.

On the error that occurs when it rolls down further, on the Adapter, you can put a breackpoint and debug.

I saw that you’re using the Viewholder standard, so just watch out for this fact, the recycling.

  • I posted the print.. and there is no way to make changes to the Adapter using baseAdapter?

  • this error is precisely when using listview.getChildAt(position). findViewById(R.id.itemNome). setBackgroundColor(Color.RED); the error is in position..

  • I’ve already fixed the second and third errors.. only the first one is missing... with respect to scrolling... when I select an item and then roll its color disappears.

  • @Pedrorangel, you need to store inside the Adapter which elements are selected. To not depend on screen only. The check.isChecked have to use some extra information in case a Set or SparseArray.

  • @Wakim I searched a lot and had found this line of code android:scrollingCache="false" to add but still does not work..

  • @Pedrorangel, that’s not it. You can’t just make the markings on Views. Because by scrolling they are rebuilt and this state is lost. You need to manage who is marked within your Adapter and not use the isChecked of Checkbox and yes of the state of Adapter.

  • @Wakim blz... but I’m not using checkbox anyway, I think you’re looking at the answer code^^..

Show 2 more comments

0

Try using the setCacheColorHint

Ex:

mDrawerList = (ListView) findViewById(R.id.hinario_left_drawer);
mDrawerList.setCacheColorHint(Color.parseColor("#669966"));

0


After much pain I managed, vlw by the help @Wakim and @Cícero Moura:

@Override
public View getView(int posicao, View convertview, ViewGroup parent) {

    View view = convertview;
    ViewHolder holder = null;

    if (view == null) {
        holder = new ViewHolder();
        view = inflater.inflate(R.layout.itens_lista, parent, false);
        holder.itemNome = (TextView) view.findViewById(R.id.itemNome);
        holder.itemEndereco = (TextView) view
                .findViewById(R.id.itemEndereco);
        view.setTag(holder);

    } else {

        holder = (ViewHolder) view.getTag();
    }

    if (listener.getPosicao() == posicao
            && listener.statusSelecao()) {
        holder.itemNome.setBackgroundColor(Color.RED);
        holder.itemEndereco.setBackgroundColor(Color.RED);
    }
        else {
            holder.itemNome.setBackgroundColor(Color.rgb(65, 105, 225));
            holder.itemEndereco.setBackgroundColor(Color.rgb(65, 105, 225));
    }

    Telefone item = getItem(posicao);
    holder.itemNome.setText(item.getNome());
    holder.itemEndereco.setText(item.getTelefone());
    return view;
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.