7

使用 SugarAdapter 快速构建 Android 列表页面

 3 years ago
source link: https://zhuanlan.zhihu.com/p/51659894
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用 SugarAdapter 快速构建 Android 列表页面

斯拉夫传承者,嘴炮学家

知乎 App 中存在大量的列表页面,可预见的未来还会不断增加,因此需要一种易上手、可维护的列表「脚手架」来支撑业务需求。

假定读者对 RecyclerView 的 原始写法 相对熟悉。一些简化 RecyclerView 使用难度的方案试图通过绕过 ViewHolder 的概念,进而直接操纵 ViewHolder 其中的 View ,代码相对中心化,失去了 ViewHolder 的可复用性;另一些也没能简化编写 Adapter 的冗余代码,仅仅把 Adapter 的概念带到了其他地方。SugarAdapter 不会试图逃避任何 RecyclerView 的所有概念,仅仅是写法上的简化,没有额外的认知成本(详细介绍可参见 GitHub 链接 )。

首先,你不需要继承并复写 Adapter ,即使是复杂类型的列表,也只需要写几行 Builder 模式的代码,冗余代码全部通过 annotationProcessor 生成:

mAdapter = SugarAdapter.Builder.with(mList) // eg. List<Object>
            .add(FooHolder.class) // extends SugarHolder<Foo>
            .add(BarHolder.class, new SugarHolder.OnCreatedCallback<BarHolder>() {
                @Override
                public void onCreated(@NonNull BarHolder holder) {
                    // holder.SETTER etc.
                }
            })
            .build();
mRecyclerView.setAdapter(mAdapter);

// mAdapter.notifyItem* or mAdapter.notifyDataSetChanged()
// mAdapter.setExtraDelegate() with onAttachedToRecyclerView()/onDetachedFromRecyclerView()

接着是 SugarHolder 。在长时间使用 RecyclerView 创建多种列表视图的过程中,我们注意到,通常对于一个 ViewHolder 而言,其 ViewType(类型)、Layout(视图层)和 Data(数据)是强相关的,因此我们简单认为 Layout – ViewType – Data 是「三位一体」的存在,这一模式对于简化 RecyclerView 的使用十分有效。此外,ViewHolder 本身可以视为列表中细粒度的 Controller ,与编写一个简单的 Activity 或者 Fragment 没有明显区别:

// 务必注解的保证子类是 public 和 final 的;R.layout.foo 同时也是 ViewType
@Layout(R.layout.foo) 
public final class FooHolder extends SugarHolder<Foo> {
    // 如果你不想手写 findViewById() 代码,
    // 只需要给定义的 View 加上 @Id() 注解,并且保证它为 public 的即可;
    // @Id() 同样只能作用于 **final** class
    @Id(R.id.text);
    public TextView mTextView;

    public FooHolder(@NonNull View view) {
        super(view);
    }

    @Override
    pubilc void onBindData(@NonNull Foo foo) {
        mTextView.setText(foo.getText());
    }
}

经过上述过程,构造列表页面的过程基本完成了。在 annotationProcessor 的帮助下省去了需要人工编写的冗余代码,同时隐藏了中心化的列表绑定逻辑,使得 RecyclerView 的相关的代码更易于维护和上手。经过知乎 Android 一年多的线上实践表明,这种设计在客户端存在大量列表视图类型的情况下,其复杂度并没有提升,可以说是一套不错的解决方案(其实是我比较懒,一年多前写好了,现在才开源。

项目地址和详细解释:https://github.com/zhihu/SugarAdapter

(不要忘记点击右上角的 Star 按钮哟

我想马上引入:

dependencies {
    // 如果你想要迁移到 AndroidX ,可以使用 1.8.3
    implementation 'com.zhihu.android:sugaradapter:1.7.5'
    annotationProcessor 'com.zhihu.android:sugaradapter-processor:1.7.5'
}

这里是广告:知乎社区平台移动端团队,负责知乎社区核心产品的开发与维护工作,为知乎社区移动端的体验和技术建设负责。在知乎成长的过程中,我们渴望对技术有追求的小伙伴加入,一起解决知乎移动端在实际业务中面对的技术挑战,攻克关乎用户体验的各项技术难题。简历请投递至 [email protected]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK