|  |  |  | @ -10,73 +10,72 @@ import androidx.recyclerview.widget.GridLayoutManager | 
			
		
	
		
			
				
					|  |  |  |  | import androidx.recyclerview.widget.RecyclerView | 
			
		
	
		
			
				
					|  |  |  |  | import java.util.* | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /** | 
			
		
	
		
			
				
					|  |  |  |  |  * Created by Invincible on 2017/11/24. | 
			
		
	
		
			
				
					|  |  |  |  |  * | 
			
		
	
		
			
				
					|  |  |  |  |  * 通用的adapter 可添加header,footer,以及不同类型item | 
			
		
	
		
			
				
					|  |  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  |  | abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  | abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context): | 
			
		
	
		
			
				
					|  |  |  |  |     RecyclerView.Adapter<ItemViewHolder>() { | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     constructor(context: Context, vararg delegates: ItemViewDelegate<ITEM>) : this(context) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     constructor(context: Context, vararg delegates: ItemViewDelegate<ITEM>): this(context) { | 
			
		
	
		
			
				
					|  |  |  |  |         addItemViewDelegates(*delegates) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     constructor( | 
			
		
	
		
			
				
					|  |  |  |  |         context: Context, | 
			
		
	
		
			
				
					|  |  |  |  |         vararg delegates: Pair<Int, ItemViewDelegate<ITEM>> | 
			
		
	
		
			
				
					|  |  |  |  |     ) : this(context) { | 
			
		
	
		
			
				
					|  |  |  |  |     ): this(context) { | 
			
		
	
		
			
				
					|  |  |  |  |         addItemViewDelegates(*delegates) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     private val inflater: LayoutInflater = LayoutInflater.from(context) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     private var headerItems: SparseArray<View>? = null | 
			
		
	
		
			
				
					|  |  |  |  |     private var footerItems: SparseArray<View>? = null | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     private val itemDelegates: HashMap<Int, ItemViewDelegate<ITEM>> = hashMapOf() | 
			
		
	
		
			
				
					|  |  |  |  |     private val items: MutableList<ITEM> = mutableListOf() | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     private val lock = Object() | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     private var itemClickListener: ((holder: ItemViewHolder, item: ITEM) -> Unit)? = null | 
			
		
	
		
			
				
					|  |  |  |  |     private var itemLongClickListener: ((holder: ItemViewHolder, item: ITEM) -> Boolean)? = null | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private var itemAnimation: ItemAnimation? = 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 <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegate(viewType: Int, delegate: DELEGATE) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun <DELEGATE: ItemViewDelegate<ITEM>> addItemViewDelegate(viewType: Int, delegate: DELEGATE) { | 
			
		
	
		
			
				
					|  |  |  |  |         itemDelegates[viewType] = delegate | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegate(delegate: DELEGATE) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun <DELEGATE: ItemViewDelegate<ITEM>> addItemViewDelegate(delegate: DELEGATE) { | 
			
		
	
		
			
				
					|  |  |  |  |         itemDelegates[itemDelegates.size] = delegate | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegates(vararg delegates: DELEGATE) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun <DELEGATE: ItemViewDelegate<ITEM>> addItemViewDelegates(vararg delegates: DELEGATE) { | 
			
		
	
		
			
				
					|  |  |  |  |         delegates.forEach { | 
			
		
	
		
			
				
					|  |  |  |  |             addItemViewDelegate(it) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun addItemViewDelegates(vararg delegates: Pair<Int, ItemViewDelegate<ITEM>>) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun addItemViewDelegates(vararg delegates: Pair<Int, ItemViewDelegate<ITEM>>) = | 
			
		
	
		
			
				
					|  |  |  |  |         delegates.forEach { | 
			
		
	
		
			
				
					|  |  |  |  |             addItemViewDelegate(it.first, it.second) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun addHeaderView(header: View) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (headerItems == null) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -89,8 +88,8 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun addFooterView(footer: View) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun addFooterView(footer: View) = | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (footerItems == null) { | 
			
		
	
		
			
				
					|  |  |  |  |                 footerItems = SparseArray() | 
			
		
	
	
		
			
				
					|  |  |  | @ -101,9 +100,9 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |                 notifyItemInserted(index) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun removeHeaderView(header: View) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun removeHeaderView(header: View) = | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             headerItems?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                 val index = it.indexOfValue(header) | 
			
		
	
	
		
			
				
					|  |  |  | @ -113,9 +112,8 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun removeFooterView(footer: View) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun removeFooterView(footer: View) = | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             footerItems?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                 val index = it.indexOfValue(footer) | 
			
		
	
	
		
			
				
					|  |  |  | @ -125,8 +123,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun setItems(items: List<ITEM>?) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (this.items.isNotEmpty()) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -138,7 +135,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             notifyDataSetChanged() | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun setItems(items: List<ITEM>?, diffResult: DiffUtil.DiffResult) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (this.items.isNotEmpty()) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -150,7 +147,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             diffResult.dispatchUpdatesTo(this) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun setItem(position: Int, item: ITEM) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             val oldSize = getActualItemCount() | 
			
		
	
	
		
			
				
					|  |  |  | @ -160,7 +157,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun addItem(item: ITEM) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             val oldSize = getActualItemCount() | 
			
		
	
	
		
			
				
					|  |  |  | @ -169,7 +166,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun addItems(position: Int, newItems: List<ITEM>) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (this.items.addAll(position, newItems)) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -177,7 +174,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun addItems(newItems: List<ITEM>) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             val oldSize = getActualItemCount() | 
			
		
	
	
		
			
				
					|  |  |  | @ -190,7 +187,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun removeItem(position: Int) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (this.items.removeAt(position) != null) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -198,7 +195,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun removeItem(item: ITEM) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (this.items.remove(item)) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -206,7 +203,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun removeItems(items: List<ITEM>) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             if (this.items.removeAll(items)) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -214,7 +211,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun swapItem(oldPosition: Int, newPosition: Int) { | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             val size = getActualItemCount() | 
			
		
	
	
		
			
				
					|  |  |  | @ -227,8 +224,8 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun updateItem(item: ITEM) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun updateItem(item: ITEM) = | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             val index = this.items.indexOf(item) | 
			
		
	
		
			
				
					|  |  |  |  |             if (index >= 0) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -236,18 +233,16 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |                 notifyItemChanged(index) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun updateItem(position: Int, payload: Any) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun updateItem(position: Int, payload: Any) = | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             val size = getActualItemCount() | 
			
		
	
		
			
				
					|  |  |  |  |             if (position in 0 until size) { | 
			
		
	
		
			
				
					|  |  |  |  |                 notifyItemChanged(position + getHeaderCount(), payload) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) = | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             val size = getActualItemCount() | 
			
		
	
		
			
				
					|  |  |  |  |             if (fromPosition in 0 until size && toPosition in 0 until size) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -258,119 +253,94 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |                 ) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun clearItems() { | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun clearItems() = | 
			
		
	
		
			
				
					|  |  |  |  |         synchronized(lock) { | 
			
		
	
		
			
				
					|  |  |  |  |             this.items.clear() | 
			
		
	
		
			
				
					|  |  |  |  |             notifyDataSetChanged() | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun isEmpty(): Boolean { | 
			
		
	
		
			
				
					|  |  |  |  |         return items.isEmpty() | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun isNotEmpty(): Boolean { | 
			
		
	
		
			
				
					|  |  |  |  |         return items.isNotEmpty() | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun isEmpty() = items.isEmpty() | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun isNotEmpty() = items.isNotEmpty() | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     /** | 
			
		
	
		
			
				
					|  |  |  |  |      * 除去header和footer | 
			
		
	
		
			
				
					|  |  |  |  |      */ | 
			
		
	
		
			
				
					|  |  |  |  |     fun getActualItemCount(): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return items.size | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun getHeaderCount(): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return headerItems?.size() ?: 0 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun getFooterCount(): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return footerItems?.size() ?: 0 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     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): ITEM? { | 
			
		
	
		
			
				
					|  |  |  |  |         val pos = position - getHeaderCount() | 
			
		
	
		
			
				
					|  |  |  |  |         return items.getOrNull(pos) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun getItemByLayoutPosition(position: Int) = items.getOrNull(position - getHeaderCount()) | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     fun getItems(): List<ITEM> = items | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     protected open fun getItemViewType(item: ITEM, position: Int): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return 0 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     protected open fun getItemViewType(item: ITEM, position: Int) = 0 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     /** | 
			
		
	
		
			
				
					|  |  |  |  |      * grid 模式下使用 | 
			
		
	
		
			
				
					|  |  |  |  |      */ | 
			
		
	
		
			
				
					|  |  |  |  |     protected open fun getSpanSize(item: ITEM, viewType: Int, position: Int): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return 1 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     final override fun getItemCount(): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return getActualItemCount() + getHeaderCount() + getFooterCount() | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     final override fun getItemViewType(position: Int): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return when { | 
			
		
	
		
			
				
					|  |  |  |  |             isHeader(position) -> TYPE_HEADER_VIEW + position | 
			
		
	
		
			
				
					|  |  |  |  |             isFooter(position) -> TYPE_FOOTER_VIEW + position - getActualItemCount() - getHeaderCount() | 
			
		
	
		
			
				
					|  |  |  |  |             else -> getItem(getActualPosition(position))?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                 getItemViewType(it, getActualPosition(position)) | 
			
		
	
		
			
				
					|  |  |  |  |             } ?: 0 | 
			
		
	
		
			
				
					|  |  |  |  |     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() | 
			
		
	
		
			
				
					|  |  |  |  |         else -> getItem(getActualPosition(position))?.let { | 
			
		
	
		
			
				
					|  |  |  |  |             getItemViewType(it, getActualPosition(position)) | 
			
		
	
		
			
				
					|  |  |  |  |         } ?: 0 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when { | 
			
		
	
		
			
				
					|  |  |  |  |         viewType < TYPE_HEADER_VIEW + getHeaderCount() -> { | 
			
		
	
		
			
				
					|  |  |  |  |             ItemViewHolder(headerItems!!.get(viewType)) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { | 
			
		
	
		
			
				
					|  |  |  |  |         return when { | 
			
		
	
		
			
				
					|  |  |  |  |             viewType < TYPE_HEADER_VIEW + getHeaderCount() -> { | 
			
		
	
		
			
				
					|  |  |  |  |                 ItemViewHolder(headerItems!!.get(viewType)) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             viewType >= TYPE_FOOTER_VIEW -> { | 
			
		
	
		
			
				
					|  |  |  |  |                 ItemViewHolder(footerItems!!.get(viewType)) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             else -> { | 
			
		
	
		
			
				
					|  |  |  |  |                 val holder = ItemViewHolder( | 
			
		
	
		
			
				
					|  |  |  |  |                     inflater.inflate( | 
			
		
	
		
			
				
					|  |  |  |  |                         itemDelegates.getValue(viewType).layoutId, | 
			
		
	
		
			
				
					|  |  |  |  |                         parent, | 
			
		
	
		
			
				
					|  |  |  |  |                         false | 
			
		
	
		
			
				
					|  |  |  |  |                     ) | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  |         viewType >= TYPE_FOOTER_VIEW -> { | 
			
		
	
		
			
				
					|  |  |  |  |             ItemViewHolder(footerItems!!.get(viewType)) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |  |         else -> { | 
			
		
	
		
			
				
					|  |  |  |  |             val holder = ItemViewHolder( | 
			
		
	
		
			
				
					|  |  |  |  |                 inflater.inflate( | 
			
		
	
		
			
				
					|  |  |  |  |                     itemDelegates.getValue(viewType).layoutId, | 
			
		
	
		
			
				
					|  |  |  |  |                     parent, | 
			
		
	
		
			
				
					|  |  |  |  |                     false | 
			
		
	
		
			
				
					|  |  |  |  |                 ) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 itemDelegates.getValue(viewType) | 
			
		
	
		
			
				
					|  |  |  |  |                     .registerListener(holder) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (itemClickListener != null) { | 
			
		
	
		
			
				
					|  |  |  |  |                     holder.itemView.setOnClickListener { | 
			
		
	
		
			
				
					|  |  |  |  |                         getItem(holder.layoutPosition)?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                             itemClickListener?.invoke(holder, it) | 
			
		
	
		
			
				
					|  |  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |  |             ) | 
			
		
	
		
			
				
					|  |  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |  |             itemDelegates.getValue(viewType) | 
			
		
	
		
			
				
					|  |  |  |  |                 .registerListener(holder) | 
			
		
	
		
			
				
					|  |  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |  |             if (itemClickListener != null) { | 
			
		
	
		
			
				
					|  |  |  |  |                 holder.itemView.setOnClickListener { | 
			
		
	
		
			
				
					|  |  |  |  |                     getItem(holder.layoutPosition)?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                         itemClickListener?.invoke(holder, it) | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 if (itemLongClickListener != null) { | 
			
		
	
		
			
				
					|  |  |  |  |                     holder.itemView.setOnLongClickListener { | 
			
		
	
		
			
				
					|  |  |  |  |                         getItem(holder.layoutPosition)?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                             itemLongClickListener?.invoke(holder, it) ?: true | 
			
		
	
		
			
				
					|  |  |  |  |                         } ?: true | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |  |             if (itemLongClickListener != null) { | 
			
		
	
		
			
				
					|  |  |  |  |                 holder.itemView.setOnLongClickListener { | 
			
		
	
		
			
				
					|  |  |  |  |                     getItem(holder.layoutPosition)?.let { | 
			
		
	
		
			
				
					|  |  |  |  |                         itemLongClickListener?.invoke(holder, it) ?: true | 
			
		
	
		
			
				
					|  |  |  |  |                     } ?: true | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 holder | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |  |             holder | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     final override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     final override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {} | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     final override fun onBindViewHolder( | 
			
		
	
		
			
				
					|  |  |  |  |         holder: ItemViewHolder, | 
			
		
	
		
			
				
					|  |  |  |  |         position: Int, | 
			
		
	
	
		
			
				
					|  |  |  | @ -383,19 +353,19 @@ abstract class CommonRecyclerAdapter<ITEM>(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( | 
			
		
	
	
		
			
				
					|  |  |  | @ -406,23 +376,13 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     fun setItemAnimation(item: ItemAnimation) { | 
			
		
	
		
			
				
					|  |  |  |  |         itemAnimation = item | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private fun isHeader(position: Int): Boolean { | 
			
		
	
		
			
				
					|  |  |  |  |         return position < getHeaderCount() | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private fun isFooter(position: Int): Boolean { | 
			
		
	
		
			
				
					|  |  |  |  |         return position >= getActualItemCount() + getHeaderCount() | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     private fun getActualPosition(position: Int): Int { | 
			
		
	
		
			
				
					|  |  |  |  |         return position - getHeaderCount() | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     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) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -433,8 +393,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  |     protected open fun startAnimation(holder: ItemViewHolder, item: ItemAnimation) { | 
			
		
	
		
			
				
					|  |  |  |  |         item.itemAnimation?.let { | 
			
		
	
		
			
				
					|  |  |  |  |             for (anim in it.getAnimators(holder.itemView)) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -443,12 +402,12 @@ abstract class CommonRecyclerAdapter<ITEM>(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 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |