当前位置: 首页 > 知识库问答 >
问题:

具有GridLayoutManager的RecyclerView和具有不同viewHolder的第一个元素

赫连靖琪
2023-03-14

我成功地做到了这一点,但是以一种非常规的方式。在我的recyclerView适配器中,我对第一个元素使用了一个不同的viewHolder,一个更大的元素。这将是一个很好的解决方案,但第二个元素将低于第一个元素。所以我做了一个技巧,给recyclerView一个与第一个元素相同的固定高度,这样第一个元素和第二个元素就会重叠,我只需要让第二个元素的可见性消失。

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    switch (viewType) {
        case 0:
            final View view = inflater.inflate(R.layout.big_item, parent, false);
            return new BigViewHolder(view);
        case 2:
            final View view2 = inflater.inflate(R.layout.normal_item, parent, false);
            return new NormalViewHolder(view2);
        default:
            return null;
    }
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (position == 1) {
        holder.itemView.setVisibility(View.GONE);
    }}

@Override
public int getItemViewType(int position) {
    if (position == 0) {
        return 0;
    } else return 2;
}

但我并不特别喜欢这种方法。有人有更好的主意吗?

共有1个答案

公孙河
2023-03-14

经过一些挖掘和咨询,我得到了一个非常好的结果。我会把它贴在下面:

首先,适配器应该像我在问题中提到的那样,没有隐藏第二个元素:

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

    public static final int TYPE_FIRST_ITEM = 0;
    public static final int TYPE_ITEM = 1;

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case TYPE_FIRST_ITEM:
                final View view = inflater.inflate(R.layout.big_item, parent, false);
                return new BigViewHolder(view);
            case TYPE_ITEM:
                final View view2 = inflater.inflate(R.layout.normal_item, parent, false);
                return new NormalViewHolder(view2);
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (holder.getItemViewType()) {
            case TYPE_FIRST_ITEM:
                BigViewHolder bigViewHolder = (BigViewHolder) holder;
                // Do what you need for the first item
                break;
            case TYPE_ITEM:
                NormalViewHolder normalViewHolder = (NormalViewHolder) holder;
                // Do what you for the other items
                break;
        }
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return TYPE_FIRST_ITEM;
        } else return TYPE_ITEM;
    }

    final class NormalViewHolder extends RecyclerView.ViewHolder {
        public NormalViewHolder(View itemView) {
            super(itemView);
        }
        // find your views here
    }

    final class BigViewHolder extends RecyclerView.ViewHolder {
        public BigViewHolder(View itemView) {
            super(itemView);
        }
        // find your views here
    }
}

其次,布局管理器应该实现一个侦听器来指定在特定位置应该有多少个跨度(行):

RecyclerView mRecyclerView = view.findViewById(R.id.my_recycler_view);
        MyAdapter mAdapter = new MyAdapter();
        GridLayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2, LinearLayoutManager.HORIZONTAL, false);
        mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                switch(mAdapter.getItemViewType(position)){
                    case MyAdapter.TYPE_FIRST_ITEM:
                        return 2;
                    case MyAdapter.TYPE_ITEM:
                        return 1;
                    default:
                        return -1;
                }
            }
        });
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setLayoutManager(mLayoutManager);

希望它也能帮助其他人。谢谢迈克·M.的支持。

 类似资料:
  • 我正在尝试使用GridLayoutManager构建一个RecyclerView,它每行有一个可变的列计数,如下所示: 同一行中所有项目的宽度之和将始终为屏幕宽度。 我试图重新组织项目列表,按行列表分组,然后每行膨胀一个线性布局。它不太好。 所以我被困住了,没有任何想法。任何帮助都将非常感激

  • 因此,我遵循本教程,我有一个带有GridLayoutManager实现的RecycerView。GridLayoutManager有2列。我希望有两个视图类型,所以我使用了两个扩展RecycerView.Viewholder的Viewholder,并且重写了这个方法:getItemViewType(int位置),但是我使用了一个强制转换异常。Logcat显示以下内容: java.lang.Clas

  • 问题内容: 我试图用来创建我的,以确保我的构建/项目的质量。该项目也需要使用和。一切在我的本地计算机上都可以正常运行,但是现在我正在尝试使环境一致,可重现。当我尝试在新的虚拟机中运行时,会中断一个在本机中正常运行但 不在 新vm中运行的。 我检查了版本,,,(其)一切都是一样的。但是,我的Maven项目在此测试中失败了。 我在这里想念什么?任何想法,建议都会受到赞赏,因为我现在还没有想法,到目前为

  • 问题内容: 我的布局基本上全部统一,其中包含应用程序主供稿所需的所有内容。首先将所有可变项(图像,视频缩略图等等)设置为,并在需要时设置为。 问题是,有时,可能是由于的回收行为,这是supposedto是该项目是在错误的地方。 范例: 项目1包含文字 项目2包含图片 项目3包含图片 我一直向下滚动到编号x,然后向上滚动,这就是我得到的: 项目1包含来自项目x的图片,有时包含项目3 项目2包含图片

  • 现在我的问题是,如何在自定义的而不是自定义的中重写方法?我没有在这里公布我的代码,因为它与链接的代码本质上是相同的,只是我需要为子创建一个自定义的来代替,这样它就可以按照“pptang”的答案所述进行正确的度量。 否则,有没有比在第二个RecyclerView中使用1个RecyclerView更好的方法?只能有1个RecyclerView使用上述列表和每个中唯一项的网格填充活动/片段吗?

  • 我在Wordpress和Visual Composer一起工作,我有一个切换容器。基本上,我点击每个选项卡,下面的内容就会发生变化。我想通过CSS为每个选项卡分配一个不同的图像作为背景。但是,我已经实现了这一点,因为每个选项卡都有相同的类名(由visual composer赋予它),所以图像是相同的。我需要弄清楚如何给每个选项卡一个唯一的id,这样我就可以给每个选项卡一个自己的背景图像--但是由于