Skip to content

Commit

Permalink
feat: 重构,支持Binder复用
Browse files Browse the repository at this point in the history
  • Loading branch information
wangchenyan committed Sep 25, 2022
1 parent 0346d91 commit d227fbb
Showing 1 changed file with 51 additions and 17 deletions.
68 changes: 51 additions & 17 deletions radapter3/src/main/java/me/wcy/radapter3/RAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ class RAdapter<T> : RecyclerView.Adapter<ViewBindingHolder<*>>() {
private val dataList: MutableList<T> = mutableListOf()
private val typePool by lazy { RTypePool() }

companion object {
private const val TAG = "RAdapter"
}

/**
* 注册 ViewBinder
*
* @param viewBinder 视图绑定器
*/
inline fun <VB : ViewBinding, reified D> register(viewBinder: RViewBinder<VB, D>): RAdapter<T> {
register(D::class.java) { viewBinder }
Expand All @@ -26,6 +24,9 @@ class RAdapter<T> : RecyclerView.Adapter<ViewBindingHolder<*>>() {

/**
* 注册 ViewBinder
*
* @param model 数据类型
* @param mapper 数据到 [RViewBinder] 的映射,支持一种数据对应多种 View。注意:映射方法会多次调用,如果要做到性能最优,建议复用 [RViewBinder],不要每次都重新构造。
*/
fun <D> register(
model: Class<D>, mapper: (data: D) -> RViewBinder<*, D>
Expand All @@ -35,51 +36,80 @@ class RAdapter<T> : RecyclerView.Adapter<ViewBindingHolder<*>>() {
}

/**
* 获取数据列表
* 获取数据集
*/
fun getDataList(): List<T> {
return dataList
}

/**
* 刷新数据集
*/
fun refresh(list: List<T>) {
dataList.clear()
dataList.addAll(list)
notifyDataSetChanged()
}

/**
* 添加数据并刷新视图
*/
fun add(item: T, index: Int? = null) {
val position = if (index != null && index in 0..dataList.size) {
index
} else {
dataList.size
if (index != null && index !in 0..dataList.size) {
Log.w(TAG, "下标越界,size: ${dataList.size}, index: $index")
return
}
val position = index ?: dataList.size
dataList.add(position, item)
notifyItemInserted(position)
}

/**
* 添加数据集并刷新视图
*/
fun addAll(list: List<T>) {
dataList.addAll(list)
notifyDataSetChanged()
}

/**
* 移除数据并刷新视图
*/
fun remove(position: Int) {
if (position in 0 until dataList.size) {
dataList.removeAt(position)
notifyItemRemoved(position)
if (position !in 0 until dataList.size) {
Log.w(TAG, "下标越界,size: ${dataList.size}, position: $position")
return
}
dataList.removeAt(position)
notifyItemRemoved(position)
}

/**
* 移除数据并刷新视图
*/
fun remove(item: T) {
remove(dataList.indexOf(item))
}

/**
* 更新数据并刷新视图
*/
fun change(item: T, position: Int) {
if (position in 0 until dataList.size && item != null) {
dataList[position] = item
notifyItemChanged(position)
if (position !in 0 until dataList.size) {
Log.w(TAG, "下标越界,size: ${dataList.size}, position: $position")
return
}
if (item == null) {
Log.w(TAG, "item is null")
return
}
dataList[position] = item
notifyItemChanged(position)
}

/**
* 数据是否为空
*/
fun isEmpty() = dataList.isEmpty()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewBindingHolder<*> {
Expand All @@ -92,7 +122,7 @@ class RAdapter<T> : RecyclerView.Adapter<ViewBindingHolder<*>>() {
try {
holder.viewBinder.onBindInternal(holder.vb, dataList[position] as Any, position)
} catch (e: Throwable) {
Log.e(TAG, "bind view holder error", e)
Log.e(TAG, "bind view error", e)
}
}

Expand All @@ -104,8 +134,12 @@ class RAdapter<T> : RecyclerView.Adapter<ViewBindingHolder<*>>() {
val data = dataList[position]
val type = typePool.getTypePosition(data)
if (type < 0) {
throw IllegalStateException("can not find view type of ${data}, have you register the data?")
throw IllegalStateException("can not find view type for ${data}, have you register the data?")
}
return type
}

companion object {
private const val TAG = "RAdapter"
}
}

0 comments on commit d227fbb

Please sign in to comment.