【问题标题】:In Recycler View with multiple view types items duplicating on scrollup在具有多个视图类型的 Recyclerview 中,项目在向上滚动时重复
【发布时间】:2018-10-11 18:20:03
【问题描述】:

我有一个启用了多种视图类型和分页的回收器视图。两页后向上滚动,项目没有保持视图并且正在复制。我已经实现了 getItemId 返回唯一 id 和 getViewtype 返回唯一值。还将适配器的 setHasStableIds 设置为 true。期待任何帮助。 谢谢。

getItemId

if (postList.get(position).getId()== null){
        return position;
    } else{
        return postList.get(position).getId();
    }

getItemViewType

 if (postList.get(position).getPostType().equals("contest")){
            return TYPE_CONTEST;
  } else if(postList.get(position).getPostType().equals("suggestion")){
            return TYPE_SUGGESTION;
        } else{
            return TYPE_POST_POLL;
        }
    } else{
        return TYPE_HEADER;
       }

【问题讨论】:

  • 您的 getItemId() 似乎没有向我返回唯一 ID

标签: android android-studio android-recyclerview


【解决方案1】:

试试这样的:

@Override
public int getItemViewType(int position) {
    if (isValidPosition(position)) {
        Dataset d = mDataset[position];
        if ("contest".equals(d.getViewType())) {
            return VIEW_TYPE_CONTEST;
        } else if ("suggestion".equals(d.getViewType())) {
            return VIEW_TYPE_SUGGESTION;
        }
        // all other cases here
    }
    // default type
    return VIEW_TYPE_CONTEST;
}

然后:

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Dataset d = mDataset[position];

    if (holder instanceof ContestVH) {
        ContestDataset contest = (ContestDataset) d;
        ContestVH vh = (ContestVH) holder;
        // bind your contest views here
    } else if (holder instanceof SuggestionVH) {
        SuggestionDataset suggestion = (SuggestionDataset) d;
        SuggestionVH vh = (SuggestionVH) holder;
        // bind your suggestion views here
    }
    // all other cases here
}

这样,您的 String 视图类型是您唯一的真实来源。

【讨论】:

  • postList.get(position).getId()
  • 正如我所写,如果为 null,则依赖位置 (1, 3, 5),如果不为 null,则依赖 id (1, 3, 5?)。这使得 id 可能不唯一。但是您不需要通过唯一 id 唯一标识您的数据集,因为它们已经由位置唯一标识。您需要做的是确保对于您拥有的每种数据类型(因此对于每种不同类型的查看器),您可以将数据集绑定到相应的视图。查看我的代码 sn-p,它可以工作。
  • 好的,有 4 个不同的 ViewHolders,但我的数据集的问题是,对于每种类型,我的模型都是相同的。有什么帮助吗?
  • 当我将新数据添加到现有数据集时,从第 1 页到第 2 页分页时也会出现问题
  • @user2837607 4 种不同类型的视图持有者意味着您有 4 种不同类型的布局,对吧?就像在 1 中一样,有一个额外的视图,依此类推。他们不同。相反,您的数据集可以很容易地相同,没问题(我假设有些将包含空值或无意义的字段),但您仍然可以通过 Java 类类型区分它们:数据集是您的(空)父级,那么您将有 4 个子级继承自它:竞赛数据集、建议数据集等。恕我直言,每个更专业的数据集都应仅填充所需的字段。这样代码清晰干净,你可以信任地绑定它们
【解决方案2】:

对于 recyclerview 中的分页,你应该使用 onScrollListener 这个

recyclerList.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        boolean isLast = isLastItemDisplaying(recyclerView);  //get last displayed item
        if (loading && isLast) {  //this check if your data is loading and if its last list item list will not load again
            loading = false;

            //get your data according to page count it will refresh your recycler list 

        }
    }
});

因为在分页中,您可以在回收站视图的页面滚动中从 Api 获取数据。因此,数据将根据页数分块出现。对于此行为,您可以在回收器列表中的滚动侦听器上使用,并在列表滚动时刷新数据,直到列表的最后一项到达。 希望对你有帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多