From 64e17732e81c6206e6e5c8d27a45aa1c94e90819 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 29 Sep 2020 10:58:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/base/adapter/CommonRecyclerAdapter.kt | 146 +++++++++--------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt b/app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt index 48e72de45..0ae540837 100644 --- a/app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt +++ b/app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt @@ -15,67 +15,67 @@ import java.util.* * * 通用的adapter 可添加header,footer,以及不同类型item */ -abstract class CommonRecyclerAdapter(protected val context: Context): +abstract class CommonRecyclerAdapter(protected val context: Context) : RecyclerView.Adapter() { - - constructor(context: Context, vararg delegates: ItemViewDelegate): this(context) { + + constructor(context: Context, vararg delegates: ItemViewDelegate) : this(context) { addItemViewDelegates(*delegates) } - + constructor( context: Context, vararg delegates: Pair> - ): this(context) { + ) : this(context) { addItemViewDelegates(*delegates) } - + private val inflater: LayoutInflater = LayoutInflater.from(context) - + private var headerItems: SparseArray? = null private var footerItems: SparseArray? = null - + private val itemDelegates: HashMap> = hashMapOf() private val items: MutableList = mutableListOf() - + private val lock = Object() - + private var itemClickListener: ((holder: ItemViewHolder, item: ITEM) -> Unit)? = null private var itemLongClickListener: ((holder: ItemViewHolder, item: ITEM) -> Boolean)? = null - + // 这个用Kotlin的setter就行了, 不需要手动开一个函数进行设置 var itemAnimation: ItemAnimation? = null - + fun setOnItemClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Unit) { itemClickListener = listener } - + fun setOnItemLongClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Boolean) { itemLongClickListener = listener } - + fun bindToRecyclerView(recyclerView: RecyclerView) { recyclerView.adapter = this } - - fun > addItemViewDelegate(viewType: Int, delegate: DELEGATE) { + + fun > addItemViewDelegate(viewType: Int, delegate: DELEGATE) { itemDelegates[viewType] = delegate } - - fun > addItemViewDelegate(delegate: DELEGATE) { + + fun > addItemViewDelegate(delegate: DELEGATE) { itemDelegates[itemDelegates.size] = delegate } - - fun > addItemViewDelegates(vararg delegates: DELEGATE) { + + fun > addItemViewDelegates(vararg delegates: DELEGATE) { delegates.forEach { addItemViewDelegate(it) } } - + fun addItemViewDelegates(vararg delegates: Pair>) = delegates.forEach { addItemViewDelegate(it.first, it.second) } - + fun addHeaderView(header: View) { synchronized(lock) { if (headerItems == null) { @@ -88,7 +88,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun addFooterView(footer: View) = synchronized(lock) { if (footerItems == null) { @@ -100,8 +100,8 @@ abstract class CommonRecyclerAdapter(protected val context: Context): notifyItemInserted(index) } } - - + + fun removeHeaderView(header: View) = synchronized(lock) { headerItems?.let { @@ -112,7 +112,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun removeFooterView(footer: View) = synchronized(lock) { footerItems?.let { @@ -123,7 +123,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun setItems(items: List?) { synchronized(lock) { if (this.items.isNotEmpty()) { @@ -135,7 +135,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): notifyDataSetChanged() } } - + fun setItems(items: List?, diffResult: DiffUtil.DiffResult) { synchronized(lock) { if (this.items.isNotEmpty()) { @@ -147,7 +147,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): diffResult.dispatchUpdatesTo(this) } } - + fun setItem(position: Int, item: ITEM) { synchronized(lock) { val oldSize = getActualItemCount() @@ -157,7 +157,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun addItem(item: ITEM) { synchronized(lock) { val oldSize = getActualItemCount() @@ -166,7 +166,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun addItems(position: Int, newItems: List) { synchronized(lock) { if (this.items.addAll(position, newItems)) { @@ -174,7 +174,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun addItems(newItems: List) { synchronized(lock) { val oldSize = getActualItemCount() @@ -187,7 +187,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun removeItem(position: Int) { synchronized(lock) { if (this.items.removeAt(position) != null) { @@ -195,7 +195,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun removeItem(item: ITEM) { synchronized(lock) { if (this.items.remove(item)) { @@ -203,7 +203,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun removeItems(items: List) { synchronized(lock) { if (this.items.removeAll(items)) { @@ -211,7 +211,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun swapItem(oldPosition: Int, newPosition: Int) { synchronized(lock) { val size = getActualItemCount() @@ -224,7 +224,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + fun updateItem(item: ITEM) = synchronized(lock) { val index = this.items.indexOf(item) @@ -233,7 +233,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): notifyItemChanged(index) } } - + fun updateItem(position: Int, payload: Any) = synchronized(lock) { val size = getActualItemCount() @@ -241,7 +241,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): notifyItemChanged(position + getHeaderCount(), payload) } } - + fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) = synchronized(lock) { val size = getActualItemCount() @@ -253,43 +253,43 @@ abstract class CommonRecyclerAdapter(protected val context: Context): ) } } - + fun clearItems() = synchronized(lock) { this.items.clear() notifyDataSetChanged() } - + fun isEmpty() = items.isEmpty() - + fun isNotEmpty() = items.isNotEmpty() - + /** * 除去header和footer */ fun getActualItemCount() = items.size - - + + fun getHeaderCount() = headerItems?.size() ?: 0 - - + + fun getFooterCount() = footerItems?.size() ?: 0 - + fun getItem(position: Int): ITEM? = items.getOrNull(position) - + fun getItemByLayoutPosition(position: Int) = items.getOrNull(position - getHeaderCount()) - + fun getItems(): List = items - + protected open fun getItemViewType(item: ITEM, position: Int) = 0 - + /** * grid 模式下使用 */ protected open fun getSpanSize(item: ITEM, viewType: Int, position: Int) = 1 - + final override fun getItemCount() = getActualItemCount() + getHeaderCount() + getFooterCount() - + final override fun getItemViewType(position: Int) = when { isHeader(position) -> TYPE_HEADER_VIEW + position isFooter(position) -> TYPE_FOOTER_VIEW + position - getActualItemCount() - getHeaderCount() @@ -297,16 +297,16 @@ abstract class CommonRecyclerAdapter(protected val context: Context): getItemViewType(it, getActualPosition(position)) } ?: 0 } - + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when { viewType < TYPE_HEADER_VIEW + getHeaderCount() -> { ItemViewHolder(headerItems!!.get(viewType)) } - + viewType >= TYPE_FOOTER_VIEW -> { ItemViewHolder(footerItems!!.get(viewType)) } - + else -> { val holder = ItemViewHolder( inflater.inflate( @@ -315,10 +315,10 @@ abstract class CommonRecyclerAdapter(protected val context: Context): false ) ) - + itemDelegates.getValue(viewType) .registerListener(holder) - + if (itemClickListener != null) { holder.itemView.setOnClickListener { getItem(holder.layoutPosition)?.let { @@ -326,7 +326,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + if (itemLongClickListener != null) { holder.itemView.setOnLongClickListener { getItem(holder.layoutPosition)?.let { @@ -334,13 +334,13 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } ?: true } } - + holder } } - + final override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {} - + final override fun onBindViewHolder( holder: ItemViewHolder, position: Int, @@ -353,19 +353,19 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + override fun onViewAttachedToWindow(holder: ItemViewHolder) { super.onViewAttachedToWindow(holder) if (!isHeader(holder.layoutPosition) && !isFooter(holder.layoutPosition)) { addAnimation(holder) } } - + override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { super.onAttachedToRecyclerView(recyclerView) val manager = recyclerView.layoutManager if (manager is GridLayoutManager) { - manager.spanSizeLookup = object: GridLayoutManager.SpanSizeLookup() { + manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { return getItem(position)?.let { if (isHeader(position) || isFooter(position)) manager.spanCount else getSpanSize( @@ -376,13 +376,13 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + private fun isHeader(position: Int) = position < getHeaderCount() - + private fun isFooter(position: Int) = position >= getActualItemCount() + getHeaderCount() - + private fun getActualPosition(position: Int) = position - getHeaderCount() - + private fun addAnimation(holder: ItemViewHolder) { itemAnimation?.let { if (it.itemAnimEnabled) { @@ -393,7 +393,7 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + protected open fun startAnimation(holder: ItemViewHolder, item: ItemAnimation) { item.itemAnimation?.let { for (anim in it.getAnimators(holder.itemView)) { @@ -402,12 +402,12 @@ abstract class CommonRecyclerAdapter(protected val context: Context): } } } - + companion object { private const val TYPE_HEADER_VIEW = Int.MIN_VALUE private const val TYPE_FOOTER_VIEW = Int.MAX_VALUE - 999 } - + }