Как реорганизовать мой код RecyclerView для работы с ViewModel и LiveData?

avatar
Tom Darious
8 августа 2021 в 20:45
75
2
0

У меня есть Fragment в моем приложении для Android с RecyclerView, и я хочу сохранить данные RecyclerView, которые у него были до закрытия приложения, и восстановить данные, сохраненные на RecyclerView, когда приложение снова открывается?

Это мой класс RecyclerView.Adapter:

class RecyclerAdapter(private val recyclerList: List<RecyclerCard>  private val listener: OnRecyclerClickListener) : RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder>() {
    inner class RecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
        val recyclerImageView: AppCompatImageView =
            itemView.findViewById(R.id.recycler_picture_image_view)
        val recyclerTitleView: AppCompatTextView = itemView.findViewById(R.id.recycler_title_text_view)
        val recyclerScoreView: AppCompatTextView =
            itemView.findViewById(R.id.recycler_score_text_view)

        init {
            itemView.setOnClickListener(this)
        }

        override fun onClick(v: View?) {
            val position = adapterPosition
            if (position != RecyclerView.NO_POSITION) {
                listener.onRecyclerClick(position)
            }
        }
    }

    interface OnRecyclerClickListener {
        fun onRecyclerClick(position: Int)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
        val itemView =
            LayoutInflater.from(parent.context).inflate(R.layout.recycler_card, parent, false)
        return RecyclerViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
        val currentRecycler = recyclerList[position]
        Glide.with(holder.itemView.context)
            .load(currentRecycler.recyclerImage)
            .apply(RequestOptions.skipMemoryCacheOf(true))
            .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE))
            .into(holder.recyclerImageView)
        holder.recyclerTitleView.text = currentRecycler.recyclerTitle
        holder.recyclerScoreView.text = currentRecycler.recyclerScore
    }

    override fun getItemCount(): Int = recyclerList.size
}

А это мой Fragment, который заполняет RecyclerView. Обратите внимание, что я удалил большую часть кода, поскольку он не имел отношения к моему вопросу, но это основной код для работы:

class Main : Fragment(), RecyclerAdapter.OnRecyclerClickListener {
    private lateinit var mainRecyclerView: RecyclerView
    private var mainList = ArrayList<RecyclerCard>()
    private var adapter = RecyclerAdapter(mainList, this)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        mainRecyclerView = rootView.findViewById(R.id.main_recycler_view)

        GlobalScope.launch(Dispatchers.IO) {
            val item = RecyclerCard(
                string1,
                string2,
                score,
                string3
            )
            mainList += item
            this@Main.requireActivity()
                .runOnUiThread(kotlinx.coroutines.Runnable {
                    run {
                        mainRecyclerView.adapter = adapter
                        mainRecyclerView.layoutManager =
                            LinearLayoutManager(this@Main.requireContext())
                        mainRecyclerView.setHasFixedSize(true)
                    }
                })
        }
    }


    override fun onRecyclerClick(position: Int) {
        // Complete an action when the user clicks on a row item
    }
}

Итак, с RecyclerView все работает так, как я хочу, теперь я хочу использовать ViewModel и LiveData для сохранения данных в RecyclerView до закрытия приложения, а затем восстановить данные обратно в RecyclerView, когда приложение снова откроется. Как я могу это сделать? У меня возникли проблемы с рефакторингом моего существующего кода, чтобы заставить это работать. Я хочу сделать это с помощью ViewModel и LiveData, так как я считаю, что это лучшая практика для того, чего я пытаюсь достичь.

Источник

Ответы (2)

avatar
Code-Apprentice
9 августа 2021 в 04:54
0

Несмотря на то, что ViewModel и LiveData — отличные инструменты, они не решают проблему постоянного хранения данных. Вместо этого вам нужно научиться сохранять данные в файл или базу данных. Я предлагаю вам посмотреть на Room API для этого.

avatar
Anshul
9 августа 2021 в 04:51
0

Обычно вы запрашиваете ViewModel в первый раз, когда система вызывает метод onCreate() объекта действия. Система может вызывать onCreate() несколько раз в течение жизни действия, например, когда экран устройства поворачивается. ViewModel существует с момента первого запроса ViewModel до завершения и уничтожения действия.

Экземпляр модели представления также получает onCleared() при вызове onDestory(), поэтому, если вы хотите сохранить данные и положение recyclerView, вам необходимо сохранить данные в базе данных и положение адаптера (при необходимости) в настройках или базе данных. так что вы можете извлечь, когда это необходимо.