#android #android-recyclerview #android-mvvm #nestedrecyclerview
#android #android-recyclerview #android-mvvm #nestedrecyclerview
Вопрос:
Я работаю над приложением для Android, которое требует использования вложенного представления переработчика с MVVM, мой код выглядит следующим образом: адаптер, элемент макета, модель представления и фрагмент:
Адаптация родителей
abstract class ParentAdapterlt;Tgt;( private var items: Listlt;Tgt;, private var listener: BaseInteractionListener? ) : RecyclerView.Adapterlt;ParentAdapter.BaseViewHoldergt;() { abstract val layoutId: Int override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { return when (viewType) { VIEW_ITEM -gt; { ChildViewHolder( DataBindingUtil.inflate( LayoutInflater.from(parent.context), layoutId, parent, false ) ) } VIEW_PARENT -gt; { ParentViewHolder( DataBindingUtil.inflate( LayoutInflater.from(parent.context), layoutId, parent, false ) ) } else -gt; throw Exception("UNKNOWN VIEW TYPE") } } override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { when (holder) { is ChildViewHolder -gt; bindItem(holder, position) is ParentViewHolder -gt; bindNestedItems(holder, position) } } private fun bindItem(holder: ChildViewHolder, position: Int) { val currentItem = items[position] holder.binding.setVariable(BR.item, currentItem) holder.binding.setVariable(BR.listener, listener) } private fun bindNestedItems(holder: ParentViewHolder, position: Int) { val listItems = ((items[position] as HomeItemlt;*gt;).myItem) as Listlt;Tgt; holder.binding.setVariable( BR.childAdapter, ChildAdapter(listItems, listener as CharacterInteractionListener) ) } override fun getItemViewType(position: Int): Int { return when ((items[position] as HomeItemlt;*gt;).type) { HomeItemType.TYPE_CHILD -gt; VIEW_ITEM HomeItemType.TYPE_PARENT -gt; VIEW_PARENT } } fun setItems(newItems: Listlt;Tgt;) { val moviesDiffUtil = DiffUtil.calculateDiff(MarvelDiffUtils(items, newItems)) items = newItems moviesDiffUtil.dispatchUpdatesTo(this) } override fun getItemCount() = items.size abstract class BaseViewHolder(binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) class ChildViewHolder(val binding: ViewDataBinding) : BaseViewHolder(binding) class ParentViewHolder(val binding: ViewDataBinding) : BaseViewHolder(binding) companion object { private const val VIEW_ITEM = 1 private const val VIEW_PARENT = 2 } }
Базовый адаптер
abstract class BaseAdapterlt;Tgt;( private var items: Listlt;Tgt;, private var listener: BaseInteractionListener? ) : RecyclerView.Adapterlt;BaseAdapter.BaseViewHoldergt;() { abstract val layoutId: Int override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { return ItemViewHolder( DataBindingUtil.inflate( LayoutInflater.from(parent.context), layoutId, parent, false ) ) } override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { val currentItem = items[position] when (holder) { is ItemViewHolder -gt; { holder.binding.setVariable(BR.item, currentItem) holder.binding.setVariable(BR.listener, listener) } } } fun setItems(newItems: Listlt;Tgt;) { val moviesDiffUtil = DiffUtil.calculateDiff(MarvelDiffUtils(items, newItems)) items = newItems moviesDiffUtil.dispatchUpdatesTo(this) } fun getItems() = items override fun getItemCount() = items.size class ItemViewHolder(val binding: ViewDataBinding) : BaseViewHolder(binding) abstract class BaseViewHolder(binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) }
ViewModel
class HomeViewModel @Inject constructor( private val repository: MarvelRepository ) : BaseViewModel(), CharacterInteractionListener { var charecters: Flowlt;Resourceslt;Listlt;Charactergt;?gt;gt; = repository.getCharacters() var items: Listlt;Charactergt;? = mutableListOflt;Charactergt;() var itemsList = MutableLiveDatalt;MutableListlt;HomeItemlt;Anygt;gt;gt;() var tempItems = mutableListOflt;HomeItemlt;Anygt;gt;() init { charecters = repository.getCharacters() viewModelScope.launch { items = charecters.first { it is Resources.Success }.data items?.let { val tempHomeItem = HomeItem(it, HomeItemType.TYPE_PARENT) tempItems.add(tempHomeItem as HomeItemlt;Anygt;) itemsList.postValue(tempItems) } } } }
Repository
fun getCharacters(): Flowlt;Resourceslt;Listlt;Charactergt;?gt;gt; { return flow { emit(Loading) try { val characters = apiService.getCharacters().body()?.items?.results?.map { characterDto -gt; characterMapper.map(characterDto) } emit(Success(characters)) } catch (throwable: Throwable) { emit(Error(throwable)) } } }
parent_item layout
lt;?xml version="1.0" encoding="utf-8"?gt; lt;layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"gt; lt;datagt; lt;variable name="childAdapter" type="com.example.marvelapp.ui.base.BaseAdapter" /gt; lt;variable name="item" type="com.example.marvelapp.domain.HomeItem" /gt; lt;/datagt; lt;androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/app_color"gt; lt;androidx.recyclerview.widget.RecyclerView android:id="@ id/parentRecycler" android:layout_width="match_parent" android:layout_height="120dp" android:orientation="horizontal" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@ id/textView" android:adapter="@{childAdapter}" tools:listitem="@layout/item_character" /gt; lt;/androidx.constraintlayout.widget.ConstraintLayoutgt; lt;/layoutgt;
HomeItem
data class HomeItemlt;Tgt;( val myItem: Listlt;Tgt;, val type: HomeItemType, )
and in fragment
@AndroidEntryPoint class HomeFragment : BaseFragmentlt;FragmentHomeBindinggt;() { override val viewModel: HomeViewModel by viewModels() override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -gt; FragmentHomeBinding get() = FragmentHomeBinding::inflate override fun setup() { binding.recyclerHome.adapter = HomeAdapter(mutableListOf(), viewModel) } }
After all of above I get the following result as shown in image below where my recyclerview is not have data in child recyclerview what is the error in my code, or what can I do to enhance my code and get what I need?