Skip to content

Commit

Permalink
优化API
Browse files Browse the repository at this point in the history
  • Loading branch information
wangchenyan committed Oct 18, 2022
1 parent e47d619 commit ec44c2e
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 27 deletions.
28 changes: 21 additions & 7 deletions radapter3/src/main/java/me/wcy/radapter3/RAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,28 @@ class RAdapter<T> : RecyclerView.Adapter<ViewBindingHolder<*>>() {
*
* @param viewBinder 视图绑定器
*/
inline fun <reified VB : ViewBinding, reified D> register(viewBinder: RViewBinder<VB, D>): RAdapter<T> {
register(D::class.java, object : RTypeMapper<D> {
override fun map(data: D): Pair<RViewBinder<out ViewBinding, D>, KClass<out ViewBinding>> {
return Pair(viewBinder, VB::class)
inline fun <reified VB : ViewBinding, reified D : Any> register(viewBinder: RViewBinder<VB, D>) =
apply {
register(viewBinder, VB::class, D::class)
}

/**
* 注册 ViewBinder
*
* @param viewBinder 视图绑定器
*/
fun <VB : ViewBinding, D : Any> register(
viewBinder: RViewBinder<VB, D>,
bindingClazz: KClass<VB>,
dataClazz: KClass<D>
) = apply {
register(dataClazz, object : RTypeMapper<D> {
override fun map(data: D): RViewBinder<out ViewBinding, D> {
return viewBinder.apply {
setViewBindingClazz(bindingClazz)
}
}
})
return this
}

/**
Expand All @@ -33,9 +48,8 @@ class RAdapter<T> : RecyclerView.Adapter<ViewBindingHolder<*>>() {
* @param model 数据类型
* @param mapper 数据到 [RViewBinder] 的映射,支持一种数据对应多种 View
*/
fun <D> register(model: Class<D>, mapper: RTypeMapper<D>): RAdapter<T> {
fun <D : Any> register(model: KClass<D>, mapper: RTypeMapper<D>) = apply {
typePool.register(model, mapper)
return this
}

/**
Expand Down
6 changes: 4 additions & 2 deletions radapter3/src/main/java/me/wcy/radapter3/RType.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package me.wcy.radapter3

import kotlin.reflect.KClass

/**
* 一个列表 item 的实体,包含数据类型和 ViewBinder
*
* Created by wangchenyan on 2018/9/21.
*/
internal class RType<T>(
internal val model: Class<T>,
internal class RType<T : Any>(
internal val model: KClass<T>,
internal val mapper: RTypeMapper<T>
) {

Expand Down
2 changes: 1 addition & 1 deletion radapter3/src/main/java/me/wcy/radapter3/RTypeMapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ import kotlin.reflect.KClass
* 注意:映射方法会多次调用,如果要做到性能最优,建议复用 [RViewBinder],不要每次都重新构造。
*/
interface RTypeMapper<T> {
fun map(data: T): Pair<RViewBinder<out ViewBinding, T>, KClass<out ViewBinding>>
fun map(data: T): RViewBinder<out ViewBinding, T>
}
16 changes: 8 additions & 8 deletions radapter3/src/main/java/me/wcy/radapter3/RTypePool.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package me.wcy.radapter3

import kotlin.reflect.KClass

/**
* 列表 item 实体管理器
*
Expand All @@ -14,8 +16,8 @@ internal class RTypePool {
/**
* 注册一个实体
*/
fun <T> register(
model: Class<T>,
fun <T : Any> register(
model: KClass<T>,
mapper: RTypeMapper<T>
) {
val type = RType(model, mapper)
Expand All @@ -34,18 +36,18 @@ internal class RTypePool {
if (data == null) {
return -1
}
val clazz = data.javaClass
val dataClazz = data.javaClass
var mapper: RTypeMapper<Any>? = null
for (type in typeList) {
if (clazz == type.model) {
if (dataClazz == type.model.java) {
mapper = type.mapper as RTypeMapper<Any>
break
}
}
if (mapper == null) {
// 尝试查找子类
for (type in typeList) {
if (type.model.isAssignableFrom(clazz)) {
if (type.model.java.isAssignableFrom(dataClazz)) {
mapper = type.mapper as RTypeMapper<Any>
break
}
Expand All @@ -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
}
Expand Down
19 changes: 17 additions & 2 deletions radapter3/src/main/java/me/wcy/radapter3/RViewBinder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,26 @@ import kotlin.reflect.KClass
* Created by wangchenyan.top on 2022/9/25.
*/
abstract class RViewBinder<VB : ViewBinding, T> {
internal lateinit var viewBindingClazz: KClass<*>
private var viewBindingClazz: KClass<*>? = null
lateinit var adapter: RAdapter<Any>

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<VB> {
val inflateMethod = viewBindingClazz.java.getMethod(
val inflateMethod = getViewBindingClazz().java.getMethod(
"inflate",
LayoutInflater::class.java,
ViewGroup::class.java,
Expand Down
19 changes: 12 additions & 7 deletions simple/src/main/java/me/wcy/radapter3/simple/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ class MainActivity : AppCompatActivity() {

val adapter = RAdapter<Any>()
adapter.register(ImageViewBinder())
val textViewBinder1 = TextViewBinder1()
val textViewBinder2 = TextViewBinder2()
adapter.register(Text::class.java, object : RTypeMapper<Text> {
override fun map(data: Text): Pair<RViewBinder<out ViewBinding, Text>, KClass<out ViewBinding>> {
adapter.register(Text::class, object : RTypeMapper<Text> {
val textViewBinder1 = TextViewBinder1()
val textViewBinder2 = TextViewBinder2()

override fun map(data: Text): RViewBinder<out ViewBinding, Text> {
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
}
}
})
Expand All @@ -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<ViewHolderText2Binding, Text>() {
Expand All @@ -82,5 +85,7 @@ class MainActivity : AppCompatActivity() {
.show()
}
}

override fun getViewBindingClazz(): KClass<*> = ViewHolderText2Binding::class
}
}

0 comments on commit ec44c2e

Please sign in to comment.