Prevent the adapter from recycling views on scroll ( Edit do not ever do this.)

Jesusrz001 picture Jesusrz001 · Dec 21, 2013 · Viewed 16.4k times · Source

I have a custom base adapter that will take in an arraylist of data. From here it will fill out a grid view with custom buttons. It does so perfectly and fills up the gridview. The problem is. I want to set a button to change colors on change. When I do this, since the view is recycled, it also changes the next view that is recycled. Ex. Click on button one at position 0. Also changes button at position 13. Now when I do some debugging, I find that it also changes some of the properties. I am wondering if there is anyway of creating my view as it is without needing to recycle any part of the views.

I have seen some things about using stableID's but even when I have overridden it to true. It still does not currently change it.

static class CategoryButtonAdapter extends BaseAdapter
{
    private Context mContext;
    private ArrayList<DishCategory> dishCategories;
    private ArrayList<Dish> dishItems;
    static ArrayList<DishCategoryButton> mDishCategoryButtons;
    //will take in an array list created in the orderlayout that will be the 
    //dish category. This will be the from where we will the count for the adapter
    public CategoryButtonAdapter(Context context, ArrayList<DishCategory> dishCategories)
    {
        this.mContext = context;
        this.dishCategories = dishCategories;

        dishItems  = dishCategories.get(0).getDishes();
    }

    public int getCount() 
    {
        return dishCategories.size();
    }

    //to be implementated later so it can b3e used to find menu categories
    @Override
    public DishCategory getItem(int position) 
    {
        return dishCategories.get(position);
    }

    public void getDishCategoryButtons()
    {
        if(mDishCategoryButtons.size() == 0)
        {
             System.out.println("The number of buttons in this adapapter is " + mDishCategoryButtons.size());
        }
        else
        {
            System.out.println("The number of buttons in this adapapter is " + mDishCategoryButtons.size());
        }
    }

    public long getItemId(int position) 
    {
        return dishCategories.get(position).getDishCategoryID();
    }

    @Override
    public boolean hasStableIds() {
        //return super.hasStableIds(); //To change body of generated methods, choose Tools | Templates.
        return true;
    }

    public View getView(int position, View convertView, ViewGroup parent) 
    {
        ViewHolder holder;
        DishCategoryButton button = null;
        //button to be created
        if(convertView == null )
        {
            holder = new ViewHolder();
            //if it is not recycled, initialize some new attributes
            button = new DishCategoryButton(this.mContext,dishCategories.get(position));
            button.setLayoutParams(new GridView.LayoutParams(100,100));
            button.setPadding(2,2,2,2);
            //convertView.setTag(holder);
            button.setTag(holder);
        }
        else
        {
            //holder = (ViewHolder)convertView.getTag();
            button = (DishCategoryButton) convertView;
        }
        //setButton to the description of the category
        //mDishCategoryButtons.add(button);
        button.setText((dishCategories.get(position).getDescription()));
        //this can be changed later to change the sex appeal of the app
        //for now it will be plain
        button.setId(position);

        //.setOnClickListener(new View.OnClickListener() 
        button.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
             // Perform action on click
            DishCategoryButton dishCategoryButton = (DishCategoryButton)v;
            PaintDrawable drawable = (PaintDrawable) dishCategoryButton.getBackground();
            System.out.println("Dish button position is " + dishCategoryButton.getId());
            //System.out.println("The position from the array says it is at " + position);
            System.out.println("Dish Category is " + dishCategoryButton.getDishCategory().getDescription());
            System.out.println("Is it currently selected  " + dishCategoryButton.getIsSelected());

            int color = drawable.getPaint().getColor();
                    System.out.println("Color is  " + color);
                    dishCategoryButton.setIsSelected(true);
                    drawable = (PaintDrawable) dishCategoryButton.getBackground();
                    color = drawable.getPaint().getColor();
                    System.out.println("Color is  " + color);
                        System.out.println("hi");

                    // The toggle is enabled

            }
        });
        //new loadDishItems(categoryButtons.get(position).getDescription()));
        return button;
    }

Don't worry about the view holder. that was an attempt to prevent the recycling. Any clues or ideas on how to get this?

Here is my button

public class DishCategoryButton extends Button 
{
private DishCategory dishCategory = new DishCategory();
private Boolean isSelected = false;


public DishCategoryButton(Context context, DishCategory dishCategory) 
{
   super(context);
   this.dishCategory = dishCategory;
   isSelected = false;
   setTextColor(Color.WHITE);
   setBackgroundDrawable(new PaintDrawable(Color.BLACK));
}
public DishCategory getDishCategory()
{
     return dishCategory;
}
public void setDishCategory(DishCategory dishCategory)
{
    this.dishCategory = dishCategory;
}

public Boolean getIsSelected() {
    return isSelected;
}

public void setIsSelected(Boolean isSelected) {
    this.isSelected = isSelected;
    if(isSelected == true)
    {
        setTextColor(Color.WHITE);
        setBackgroundDrawable(new PaintDrawable(Color.GREEN));
    }
    else
    {
        setTextColor(Color.WHITE);
        setBackgroundDrawable(new PaintDrawable(Color.BLACK));
    }
}

}

Answer

Sourav Chandra picture Sourav Chandra · Jan 20, 2016

A better approach would be using

recyclerView.getRecycledViewPool().setMaxRecycledViews(VIEW_TYPE,0);

You must note that this may reduce the performance of your RecyclerView.

You can Override the getItemViewType method as mentioned below

@Override
public int getItemViewType(int position) {
    if (position == feedElements.size())
        return 3;
    else if (feedElements.get(position).getType() == 1)
        return 1;
    else
        return 2;
}