Skip to content

Instantly share code, notes, and snippets.

@hwd6190128
Last active November 14, 2018 02:21
Show Gist options
  • Save hwd6190128/ca637850102f3e6c672d7b7dcd62da63 to your computer and use it in GitHub Desktop.
Save hwd6190128/ca637850102f3e6c672d7b7dcd62da63 to your computer and use it in GitHub Desktop.
/**
* Created by Howard Chang on 2018/11/13.
*
* @param recyclerView 被綁定的RecyclerView
* @param mIsLoadMore 是否要演出刷新動畫
* @param mIsAnim 是否有LoadMore功能,有得話在刷新之後復位position
*/
abstract class BaseDiffAdapter<T, V : RecyclerView.ViewHolder>(
protected val recyclerView: RecyclerView? = null
, protected val mIsLoadMore: Boolean = false
, protected val mIsAnim: Boolean = true) : RecyclerView.Adapter<V>() {
init {
if (recyclerView != null) {
if (!mIsLoadMore && mIsAnim ||
!mIsAnim) {
recyclerView.itemAnimator = null
}
}
}
protected abstract fun areItemsTheSame(oldItem: T, newItem: T): Boolean
protected abstract fun areContentsTheSame(oldItem: T, newItem: T): Boolean
protected abstract fun getChangePayload(oldItem: T, newItem: T): Any?
fun notifyDiff(temp: MutableList<T>, new: List<T>) {
if (!mIsAnim && recyclerView != null) {
recyclerView.itemAnimator = null
}
val diffDisposable = Single.just(DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return temp.size
}
override fun getNewListSize(): Int {
return new.size
}
// return兩個對像是否是相同item
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return [email protected](temp[oldItemPosition]!!, new[newItemPosition]!!)
}
/**
* return item是否同內容
*
* 當areItemsTheSame為true時才觸發
* 當areItemsTheSame返回為false時,即不管areContentsTheSame是否為true皆進行刷新
*/
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return [email protected](temp[oldItemPosition]!!, new[newItemPosition]!!)
}
/**
* areItemsTheSame() 返回 true 而 areContentsTheSame() 返回 false 時觸發
*
* 如果使用 RecyclerView 配合 DiffUtils 且調用此方法,RecyclerView 會用透過這些內容自動去執行正確的動畫
 * {@link android.support.v7.widget.RecyclerView.ItemAnimator ItemAnimator}
*
* 預設return null
* @param oldItemPosition
* @param newItemPosition
* @return
*/
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
return [email protected](temp[oldItemPosition]!!, new[newItemPosition]!!)
}
}))
// 如果是loadMore,記住當前滑動位置
var mRecyclerViewState: Parcelable? = null
if (isSaveInstanceState()) {
mRecyclerViewState = recyclerView!!.layoutManager.onSaveInstanceState()
}
CompositeDisposable()
.add(diffDisposable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { result ->
result.dispatchUpdatesTo(this)
// 非loadMore,先清空原有temp
if (!mIsLoadMore) {
temp.clear()
}
temp.addAll(new)
// 如果是loadMore,回復原來的滑動位置
if (isSaveInstanceState() && mRecyclerViewState != null) {
recyclerView!!.layoutManager.onRestoreInstanceState(mRecyclerViewState)
}
})
}
private fun isSaveInstanceState(): Boolean {
return recyclerView != null && mIsLoadMore
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment