• Stars
    star
    413
  • Rank 104,801 (Top 3 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

一种优雅的方式来使用RecyclerView

一种优雅的方式来使用RecyclerView

使得RecyclerView各种情况的多类型条目更简单!

License MavenCentral MinSdk

示例图片

下载体验

核心思想

  想必大家都遇到过,在一个列表中显示不同样式的需求。在RecyclerView中可以通过ViewType进行区分,如果样式特别多的时候就会使得代码非常冗余,不利于开发及维护。那么有没有一种优雅的方法解决这个问题呢?

  技术经理给你说,接下来的项目由你负责,明天下班前把排期同步出来。这时你应该怎么做?由于你是Android端的RD,你对Android的排期是比较了解的,但是iOS端、FE端、Server端的排期怎么办呢?聪明的你立即把任务派发下去了,给每个端的负责人说,明天中午之前把排期汇总给我。

  没错,在多样式列表的设计中也可以采用这种策略,给RecyclerView设置的Adapter不做具体的处理,而是由它派发出去。

实现方案

  1. addDelegate 向Adapter中注册委托Adapter;
  2. addDataList 设置数据;
  3. layout 渲染布局,Adapter查找到对应的委托Adapter,由委托Adapter去做具体渲染。

引入

androidX

implementation 'com.zwenkai:delegationadapter:2.0.8'
// 扩展库,扩展支持了item click、item long click、databinding、load more
implementation 'com.zwenkai:delegationadapter-extras:2.0.8'

support[不在支持]

// JCenter
implementation 'com.kevin:delegationadapter:1.2.1'
// 扩展库,扩展支持了item click、item long click、databinding、load more
implementation 'com.kevin:delegationadapter-extras:1.2.1'

如何使用

简单用法

  1. 带RecyclerView的布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>
    
  2. 初始化RecyclerView

    Adapter为DelegationAdapter,然后向DelegationAdapter中注册委托Adapter。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        // ① 设置 LayoutManager
        // LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        GridLayoutManager layoutManager = new GridLayoutManager(this, 3);
        recyclerView.setLayoutManager(layoutManager);
        // ② 创建 DelegationAdapter 对象
        DelegationAdapter delegationAdapter = new DelegationAdapter();
        // ③ 向Adapter中注册委托Adapter
        delegationAdapter.addDelegate(new CompanyAdapterDelegate());
        // ④ 设置Adapter
        recyclerView.setAdapter(delegationAdapter);
    }
    
  3. 委托Adapter编写

    委托Adapter继承自AdapterDelegate,需要两个泛型,第一个为该委托Adapter可处理数据的数据类型(这里为String),第二个参数为ViewHolder。剩下的就按照之前怎么写Adapter来写委托Adapter就可以啦。比如:在onCreateViewHolder创建ViewHolder,在onBindViewHolder中绑定数据到视图控件。

    public class CompanyAdapterDelegate extends AdapterDelegate<String, CompanyAdapterDelegate.ViewHolder> {
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent) {
            View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position, final String item) {
            holder.tvName.setText(item);
        }
    
        static class ViewHolder extends RecyclerView.ViewHolder {
            public TextView tvName;
    
            public ViewHolder(View itemView) {
                super(itemView);
                tvName = itemView.findViewById(android.R.id.text1);
            }
        }
    }
    
  4. 设置数据

    protected void onCreate(Bundle savedInstanceState) {
        // ... ...
    
        List<String> companies = new ArrayList<>();
        companies.add("🇨🇳 Baidu");
        companies.add("🇨🇳 Alibaba");
        companies.add("🇨🇳 Tencent");
        companies.add("🇺🇸 Google");
        companies.add("🇺🇸 Facebook");
        companies.add("🇺🇸 Microsoft");
        // ⑤ 设置数据
        delegationAdapter.setDataItems(companies);
    }
    

复杂用法

如果想区分🇨🇳公司为红色,美国公司为蓝色,怎么办呢?

  1. 编写CNCompanyAdapterDelegate

    public class CNCompanyAdapterDelegate extends AdapterDelegate<String, CNCompanyAdapterDelegate.ViewHolder> {
    
        @Override
        public boolean isForViewType(String item, int position) {
            return item.contains("🇨🇳");
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent) {
            View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position, final String item) {
            holder.tvName.setText(item);
            holder.tvName.setTextColor(Color.RED);
        }
        
        static class ViewHolder extends RecyclerView.ViewHolder {
            public TextView tvName;
    
            public ViewHolder(View itemView) {
                super(itemView);
                tvName = itemView.findViewById(android.R.id.text1);
            }
        }
    }
    
  2. 编写USCompanyAdapterDelegate

    public class USCompanyAdapterDelegate extends AdapterDelegate<String, USCompanyAdapterDelegate.ViewHolder> {
    
        @Override
        public boolean isForViewType(String item, int position) {
            return item.contains("🇺🇸");
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent) {
            View view = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        }
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, final int position, final String item) {
            holder.tvName.setText(item);
            holder.tvName.setTextColor(Color.BLUE);
        }
    
        static class ViewHolder extends RecyclerView.ViewHolder {
            public TextView tvName;
    
            public ViewHolder(View itemView) {
                super(itemView);
                tvName = itemView.findViewById(android.R.id.text1);
            }
        }
    }
    
  3. 注册委托Adapter

// 向Adapter中注册委托Adapter
delegationAdapter.addDelegate(new CNCompanyAdapterDelegate());
delegationAdapter.addDelegate(new USCompanyAdapterDelegate());

更多请看示例

THANKS TO

  1. MultiItem 委托思想来源
  2. AdapterDelegates 委托架子来源

More Repositories

1

PullToRefresh-Demo

Demos of PullToRefresh.
Java
137
star
2

Android-LoopView

自定义无限轮转控件
Java
103
star
3

Android-ImageCrop

Android image crop
Java
97
star
4

WrapRecyclerView

RecyclerView can add header and footer.
Java
92
star
5

Android-TabIndicator

底部导航
Java
82
star
6

Android-Crop

Java
77
star
7

Android-JSONTool

JSON Bean 相互转换
Java
45
star
8

ImageUpload

Android上传图片到JavaWeb服务器
Java
42
star
9

UltimateRecyclerView

RecyclerView that support pull to refresh,add header and footer.
Java
27
star
10

SlidingTabLayout

Java
18
star
11

Android-ShadowView

Android Shadow View
Java
15
star
12

Android-WheelView

Kotlin
12
star
13

Android-BaseDialog

基于DialogFragment的弹窗封装,使弹窗使用更简单。
Kotlin
8
star
14

Android-GridPagerView

让网格翻页开发变得更简单
Kotlin
8
star
15

Ksoup

优雅地把Html解析为Java/Kotlin实体对象
HTML
6
star
16

Android-Utils

Android 常用工具类
Java
5
star
17

Android-ScaleHelper

Android 屏幕适配的一种方案
Java
4
star
18

Android-WhiteListTool

Android 启动白名单工具
Kotlin
4
star
19

Hannibai

A easy way to use android SharePreference.
Java
3
star
20

VlayoutHelper

vlayout & databinding & MVVM
Java
3
star
21

RemoteBuild

远程编译项目
Shell
3
star
22

Android-ViewContext

扩展Fragment、Activity方便获取Context、Activity、LifecycleOwner、Resources
Kotlin
2
star
23

Android-WebShareInfo

获取WebView中H5的分享(开放图谱)信息
Kotlin
2
star
24

SupperTextView

Java
1
star
25

SwipeToLoadLayout

Kotlin
1
star
26

Android-KnowledgeGraph

Android 知识点归纳总结
1
star
27

Android-GitHubAppDownload

官方GitHub App下载,给不方便翻墙的童鞋~
1
star