Created
July 7, 2021 05:54
-
-
Save hi-manshu/75c5bfdfd2d3a921fe63877dd032da26 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
abstract class BaseAdapter<T : Any, VH : BaseItemViewHolder<T, out BaseItemViewModel<T>>>( | |
parentLifecycle: Lifecycle, | |
private val dataList: ArrayList<T> | |
) : RecyclerView.Adapter<VH>() { | |
private var recyclerView: RecyclerView? = null | |
init { | |
parentLifecycle.addObserver(object : LifecycleObserver { | |
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) | |
fun onParentDestroy() { | |
recyclerView?.run { | |
for (i in 0 until childCount) { | |
getChildAt(i)?.let { | |
(getChildViewHolder(it) as BaseItemViewHolder<*, *>) | |
.run { | |
onDestroy() | |
viewModel.onManualCleared() | |
} | |
} | |
} | |
} | |
} | |
@OnLifecycleEvent(Lifecycle.Event.ON_STOP) | |
fun onParentStop() { | |
recyclerView?.run { | |
for (i in 0 until childCount) { | |
getChildAt(i)?.let { | |
(getChildViewHolder(it) as BaseItemViewHolder<*, *>).onStop() | |
} | |
} | |
} | |
} | |
@OnLifecycleEvent(Lifecycle.Event.ON_START) | |
fun onParentStart() { | |
recyclerView?.run { | |
if (layoutManager is LinearLayoutManager) { | |
val first = (layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() | |
val last = (layoutManager as LinearLayoutManager).findLastVisibleItemPosition() | |
if (first in 0..last) | |
for (i in first..last) { | |
findViewHolderForAdapterPosition(i)?.let { | |
(it as BaseItemViewHolder<*, *>).onStart() | |
} | |
} | |
} | |
} | |
} | |
}) | |
} | |
override fun onViewAttachedToWindow(holder: VH) { | |
super.onViewAttachedToWindow(holder) | |
holder.onStart() | |
} | |
override fun onViewDetachedFromWindow(holder: VH) { | |
super.onViewDetachedFromWindow(holder) | |
holder.onStop() | |
} | |
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) { | |
super.onAttachedToRecyclerView(recyclerView) | |
this.recyclerView = recyclerView | |
} | |
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) { | |
super.onDetachedFromRecyclerView(recyclerView) | |
this.recyclerView = null | |
} | |
override fun getItemCount(): Int = dataList.size | |
override fun onBindViewHolder(holder: VH, position: Int) { | |
holder.bind(dataList[position]) | |
} | |
fun appendData(dataList: List<T>) { | |
val oldCount = itemCount | |
this.dataList.addAll(dataList) | |
val currentCount = itemCount | |
if (oldCount == 0 && currentCount > 0) | |
notifyDataSetChanged() | |
else if (oldCount > 0 && currentCount > oldCount) | |
notifyItemRangeChanged(oldCount - 1, currentCount - oldCount) | |
} | |
fun updateList(list: List<T>) { | |
dataList.clear() | |
dataList.addAll(list) | |
notifyDataSetChanged() | |
} | |
} |
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
abstract class BaseItemViewHolder<T : Any, VM : BaseItemViewModel<T>>( | |
@LayoutRes layoutId: Int, parent: ViewGroup | |
) : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(layoutId, parent, false)), | |
LifecycleOwner { | |
init { | |
onCreate() | |
} | |
@Inject | |
lateinit var viewModel: VM | |
@Inject | |
lateinit var lifecycleRegistry: LifecycleRegistry | |
override fun getLifecycle(): Lifecycle = lifecycleRegistry | |
open fun bind(data: T) { | |
viewModel.updateData(data) | |
} | |
protected fun onCreate() { | |
injectDependencies(buildViewHolderComponent()) | |
lifecycleRegistry.markState(Lifecycle.State.INITIALIZED) | |
lifecycleRegistry.markState(Lifecycle.State.CREATED) | |
setupObservers() | |
setupView(itemView) | |
} | |
fun onStart() { | |
lifecycleRegistry.markState(Lifecycle.State.STARTED) | |
lifecycleRegistry.markState(Lifecycle.State.RESUMED) | |
} | |
fun onStop() { | |
lifecycleRegistry.markState(Lifecycle.State.STARTED) | |
lifecycleRegistry.markState(Lifecycle.State.CREATED) | |
} | |
fun onDestroy() { | |
lifecycleRegistry.markState(Lifecycle.State.DESTROYED) | |
} | |
private fun buildViewHolderComponent() = | |
DaggerViewHolderComponent | |
.builder() | |
.applicationComponent((itemView.context.applicationContext as Application).applicationComponent) | |
.viewHolderModule(ViewHolderModule(this)) | |
.build() | |
fun showMessage(message: String) = Toaster.show(itemView.context, message) | |
fun showMessage(@StringRes resId: Int) = showMessage(itemView.context.getString(resId)) | |
protected open fun setupObservers() { | |
viewModel.messageString.observe(this, Observer { | |
it.data?.run { showMessage(this) } | |
}) | |
viewModel.messageStringId.observe(this, Observer { | |
it.data?.run { showMessage(this) } | |
}) | |
} | |
protected abstract fun injectDependencies(viewHolderComponent: ViewHolderComponent) | |
abstract fun setupView(view: View) | |
} |
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
abstract class BaseItemViewModel<T : Any>( | |
schedulerProvider: SchedulerProvider, | |
compositeDisposable: CompositeDisposable, | |
networkHelper: NetworkHelper | |
) : BaseViewModel(schedulerProvider, compositeDisposable, networkHelper) { | |
val data: MutableLiveData<T> = MutableLiveData() | |
fun onManualCleared() = onCleared() | |
fun updateData(data: T) { | |
this.data.postValue(data) | |
} | |
} |
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
@Module | |
class ViewHolderModule(private val viewHolder: BaseItemViewHolder<*, *>) { | |
@Provides | |
@ViewModelScope | |
fun provideLifecycleRegistry(): LifecycleRegistry = LifecycleRegistry(viewHolder) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment