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

如何为RecycleView实现多视图类型?

江正德
2023-03-14

目前,我在为RecycleView定制多视图类型。我找到了很多解决这个问题的方法,但我会分享我的方法。

不同的是使用enum定义ViewType。

更多细节请参见我的答案。(只想分享)。

共有1个答案

裴浩歌
2023-03-14

更新

我推荐阅读这篇文章:编写更好的适配器

以下是我为RecyclewView自定义多视图类型的方法。

我将首先显示代码,然后在下面解释。

@SuppressWarnings("unchecked")
public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder> {
    private final List<Wrapper<?>> items;

    public BaseAdapter() {
        this.items = new ArrayList<>();
    }

    @Override
    public int getItemViewType(int position) {
        return items.get(position).viewType;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return ViewType.values()[viewType].onCreateViewHolder(parent);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.onBind(items.get(position));
    }

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


    public void simulateAddItems() {
        items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
        items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
        items.add(new Wrapper<>(ViewType.USER.viewTYpe(), new User()));
        items.add(new Wrapper<>(ViewType.BOTTOM.viewTYpe(), new BottomData()));

        notifyDataSetChanged();
    }

    public enum ViewType {
        USER {
            @Override
            public ViewHolder onCreateViewHolder(ViewGroup parent) {
                return new UserViewHolder(itemView);
            }
        },
        BOTTOM {
            @Override
            public ViewHolder onCreateViewHolder(ViewGroup parent) {
                return new BottomViewHolder(itemView);
            }
        };

        public abstract ViewHolder onCreateViewHolder(ViewGroup parent);

        public int viewTYpe() {
            return ordinal();
        }
    }


    static class Wrapper<T> {
        final int viewType;
        final T data;

        public Wrapper(int viewType, T data) {
            this.viewType = viewType;
            this.data = data;
        }
    }

    public static class ViewHolder<T> extends RecyclerView.ViewHolder {
        private T item;

        public ViewHolder(View itemView) {
            super(itemView);
        }


        public void onBind(T item) {
        }
    }

    public static class UserViewHolder extends ViewHolder<User> {

        public UserViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        public void onBind(User item) {
            super.onBind(item);
        }
    }

    public static class BottomViewHolder extends ViewHolder<BottomData> {

        public BottomViewHolder(View itemView) {
            super(itemView);
        }

        @Override
        public void onBind(BottomData item) {
            super.onBind(item);
        }
    }


    static class User {
        // user fields & method
    }

    static class BottomData {
        // bottom data fields & method
    }
}

您可以看到适配器有一些特殊之处:

>

  • 适配器的数据是通用的

    带有< code>T的通用< code>ViewHolder是视图持有者的一种数据。您可以看到两个自定义视图持有人< code>UserViewHolder和< code>BottomViewHolder从< code>ViewHolder扩展而来的数据。(因此在每个视图持有者的< code>onBind中将有他们想要使用的确切数据-

    enum ViewType包含适配器的所有视图类型。此外,在视图类型中,我们有方法< code > ViewHolder onCreateViewHolder(view group parent),这样我们可以更容易地从< code>ViewType中创建view holder。我认为相对于视图类型,我们的眼睛更容易看到持有者。

    此外,我们有方法 viewType() 它只是返回枚举的序数()。作为java文档中的参考,该方法可能不使用。但在这种情况下,我认为它足够公平(因为它是独一无二的)。

    因此,在适配器的onCreateViewHolder方法中,我们可以简单调用:返回ViewType.values()[ViewType].onCreateViewHolder(父级)

    在<code>onBindViewHolder</code>中,我们将调用<code>holder.onBind(items.get(position))

    最后,我为演示我们如何将项目添加到适配器制作了simateAddItems

    以下是使用RecycleView的自定义视图类型时的一些经验。我希望它有用

  •  类似资料:
    • 我想创建一个recyclerview,当它在列表中看到LIQUID作为pid时,它将使用具有自己布局的ViewWholder2。否则,它将使用具有自己布局的viewholder1。 问题是我创建的recyclerview只显示一个ViewWholder。如果位置0 pid为液体,则viewholder为ViewHolder2,即使对于列表上的后续项,pid不再为液体。简而言之,位置0上的pid值将

    • 从使用RecycerView创建动态列表: 当我们创建时,我们必须指定将与适配器绑定的。 是否可以创建具有多种视图类型的?

    • 问题内容: 我想继承不可变类型或实现自己的一种,其行为类似于以下控制台会话所示: 毫不奇怪,对象没有方法,但应用于对象并不会导致错误,相反,它显然会创建一个新对象,并且还以某种方式神奇地将其重新分配为扩充赋值语句中给出的名称。 是否可以创建一个内置的不可变类的用户定义类或子类,并且可以这样做? 问题答案: 使用的返回值。您无需返回要添加到的对象;您可以创建一个新的并将其返回。实际上,如果对象是不可

    • 本文向大家介绍H5播放的video视频,如何实现对视频截图?相关面试题,主要包含被问及H5播放的video视频,如何实现对视频截图?时的应答技巧和注意事项,需要的朋友参考一下

    • 我读过一些关于使用bing的东西,但我不确定,你知道另一种方法吗?,我想我需要在线才能使用bing库。我说的对吗?

    • 我有扩展抽象类的类,我不想把放在所有子类的顶部。 有没有办法为抽象类实现Lombok?