Skip to content

Commit

Permalink
findViewById复用
Browse files Browse the repository at this point in the history
  • Loading branch information
lizixian committed Jun 16, 2021
1 parent 705f764 commit 9e28eb4
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 45 deletions.
6 changes: 6 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 19 additions & 17 deletions library/src/main/java/com/lzx/library/EfficientAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package com.lzx.library

import android.support.v4.util.SparseArrayCompat
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup

open class EfficientAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
open class EfficientAdapter<T> : RecyclerView.Adapter<BaseViewHolder>() {

companion object {
private const val FALLBACK_DELEGATE_VIEW_TYPE = Int.MAX_VALUE - 1
Expand All @@ -13,25 +14,26 @@ open class EfficientAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>()
var items: MutableList<T>? = mutableListOf()
private val typeHolders: SparseArrayCompat<ViewHolderCreator<T>> = SparseArrayCompat()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val holder = getHolderForViewType(viewType)
?: throw NullPointerException("No Holder added for ViewType $viewType")
return BaseViewHolder(parent, holder.getResourceId())
?: throw NullPointerException("No Holder added for ViewType $viewType")
val view = LayoutInflater.from(parent.context).inflate(holder.getResourceId(), parent, false)
return BaseViewHolder(view)
}

override fun getItemCount(): Int = items?.size ?: 0

override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
override fun onBindViewHolder(viewHolder: BaseViewHolder, position: Int) {
onBindViewHolder(viewHolder, position, mutableListOf())
}

override fun onBindViewHolder(
viewHolder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>
viewHolder: BaseViewHolder, position: Int, payloads: MutableList<Any>
) {
val holder = getHolderForViewType(viewHolder.itemViewType)
?: throw NullPointerException(
"No Holder added for ViewType " + viewHolder.itemViewType)
holder.registerItemView(viewHolder.itemView)
?: throw NullPointerException(
"No Holder added for ViewType " + viewHolder.itemViewType)
holder.registerViewHolder(viewHolder)
holder.onBindViewHolder(items?.get(position), items, position, holder)
}

Expand All @@ -49,7 +51,7 @@ open class EfficientAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>()

//找不到匹配的 viewType
throw NullPointerException(
"No holder added that matches at position=$position in data source")
"No holder added that matches at position=$position in data source")
}

