Gunakan AdapterDataObserver di RecyclerView kustom
Kotlin:
RecyclerViewEnum.kt
enum class RecyclerViewEnum {
LOADING,
NORMAL,
EMPTY_STATE
}
RecyclerViewEmptyLoadingSupport.kt
class RecyclerViewEmptyLoadingSupport : RecyclerView {
var stateView: RecyclerViewEnum? = RecyclerViewEnum.LOADING
set(value) {
field = value
setState()
}
var emptyStateView: View? = null
var loadingStateView: View? = null
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}
private val dataObserver = object : AdapterDataObserver() {
override fun onChanged() {
onChangeState()
}
override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
super.onItemRangeRemoved(positionStart, itemCount)
onChangeState()
}
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
super.onItemRangeInserted(positionStart, itemCount)
onChangeState()
}
}
override fun setAdapter(adapter: RecyclerView.Adapter<*>?) {
super.setAdapter(adapter)
adapter?.registerAdapterDataObserver(dataObserver)
dataObserver.onChanged()
}
fun onChangeState() {
if (adapter?.itemCount == 0) {
emptyStateView?.visibility = View.VISIBLE
loadingStateView?.visibility = View.GONE
this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
} else {
emptyStateView?.visibility = View.GONE
loadingStateView?.visibility = View.GONE
this@RecyclerViewEmptyLoadingSupport.visibility = View.VISIBLE
}
}
private fun setState() {
when (this.stateView) {
RecyclerViewEnum.LOADING -> {
loadingStateView?.visibility = View.VISIBLE
this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
emptyStateView?.visibility = View.GONE
}
RecyclerViewEnum.NORMAL -> {
loadingStateView?.visibility = View.GONE
this@RecyclerViewEmptyLoadingSupport.visibility = View.VISIBLE
emptyStateView?.visibility = View.GONE
}
RecyclerViewEnum.EMPTY_STATE -> {
loadingStateView?.visibility = View.GONE
this@RecyclerViewEmptyLoadingSupport.visibility = View.GONE
emptyStateView?.visibility = View.VISIBLE
}
}
}
}
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/emptyView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/emptyLabelTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="empty" />
</LinearLayout>
<LinearLayout
android:id="@+id/loadingView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:gravity="center"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:indeterminate="true"
android:theme="@style/progressBarBlue" />
</LinearLayout>
<com.peeyade.components.recyclerView.RecyclerViewEmptyLoadingSupport
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
dalam aktivitas gunakan cara ini:
recyclerView?.apply {
layoutManager = GridLayoutManager(context, 2)
emptyStateView = emptyView
loadingStateView = loadingView
adapter = adapterGrid
}
// you can set LoadingView or emptyView manual
recyclerView.stateView = RecyclerViewEnum.EMPTY_STATE
recyclerView.stateView = RecyclerViewEnum.LOADING