阻止适配器在滚动时回收视图(编辑不要这样做。)

时间:2013-12-21 17:40:00

标签: android button gridview baseadapter

我有一个自定义基础适配器,它将接收数据的arraylist。从这里开始,它将使用自定义按钮填充网格视图。它完美地完成并填满了gridview。问题是。我想设置一个按钮来改变颜色。当我这样做时,由于视图被回收,它还会更改下一个被回收的视图。防爆。单击位置0处的按钮1。同时更改位置13处的按钮。现在,当我进行一些调试时,我发现它也会更改某些属性。我想知道是否有创建我的视图,因为它不需要回收任何部分的视图。

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

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

}

4 个答案:

答案 0 :(得分:15)

更好的方法是使用

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

您必须注意,这可能会降低RecyclerView的性能。

您可以覆盖下面提到的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;
}

答案 1 :(得分:3)

  

防止适配器在滚动

上回收视图

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

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

因此,如果您的某些convertView属性发生了更改,则会将其更改为非默认值,请将其重置为Button中的默认值。

答案 2 :(得分:1)

  public View getView(int position, View convertView, ViewGroup parent) {
        View itemview = null;

        itemview = getLayoutInflater().inflate(R.layout.ordermini, parent,false);

    }

这将有助于扩充新视图

答案 3 :(得分:0)

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

//--------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)
{
 }