Last active
November 14, 2018 02:21
-
-
Save hwd6190128/ca637850102f3e6c672d7b7dcd62da63 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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