防止适配器在滚动时回收视图(编辑永远不要这样做



我有一个自定义的基本适配器,它将接收一个数组数据列表。从这里它将使用自定义按钮填写网格视图。它完美地做到了这一点,并填满了网格视图。问题是。我想设置一个按钮来更改颜色。当我这样做时,由于视图是回收的,它也会更改下一个被回收的视图。例如,单击位置 0 处的按钮 1。同时更改位置 13 处的按钮。现在,当我进行一些调试时,我发现它也更改了一些属性。我想知道是否有无论如何可以按原样创建我的视图,而无需回收视图的任何部分。

我已经看到了一些关于使用 stableID 的事情,但即使我已经覆盖了它。它目前仍然没有改变它。

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

不用担心视图持有人。 这是试图阻止回收。关于如何获得此内容的任何线索或想法?

这是我的按钮

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));
    }
}

}

更好的方法是使用

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

您必须注意,这可能会降低回收器视图的性能。

您可以重写 getItemViewType 方法,如下所述

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

防止适配器回收滚动视图

只是不要使用传递给getView()convertView参数,并始终返回新生成的View

但是,就

性能而言,这是一个糟糕的解决方案。相反,你的目标不应该是阻止回收,而是相应地回收:你的getView()应该将convertView重置为原始状态。

因此,如果更改了 Button 的某些属性从其非默认值更改,请在 getView() 中将它们重置回默认值。

  public View getView(int position, View convertView, ViewGroup parent) {
        View itemview = null;
        itemview = getLayoutInflater().inflate(R.layout.ordermini, parent,false);
    }

这将有助于膨胀新视图

我遇到了这个确切的问题所以我添加了一些代码来检查每个视图它没有突出显示当它找到突出显示的视图时,它会将其更改回来。

//--------SET-FOREGROUND-IMAGE-(BORDER)------------
    /*If the user clicks on an item and then scrolls down so the selected item is no longer in view Then the
    Item that the user clicked on will be recycled with the foreground image.
    This is BAD because when the user sees the selected item (as distinguished by it's different border)
    it will be holding different data from a different data model item.
    These following lines of code will change the colour of any non selected item back to normal and they will
    colour of the selected views appropriately*/
        if(currentLine.getLineId() == clickedId)
        {recycleHolder.cardView.setForeground(parentActivity.getResources().getDrawable(R.drawable.card_view_border_selected));}
        else
        {recycleHolder.cardView.setForeground(parentActivity.getResources().getDrawable(R.drawable.card_view_border));}

并且此代码放置在

 @Override
public void onBindViewHolder(final RecyclableViewHolder recycleHolder, int i)
{
 }

最新更新