【问题标题】:How do I refactor my RecyclerView code to work with a ViewModel and LiveData?如何重构我的 RecyclerView 代码以使用 ViewModel 和 LiveData?
【发布时间】:2021-08-08 20:45:57
【问题描述】:

我的 Android 应用中有一个 Fragment,它有一个 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 的所有功能都如我所愿,我现在要做的是在应用程序关闭之前使用ViewModelLiveData 将数据保存在RecyclerView 中,然后恢复当应用程序再次打开时,数据返回到RecyclerView。我怎么做?我在重构现有代码以使其正常工作时遇到了麻烦。我想用ViewModelLiveData 来做到这一点,因为我相信这是我想要实现的最佳实践。

【问题讨论】:

    标签: android kotlin android-recyclerview android-livedata android-viewmodel


    【解决方案1】:

    您通常在系统第一次调用活动对象的 onCreate() 方法时请求 ViewModel。在活动的整个生命周期中,系统可能会多次调用 onCreate(),例如当设备屏幕旋转时。从您第一次请求 ViewModel 到 Activity 完成并销毁,ViewModel 一直存在。

    当调用onDestory() 时,viewmodel 的实例也会得到onCleared(),因此如果要保存recyclerView 的数据和位置,则需要将数据存储在数据库中,并将适配器的位置(如果需要)存储在首选项或数据库中所以你可以在需要时提取。

    【讨论】:

      【解决方案2】:

      虽然ViewModelLiveData 是很棒的工具,但它们并不能解决您更永久地存储数据的问题。相反,您需要学习如何将数据保存到文件或数据库中。我建议您为此查看 Room API。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-10
        • 2019-02-04
        • 1970-01-01
        • 1970-01-01
        • 2018-12-23
        • 1970-01-01
        • 1970-01-01
        • 2018-11-29
        相关资源
        最近更新 更多