一个全新的RecyclerView Adapter框架源码开源
2020/7/4 23:55:46
本文主要是介绍一个全新的RecyclerView Adapter框架源码开源,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
RecyclerViewAdapter
重新定义RecyclerView Adapter的封装,追求既简单又实用,结合Kotlin的高级特性,优化代码书写方式,真正做到高内聚低耦合
开源地址
Github RecyclerViewAdapter
框架设计核心思想
- 摒弃notifyDataSetChanged无脑操作,利用ObservableList自动匹配数据,并实现局部刷新
- 真正通用的ViewHolder抽象,从此只关注Layout XML布局
- 真正通用的Adapter,从此不再写Adapter子类
- ItemViewType自动匹配对象Layout XML,不再关心它的细节
- 科学的分包处理,真正做到框架的各取所需(一般列表只需引用Adapter-core核心库即可)
- 扩展Anko Layout版本,体验Anko Layout的魅力,并能获取高于XML加载至少3倍以上的效率提升
- 像堆积木一样,将页面的每个模块都做到了复用,跟Fragment可以说再见
设计图
![Image](/upload/202007/04/202007042355462370.png)
规划
核心库Core的完善Anko扩展- FlexboxLayout 扩展
- SortedList 扩展
- paging 3 扩展
- DiffUtil 扩展
- DataBinding 扩展
- 等等.. 未来有好的想法继续扩展
环境需要
- Kotlin
- JAVA
- AndroidX 抱歉目前按照最新的AndroidX适配的,如有其他需要请私聊我。
怎么用
ArrayListAdapter
step1
创建xml布局,和之前一样的布局方式
<?xml version="1.0" encoding="utf-8"?> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:layout_margin="5dp"> <LinearLayout android:background="?attr/selectableItemBackground" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp" android:orientation="vertical"> <TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/colorPrimary" android:textSize="22sp" /> <TextView android:id="@+id/tv_subTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/colorAccent" android:textSize="18sp" /> </LinearLayout> </androidx.cardview.widget.CardView> 复制代码
step2
定义ViewModel及Model,可以看到,逻辑简单明了,刷新自己的时候只需要更新Model,并reBindView即可,刷新别人的话,需要通过Adapter去更新,复杂页面只需要再新建一个ArrayItemViewModel的子类即可,并创建一个新的XML布局,从这里的代码可以看出,同样一个ViewModel未来可以复用很多XML布局,完全做到了ViewModel、View、Model三个角色的任意复用。为业务多样化提供最底层的支持。
/** * Model */ data class ModelTest(var title: String, var subTitle: String) /** * ViewModel */ class ArrayViewModelTest : ArrayItemViewModel<ModelTest>() { var index = 0 override fun onBindView(adapter: ArrayListAdapter?) { viewHolder.itemView.apply { tv_title.text = model.title tv_subTitle.text = model.subTitle cardItem.setOnClickListener { model.title = "${index++}" reBindView() } } } override fun getLayoutRes() = R.layout.item_test } 复制代码
复用逻辑如下图:
![](/upload/202007/04/202007042355464773.png)
step3
Activity 中增删改,增删改都是对ViewModel层的操作,简单实用。
/** * Activity */ class ArrayListActivity : AppCompatActivity() { private val mArrayListAdapter by lazy { ArrayListAdapter() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_array_list) rv_list.bindListAdapter(mArrayListAdapter) // 新增一个 new_add.setText("新增").setOnClickListener { mArrayListAdapter.add(ArrayViewModelTest().apply { model = ModelTest("标题", "副标题") }) } // 删除第一个 delete.setText("删除").setOnClickListener { if (mArrayListAdapter.size > 0) mArrayListAdapter.removeAt(0) else toast("请添加新用例后再试") } // 随机更新 var updateSize = 0 update.setText("更新").setOnClickListener { updateSize++ if (mArrayListAdapter.size > 0) { val randomInt = Random.nextInt(0, mArrayListAdapter.size) mArrayListAdapter.set(randomInt, ArrayViewModelTest().apply { model = ModelTest("标题$updateSize", "副标题$updateSize") }) } else { toast("请添加新用例后再试") } } } } 复制代码
AnkoListAdapter
step1
定义AnkoLayout
/** * AnkoItemView */ class AnkoItemView() : AnkoComponent<ViewGroup> { var tvTitle: TextView? = null var tvSubTitle: TextView? = null @SuppressLint("ResourceType") override fun createView(ui: AnkoContext<ViewGroup>) = with(ui) { cardView { layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT ).apply { margin = dip(5) } verticalLayout { val typedValue = TypedValue() context.theme .resolveAttribute(android.R.attr.selectableItemBackground, typedValue, true) val attribute = intArrayOf(android.R.attr.selectableItemBackground) val typedArray = context.theme.obtainStyledAttributes(typedValue.resourceId, attribute) background = typedArray.getDrawable(0) layoutParams = FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT ).apply { padding = dip(10) } tvTitle = textView { textSize = px2dip(60) textColorResource = R.color.colorPrimary }.lparams(matchParent, wrapContent) tvSubTitle = textView { textSize = px2dip(45) textColorResource = R.color.colorAccent }.lparams(matchParent, wrapContent) } } } } 复制代码
step2
定义ViewModel,Model
/** * Model */ data class ModelTest(var title: String, var subTitle: String) /** * ViewModel */ class AnkoViewModelTest : AnkoItemViewModel<ModelTest, AnkoItemView>() { var index = 0 override fun onBindView(adapter: AnkoListAdapter) { ankoView.tvTitle?.text = model.title ankoView.tvSubTitle?.text = model.subTitle viewHolder.itemView.setOnClickListener { model.title = "${index++}" reBindView() } } override fun onCreateView(): AnkoItemView { return AnkoItemView() } } 复制代码
step3
Activity 中增删改
/** * Activity */ class AnkoLayoutActivity : AppCompatActivity() { private val mAnkoListAdapter by lazy { AnkoListAdapter() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) AnkoLayoutComponent(mAnkoListAdapter).setContentView(this).apply { // 新增一个 new_add.setText("新增").setOnClickListener { mAnkoListAdapter.add(AnkoViewModelTest().apply { model = ModelTest("标题", "副标题") }) } // 删除第一个 delete.setText("删除").setOnClickListener { if (mAnkoListAdapter.size > 0) mAnkoListAdapter.removeAt(0) else toast("请添加新用例后再试") } // 随机更新 var updateSize = 0 update.setText("更新").setOnClickListener { updateSize++ if (mAnkoListAdapter.size > 0) { val randomInt = Random.nextInt(0, mAnkoListAdapter.size) mAnkoListAdapter.set(randomInt, mAnkoListAdapter.getItem(randomInt).apply { model.also { it as ModelTest it.title = "$updateSize" } }) } else { toast("请添加新用例后再试") } } } } } /** * View * */ class AnkoLayoutComponent(private val ankoListAdapter: AnkoListAdapter) : AnkoComponent<AnkoLayoutActivity> { override fun createView(ui: AnkoContext<AnkoLayoutActivity>) = with(ui) { verticalLayout { recyclerView { bindListAdapter(ankoListAdapter) }.lparams(matchParent) { weight = 1F } // Anko 兼容 xml布局的加载 include<View>(R.layout.include_button_bottom) } } } 复制代码
上一篇博客
一个资深的Android是不是应该学会自己做一个超级的RecyclerView.Adapter
开发者
- i校长
- Jetpack.net.cn
- 简书
- 掘金
这篇关于一个全新的RecyclerView Adapter框架源码开源的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-01-18android.permission.read_media_video
- 2024-01-18android_getaddrinfo failed eai_nodata
- 2024-01-18androidmo
- 2024-01-15Android下三种离屏渲染技术
- 2024-01-09Android 蓝牙使用
- 2024-01-06Android对接华为AI - 文本识别
- 2023-11-15代码安全之代码混淆及加固(Android)
- 2023-11-10简述Android语音播报TTS
- 2023-11-06Android WiFi工具类
- 2023-07-22Android开发未来的出路