如何在片段中只调用一次函数 android kotlin

How to only call a function once in a fragment android kotlin

当我的应用程序启动时,我调用一个使用 retrofit/gson 的函数并调用一个 rest API,然后从那里将数据发送到适配器并放置在回收器视图中。我遇到的问题是,当我导航到另一个片段并再次返回时,再次调用该函数,但旧数据保留在回收器视图中,导致当我只在回收器视图中放置相同数据的多个副本希望它调用一次或至少在回收站视图中只有一组数据

我试过从 activity 而不是片段调用函数,将函数放入 onCreate 方法和数学 if-else 表达式都没有产生预期的效果。

我的代码:

MainFragment.kt

class MainFragment : Fragment() {
    
    private var text1list = mutableListOf<String>()
    private var text2list = mutableListOf<String>()
    private var text3list = mutableListOf<String>()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_main, container, false)
        view.see_codes.setOnClickListener {
            findNavController().navigate(R.id.action_mainFragment_to_listFragment2)
        }

        TestGet()


        return view
    }

    val BASE_URL = "https://run.mocky.io/v3/"

    private fun TestGet() {

            val api = Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build()
                    .create(SimpleApi::class.java)

            GlobalScope.launch(Dispatchers.IO) {
                val response = api.phonehome()

                try {
                    for (Mlist in response.Mlist){
                        Log.d("MainActivity", "Result + $Mlist")
                        addToList(Mlist.text1, Mlist.text2, Mlist.text3)
                    }

                    withContext(Dispatchers.Main){
                        setUpRecyclerView()
                    }
                }catch (e: Exception){
                    println("you messed up the connection some how")
                }
            }
    }


    
    private fun setUpRecyclerView() {
        main_recyclerview.layoutManager = LinearLayoutManager(this.context)
        main_recyclerview.adapter = MainAdapter(text1list,text2list,text3list)
    }

    private fun addToList(text1: String, text2: String, text3: String){
        text1list.add(text1)
        text2list.add(text2)
        text3list.add(text3)

    }
}

我的适配器

MainAdapter.kt
class MainAdapter(
        private var text1: List<String>, private var text2: List<String>, private var text3: List<String>)  : RecyclerView.Adapter<MainAdapter.ViewHolder>() {

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
        var itemtext1 : TextView = itemView.findViewById(R.id.note_text_view_1)
        var itemtext2 : TextView = itemView.findViewById(R.id.note_text_view_2)
        var itmetext3 : TextView = itemView.findViewById(R.id.note_text_View_3)

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainAdapter.ViewHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.carditem,parent,false)
        return ViewHolder(v)
    }

    override fun getItemCount(): Int {
        return text1.size
    }

    override fun onBindViewHolder(holder: MainAdapter.ViewHolder, position: Int) {
        holder.itemtext1.text = text1[position]
        holder.itemtext2.text = text2[position]
        holder.itmetext3.text = text3[position]
    }

}

感谢您的宝贵时间。

您可以查看 RecyclerView.adapter 是否为空。并采取相应行动。

如果不是null,您已经查询并设置了适配器

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    val view = inflater.inflate(R.layout.fragment_main, container, false)
    view.see_codes.setOnClickListener {
        findNavController().navigate(R.id.action_mainFragment_to_listFragment2)
    }

    if (view.main_recyclerview.adapter == null) {
        TestGet()
    }

    return view
}

如果问题只是 RecyclerView 中的重复数据,那么您可以在 setUpRecyclerView() 函数中检查适配器是否为 null。

private fun setUpRecyclerView() {
    if (main_recyclerview.adapter == null) {  
        main_recyclerview.layoutManager = LinearLayoutManager(this.context)
        main_recyclerview.adapter = MainAdapter(text1list,text2list,text3list)
    }
}

编辑:

作为最后的手段,您可以制作一个名为 extensions 或其他名称的单独的 kotlin 文件,并在其中包含一个对象,如下所示:

object Settings{
    var recViewAlreadyUpdated : Boolean = false
}

这个变量是在应用程序运行时创建的,并且只要应用程序存在就存在,所以你可以使用这个标志将数据加载到你的 RecyclerView 中,如下所示:

if (!Settings.recViewAlreadyUpdated) {
    TestGet()
    Settings.recViewAlreadyUpdated = true
}

我认为这里正确的方法是只创建 RecyclerView 并且它是 Adapter 一次。然后更新适配器存储的数据并调用 notifyDataChanged().

我相信我已经弄清楚我的应用程序出了什么问题,但首先要非常感谢 Mehran B,是他为这个解决方案奠定了基础。

问题出在代码顶部的 mutableListOf 变量。他们保留了上次调用该函数的数据,并只是将其添加到其中。所以首先我试图通过清除所有 mutableListOf 的数据来解决问题。好吧,我不知道具体怎么做,但如果有人知道怎么做,请发表评论。

所以我最终做的是这个

    if (!Settings.recViewAlreadyUpdated) {
        TestGet()

        Settings.recViewAlreadyUpdated = true

    }else{
        text1list = mutableListOf()
        text2list = mutableListOf()
        text3list = mutableListOf()
        TestGet()
    }

我所做的是覆盖或创建一个新的 mutableListOf(我不确定是哪个),如果以前没有使用过该功能。再次非常感谢 Mehran B https://whosebug.com/users/10695663/mehran-b