From ec44c2e2a0e366be5fc74547a0f07aaa52502337 Mon Sep 17 00:00:00 2001 From: wcy <919247701@qq.com> Date: Tue, 18 Oct 2022 18:36:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/me/wcy/radapter3/RAdapter.kt | 28 ++++++++++++++----- .../src/main/java/me/wcy/radapter3/RType.kt | 6 ++-- .../main/java/me/wcy/radapter3/RTypeMapper.kt | 2 +- .../main/java/me/wcy/radapter3/RTypePool.kt | 16 +++++------ .../main/java/me/wcy/radapter3/RViewBinder.kt | 19 +++++++++++-- .../me/wcy/radapter3/simple/MainActivity.kt | 19 ++++++++----- 6 files changed, 63 insertions(+), 27 deletions(-) diff --git a/radapter3/src/main/java/me/wcy/radapter3/RAdapter.kt b/radapter3/src/main/java/me/wcy/radapter3/RAdapter.kt index a3be924..e6d780c 100644 --- a/radapter3/src/main/java/me/wcy/radapter3/RAdapter.kt +++ b/radapter3/src/main/java/me/wcy/radapter3/RAdapter.kt @@ -18,13 +18,28 @@ class RAdapter : RecyclerView.Adapter>() { * * @param viewBinder 视图绑定器 */ - inline fun register(viewBinder: RViewBinder): RAdapter { - register(D::class.java, object : RTypeMapper { - override fun map(data: D): Pair, KClass> { - return Pair(viewBinder, VB::class) + inline fun register(viewBinder: RViewBinder) = + apply { + register(viewBinder, VB::class, D::class) + } + + /** + * 注册 ViewBinder + * + * @param viewBinder 视图绑定器 + */ + fun register( + viewBinder: RViewBinder, + bindingClazz: KClass, + dataClazz: KClass + ) = apply { + register(dataClazz, object : RTypeMapper { + override fun map(data: D): RViewBinder { + return viewBinder.apply { + setViewBindingClazz(bindingClazz) + } } }) - return this } /** @@ -33,9 +48,8 @@ class RAdapter : RecyclerView.Adapter>() { * @param model 数据类型 * @param mapper 数据到 [RViewBinder] 的映射,支持一种数据对应多种 View */ - fun register(model: Class, mapper: RTypeMapper): RAdapter { + fun register(model: KClass, mapper: RTypeMapper) = apply { typePool.register(model, mapper) - return this } /** diff --git a/radapter3/src/main/java/me/wcy/radapter3/RType.kt b/radapter3/src/main/java/me/wcy/radapter3/RType.kt index d4bfc25..1bc8c85 100644 --- a/radapter3/src/main/java/me/wcy/radapter3/RType.kt +++ b/radapter3/src/main/java/me/wcy/radapter3/RType.kt @@ -1,12 +1,14 @@ package me.wcy.radapter3 +import kotlin.reflect.KClass + /** * 一个列表 item 的实体,包含数据类型和 ViewBinder * * Created by wangchenyan on 2018/9/21. */ -internal class RType( - internal val model: Class, +internal class RType( + internal val model: KClass, internal val mapper: RTypeMapper ) { diff --git a/radapter3/src/main/java/me/wcy/radapter3/RTypeMapper.kt b/radapter3/src/main/java/me/wcy/radapter3/RTypeMapper.kt index 3d47022..5347281 100644 --- a/radapter3/src/main/java/me/wcy/radapter3/RTypeMapper.kt +++ b/radapter3/src/main/java/me/wcy/radapter3/RTypeMapper.kt @@ -9,5 +9,5 @@ import kotlin.reflect.KClass * 注意:映射方法会多次调用,如果要做到性能最优,建议复用 [RViewBinder],不要每次都重新构造。 */ interface RTypeMapper { - fun map(data: T): Pair, KClass> + fun map(data: T): RViewBinder } \ No newline at end of file diff --git a/radapter3/src/main/java/me/wcy/radapter3/RTypePool.kt b/radapter3/src/main/java/me/wcy/radapter3/RTypePool.kt index b900f9f..727c4f5 100644 --- a/radapter3/src/main/java/me/wcy/radapter3/RTypePool.kt +++ b/radapter3/src/main/java/me/wcy/radapter3/RTypePool.kt @@ -1,5 +1,7 @@ package me.wcy.radapter3 +import kotlin.reflect.KClass + /** * 列表 item 实体管理器 * @@ -14,8 +16,8 @@ internal class RTypePool { /** * 注册一个实体 */ - fun register( - model: Class, + fun register( + model: KClass, mapper: RTypeMapper ) { val type = RType(model, mapper) @@ -34,10 +36,10 @@ internal class RTypePool { if (data == null) { return -1 } - val clazz = data.javaClass + val dataClazz = data.javaClass var mapper: RTypeMapper? = null for (type in typeList) { - if (clazz == type.model) { + if (dataClazz == type.model.java) { mapper = type.mapper as RTypeMapper break } @@ -45,7 +47,7 @@ internal class RTypePool { if (mapper == null) { // 尝试查找子类 for (type in typeList) { - if (type.model.isAssignableFrom(clazz)) { + if (type.model.java.isAssignableFrom(dataClazz)) { mapper = type.mapper as RTypeMapper break } @@ -55,11 +57,9 @@ internal class RTypePool { return -1 } // TODO 避免多次创建 ViewBinder 实例 - val pair = mapper.map(data) - val viewBinder = pair.first + val viewBinder = mapper.map(data) var exist = viewBinderList.find { it.javaClass == viewBinder.javaClass } if (exist == null) { - viewBinder.viewBindingClazz = pair.second viewBinderList.add(viewBinder) exist = viewBinder } diff --git a/radapter3/src/main/java/me/wcy/radapter3/RViewBinder.kt b/radapter3/src/main/java/me/wcy/radapter3/RViewBinder.kt index c12f9df..3bb342f 100644 --- a/radapter3/src/main/java/me/wcy/radapter3/RViewBinder.kt +++ b/radapter3/src/main/java/me/wcy/radapter3/RViewBinder.kt @@ -9,11 +9,26 @@ import kotlin.reflect.KClass * Created by wangchenyan.top on 2022/9/25. */ abstract class RViewBinder { - internal lateinit var viewBindingClazz: KClass<*> + private var viewBindingClazz: KClass<*>? = null lateinit var adapter: RAdapter + open fun getViewBindingClazz(): KClass<*> { + if (viewBindingClazz == null) { + throw IllegalStateException( + "viewBindingClazz can not be null!" + + "\nIf you use 'RTypeMapper', place override 'getViewBindingClazz()' method from 'RViewBinder'" + + ", and provide ViewBinding class" + ) + } + return viewBindingClazz!! + } + + internal fun setViewBindingClazz(clazz: KClass<*>) { + viewBindingClazz = clazz + } + fun onCreateViewHolder(parent: ViewGroup): ViewBindingHolder { - val inflateMethod = viewBindingClazz.java.getMethod( + val inflateMethod = getViewBindingClazz().java.getMethod( "inflate", LayoutInflater::class.java, ViewGroup::class.java, diff --git a/simple/src/main/java/me/wcy/radapter3/simple/MainActivity.kt b/simple/src/main/java/me/wcy/radapter3/simple/MainActivity.kt index 6ee1a83..8184fdf 100644 --- a/simple/src/main/java/me/wcy/radapter3/simple/MainActivity.kt +++ b/simple/src/main/java/me/wcy/radapter3/simple/MainActivity.kt @@ -40,14 +40,15 @@ class MainActivity : AppCompatActivity() { val adapter = RAdapter() adapter.register(ImageViewBinder()) - val textViewBinder1 = TextViewBinder1() - val textViewBinder2 = TextViewBinder2() - adapter.register(Text::class.java, object : RTypeMapper { - override fun map(data: Text): Pair, KClass> { + adapter.register(Text::class, object : RTypeMapper { + val textViewBinder1 = TextViewBinder1() + val textViewBinder2 = TextViewBinder2() + + override fun map(data: Text): RViewBinder { return when (data.style) { - 1 -> Pair(textViewBinder1, ViewHolderText1Binding::class) - 2 -> Pair(textViewBinder2, ViewHolderText2Binding::class) - else -> Pair(textViewBinder2, ViewHolderText2Binding::class) + 1 -> textViewBinder1 + 2 -> textViewBinder2 + else -> textViewBinder2 } } }) @@ -72,6 +73,8 @@ class MainActivity : AppCompatActivity() { override fun onBind(viewBinding: ViewHolderText1Binding, item: Text, position: Int) { viewBinding.text1.text = item.text } + + override fun getViewBindingClazz(): KClass<*> = ViewHolderText1Binding::class } class TextViewBinder2 : RViewBinder() { @@ -82,5 +85,7 @@ class MainActivity : AppCompatActivity() { .show() } } + + override fun getViewBindingClazz(): KClass<*> = ViewHolderText2Binding::class } }