private fun getHolderForViewType(viewType: Int): ViewHolderCreator<T>? {
Expand All @@ -65,8 +67,8 @@ open class EfficientAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>()
viewType++
require(viewType != FALLBACK_DELEGATE_VIEW_TYPE) {
"Oops, we are very close to Integer.MAX_VALUE. " +
"It seems that there are no more free and " +
"unused view type integers left to add another holder."
"It seems that there are no more free and " +
"unused view type integers left to add another holder."
}
}
return addTypeHolder(viewType, holder)
Expand All @@ -81,11 +83,11 @@ open class EfficientAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>()
}
require(viewType != FALLBACK_DELEGATE_VIEW_TYPE) {
"The view type = " + FALLBACK_DELEGATE_VIEW_TYPE +
" is reserved for fallback adapter holder Please use another view type."
" is reserved for fallback adapter holder Please use another view type."
}
require(typeHolders.get(viewType) == null) {
"An holder is already registered for the viewType = $viewType. Already registered holder is " +
typeHolders.get(viewType)
typeHolders.get(viewType)
}
typeHolders.put(viewType, holder)
}
Expand Down Expand Up @@ -132,8 +134,8 @@ open class EfficientAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>()
viewType++
require(viewType != FALLBACK_DELEGATE_VIEW_TYPE) {
"Oops, we are very close to Integer.MAX_VALUE. " +
"It seems that there are no more free" +
"and unused view type integers left to add another holder."
"It seems that there are no more free" +
"and unused view type integers left to add another holder."
}
}
return register(viewType, holder)
Expand All @@ -145,7 +147,7 @@ open class EfficientAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>()
fun register(viewType: Int, holder: ViewHolderCreator<T>) = apply {
require(viewType != FALLBACK_DELEGATE_VIEW_TYPE) {
"The view type = $FALLBACK_DELEGATE_VIEW_TYPE is reserved " +
"for fallback adapter holder). Please use another view type."
"for fallback adapter holder). Please use another view type."
}
typeHolders.put(viewType, holder)
}
Expand Down
6 changes: 3 additions & 3 deletions library/src/main/java/com/lzx/library/EfficientAdapterExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ fun <T : Any> EfficientAdapter<T>.addItem(resourceId: Int, init: ViewHolderDsl<T
class ViewHolderDsl<T>(private val resourceId: Int) : ViewHolderCreator<T>() {

private var viewType: ((data: T?, position: Int) -> Boolean)? = null
private var viewHolder: ((data: T?, position: Int, holder: ViewHolderCreator<T>) -> Unit)? =
private var holderCreator: ((data: T?, position: Int, holder: ViewHolderCreator<T>) -> Unit)? =
null

fun isForViewType(viewType: (data: T?, position: Int) -> Boolean) {
this.viewType = viewType
}

fun bindViewHolder(holder: (data: T?, position: Int, holder: ViewHolderCreator<T>) -> Unit) {
viewHolder = holder
holderCreator = holder
}

override fun isForViewType(data: T?, position: Int): Boolean {
Expand All @@ -42,7 +42,7 @@ class ViewHolderDsl<T>(private val resourceId: Int) : ViewHolderCreator<T>() {
override fun getResourceId() = resourceId

override fun onBindViewHolder(data: T?, items: MutableList<T>?, position: Int, holder: ViewHolderCreator<T>) {
viewHolder?.invoke(data, position, holder)
holderCreator?.invoke(data, position, holder)
}
}

Expand Down
58 changes: 34 additions & 24 deletions library/src/main/java/com/lzx/library/ViewHolderCreator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,52 @@ package com.lzx.library
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.os.Build
import android.support.annotation.IdRes
import android.support.v7.widget.RecyclerView
import android.util.SparseArray
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnLongClickListener
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView

class BaseViewHolder(parent: ViewGroup, resource: Int) : RecyclerView.ViewHolder(
LayoutInflater.from(parent.context).inflate(resource, parent, false)
)
class BaseViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val views = SparseArray<View>()

fun <T : View> findViewById(@IdRes viewId: Int): T {
var view = views[viewId]
if (view == null) {
view = itemView.findViewById(viewId)
views.put(viewId, view)
}
return view as T
}
}

abstract class ViewHolderCreator<T> {
abstract fun isForViewType(data: T?, position: Int): Boolean
abstract fun getResourceId(): Int
abstract fun onBindViewHolder(
data: T?,
items: MutableList<T>?,
position: Int,
holder: ViewHolderCreator<T>
data: T?,
items: MutableList<T>?,
position: Int,
holder: ViewHolderCreator<T>
)

var itemView: View? = null
var viewHolder: BaseViewHolder? = null

fun registerItemView(itemView: View?) {
this.itemView = itemView
fun registerViewHolder(viewHolder: BaseViewHolder?) {
this.viewHolder = viewHolder
}

fun <V : View> findViewById(viewId: Int): V {
checkItemView()
return itemView!!.findViewById(viewId)
return viewHolder!!.findViewById(viewId)
}

private fun checkItemView() {
if (itemView == null) {
if (viewHolder == null) {
throw NullPointerException("itemView is null")
}
}
Expand Down Expand Up @@ -79,15 +89,15 @@ fun <T> ViewHolderCreator<T>.setBackgroundResource(viewId: Int, resid: Int) = ap
}

fun <T> ViewHolderCreator<T>.visible(id: Int) =
apply { findViewById<View>(id).visibility = View.VISIBLE }
apply { findViewById<View>(id).visibility = View.VISIBLE }

fun <T> ViewHolderCreator<T>.invisible(id: Int) =
apply { findViewById<View>(id).visibility = View.INVISIBLE }
apply { findViewById<View>(id).visibility = View.INVISIBLE }

fun <T> ViewHolderCreator<T>.gone(id: Int) = apply { findViewById<View>(id).visibility = View.GONE }

fun <T> ViewHolderCreator<T>.visibility(id: Int, visibility: Int) =
apply { findViewById<View>(id).visibility = visibility }
apply { findViewById<View>(id).visibility = visibility }

fun <T> ViewHolderCreator<T>.setTextColor(id: Int, color: Int) = apply {
val view: TextView = findViewById(id)
Expand All @@ -100,16 +110,16 @@ fun <T> ViewHolderCreator<T>.setTextSize(id: Int, sp: Int) = apply {
}

fun <T> ViewHolderCreator<T>.clicked(id: Int, listener: View.OnClickListener?) =
apply { findViewById<View>(id).setOnClickListener(listener) }
apply { findViewById<View>(id).setOnClickListener(listener) }

fun <T> ViewHolderCreator<T>.itemClicked(listener: View.OnClickListener?) =
apply { itemView?.setOnClickListener(listener) }
apply { viewHolder?.itemView?.setOnClickListener(listener) }

fun <T> ViewHolderCreator<T>.longClicked(id: Int, listener: OnLongClickListener?) =
apply { findViewById<View>(id).setOnLongClickListener(listener) }
apply { findViewById<View>(id).setOnLongClickListener(listener) }

fun <T> ViewHolderCreator<T>.isEnabled(id: Int, enable: Boolean = true) =
apply { findViewById<View>(id).isEnabled = enable }
apply { findViewById<View>(id).isEnabled = enable }

fun <T> ViewHolderCreator<T>.addView(id: Int, vararg views: View?) = apply {
val viewGroup: ViewGroup = findViewById(id)
Expand All @@ -119,10 +129,10 @@ fun <T> ViewHolderCreator<T>.addView(id: Int, vararg views: View?) = apply {
}

fun <T> ViewHolderCreator<T>.addView(id: Int, view: View?, params: ViewGroup.LayoutParams?) =
apply {
val viewGroup: ViewGroup = findViewById(id)
viewGroup.addView(view, params)
}
apply {
val viewGroup: ViewGroup = findViewById(id)
viewGroup.addView(view, params)
}

fun <T> ViewHolderCreator<T>.removeAllViews(id: Int) = apply {
val viewGroup: ViewGroup = findViewById(id)
Expand Down

0 comments on commit 9e28eb4

Please sign in to comment.