【问题标题】:Multiple ViewHolder RecycleVIew List rearrange多个 ViewHolder 回收视图列表重新排列
【发布时间】:2018-06-01 14:12:48
【问题描述】:

我试图找到解决方案,但我认为没有人遇到过这样的问题。

所以我在我的大部分项目中都使用了ListView,我觉得它更灵活,因为你不需要在RecyclerView 中使用BindViewHolder。但是因为我需要制作一个水平的listview,所以我可以使用RecyclerView 使用LayoutManager 轻松做到这一点。它完美地工作。

但现在我为RecyclerView 使用多个ViewHolders,因为我需要为RecyclerView 的不同项目显示不同的视图。它再次使用下面的代码完美地工作。

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private List<Item> data;
    private Context context;

    // Item.Type is an enum, used to differentiate the view types.

    public MyAdapter(List<Item> list, Context context) {
        this.data = list;
        this.context = context;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(data.get(viewType).getType() == TYPEA) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.type_a, parent, false);
            return new ViewHolderA(itemView);
        }
        else {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.type_b, parent, false);
            return new ViewHolderB(itemView);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if ( data.get(position).getType()== TYPEA ){
            ViewHolderA viewHolder = (ViewHolderA) holder;
            ...

        }
        else if (data.get(position).getType()== TYPEB){
            ViewHolderB viewHolder = ((ViewHolderB) holder);
            ...            
        }
    }


    @Override
    public int getItemViewType(int position) {        
        return position;
    }


    @Override
    public int getItemCount() {        
        return data.size();
    }

}

所以当我重新排列用于显示项目的列表时,问题就出现了。例如,我从TYPEB 列表中的一项开始,它显示正确。但现在我想在列表中添加新项目,但在开始时,TYPEB 被推回。所以我添加了一个新项目TYPEA,列表看起来像[TYPEA,TYPEB]ViewHolderA 用于TYPEA,同样ViewHolderB 用于TYPEB

在这种情况下onBindViewHolder里面的行

ViewHolderA viewHolder = (ViewHolderA) holder;

提示我无法将 ViewHolderB 强制转换为 ViewHolderA。这表明在重新排列列表后,适配器正在调用 onBindViewHolder,并针对 positon 使用错误的 ViewHolder 实例。任何想法如何解决这个问题。

【问题讨论】:

    标签: android android-recyclerview android-viewholder


    【解决方案1】:

    这里需要指定唯一的id,位置不用返回:

    @Override
    public int getItemViewType(int position) {        
        return data.get(position).getType()
    }
    

    当然你必须使用 viewType 参数作为类型而不是位置:

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if(viewType == TYPEA) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.type_a, parent, false);
            return new ViewHolderA(itemView);
        }
        else {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.type_b, parent, false);
            return new ViewHolderB(itemView);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-28
      • 2016-05-23
      • 1970-01-01
      • 2011-12-07
      相关资源
      最近更新 更多