如何实现RecycleView的多种视图类型? [英] How implement multi view types for RecycleView?

查看:137
本文介绍了如何实现RecycleView的多种视图类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我致力于RecycleView的自定义多视图类型. 我找到了解决此问题的许多解决方案,但我会分享我的方式.

Currently, I work on custom multi-view types for RecycleView. I found many solutions for this problem, but I will share my way.

不同之处在于,使用enum定义ViewType.

The different is use enum for define ViewType.

请参阅我的答案以获取更多详细信息. (只想分享).

See my answer for more detail. (Just want to share).

推荐答案

更新

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

I recommend read this article: Writing Better Adapter

这是我为RecyclewView自定义多视图类型的方式.

Here is the way I custom multi-view types for RecyclewView.

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

I will show the code first, then explain bellow.

@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
    }
}

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

You can see the adapter have something special:

  1. Adapter的数据是通用&从Wrapper类扩展. Wrapper类只是POJO类,包含两个字段viewType& item数据. viewType将通过getItemViewType(int position)传递,而item是每个视图持有者的数据.

  1. The data of Adapter is generic & extends from Wrapper class. The Wrapper class simply POJO class contain two fields viewType & item data. The viewType will be passing via getItemViewType(int position) and the item is data for each view holder.

带有T的通用ViewHolder是视图持有者的一种数据.您可以看到两个自定义视图保存器UserViewHolderBottomViewHolderViewHolder扩展到此数据. (因此,每个视图持有人的onBind中将拥有他们想要使用的确切数据->无需强制转换.因为我们已经在强制转换中了.)

The generic ViewHolder with T is kind of data for the view holder. You can see two custom view holder UserViewHolder and BottomViewHolder extends from ViewHolder with this data. (So in onBind of each view holder will have exact data they want to use -> no need to cast. Because we already in cast).

枚举ViewType包含适配器的所有视图类型.另外,在视图类型中,我们有方法ViewHolder onCreateViewHolder(ViewGroup parent),因此我们可以更容易地从ViewType制作viewHolder.我认为相对于ViewType,我们的眼睛更容易看到Holder.

The enum ViewType contain all view type of adapter. Also, in view type, we have method ViewHolder onCreateViewHolder(ViewGroup parent) so we can easier make viewHolder from ViewType. I think it is easier for our eyes to see the Holder relative to the ViewType.

此外,我们有方法viewType(),它只返回枚举的ordinal(). 作为java docs中的参考,该方法可能不使用.但是在这种情况下,我认为使用起来很公平(因为它是唯一的).

Also, we have method viewType() it simply return ordinal() of enum. As a reference in java docs that method may not use. But in this case, I think it is fair enough to use (because it is unique).

因此,在Adapter的方法onCreateViewHolder中,我们可以简单地调用: return ViewType.values()[viewType].onCreateViewHolder(parent);

So in the method onCreateViewHolder of Adapter we can simple call: return ViewType.values()[viewType].onCreateViewHolder(parent);

,在onBindViewHolder中,我们将调用holder.onBind(items.get(position));.

and in onBindViewHolder we will call holder.onBind(items.get(position));.

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

Finally, I made simulateAddItems for demo how we add item to the adapter.

使用RecycleView的自定义视图类型时,这里有一些经验.我希望它有用&帮助别人.

Here is some experiences while working with custom view type for RecycleView. I hope it useful & help other people.

这篇关于如何实现RecycleView的多种视图类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