Android MVVM: Вложенный просмотр вторсырья

#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?