Kotlin Android - 当主活动添加项目时,从 Fragment 刷新 ListView

Posted

技术标签:

【中文标题】Kotlin Android - 当主活动添加项目时,从 Fragment 刷新 ListView【英文标题】:Kotlin Android - Refresh ListView from Fragment when an item is added by Main Activity 【发布时间】:2019-12-13 21:54:07 【问题描述】:

我有一个BottomNavigationView,有 2 个子菜单,主页和电子邮件,还有一个用于向电子邮件添加项目的工厂。

我正在使用fragment EmailFragment 来处理子菜单点击。现在,在 EmailFragment 中,我有一个 ListView。 BottomNavigationMenu 中的工厂能够从 MainActivityEmailFragment ListView 添加项目,并且工作正常。问题是,只有当我重新打开 EmailFragment 及其布局时,我才会看到新的 ListView 项目。

我希望当我将项目添加到此 ListView 时不会重新打开片段。

这是我在 MainActivity 中添加项目的方式:

 positiveButton.setOnClickListener

                if(dialogView.email_textInput.text!!.isEmpty() || dialogView.email_password_textInput.text!!.isEmpty()) 
                    Toast.makeText(this, resources.getString(R.string.empty_fields), Toast.LENGTH_LONG).show()
                

                else

                    emailAddresses.add(dialogView.email_textInput.text!!.toString())


                    adapter.notifyDataSetChanged()

                    saveData()

                
            

这是我从 MainActivity 保存数据的方式:

private fun saveData() 
    val sharedPreferences = getSharedPreferences("shared preferences", MODE_PRIVATE)
    val editor = sharedPreferences.edit()
    val gson = Gson()
    val json = gson.toJson(emailAddresses) //convert ArrayList to JSON (shared preferences can't handle ArrayList)
    editor.putString("emailAddresses", json) //save the new JSON with values
    editor.apply() //apply new changes

这就是我从 EmailFragment 获取数据的方式:

private fun loadData() 
    val sharedPreferences = this.activity!!.getSharedPreferences("shared preferences", MODE_PRIVATE)
    val gson = Gson()
    val json = sharedPreferences.getString("emailAddresses", null)
    val type = object : TypeToken<ArrayList<String>>() 
    .type

    when (json) 
        null -> emailAddresses = ArrayList() //if json is null, so empty, values is just an empty ArrayList
        else -> emailAddresses = gson.fromJson(json, type) //got JSON values and convert them back to ArrayList

    


override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?

): View? 

    loadData()

    val adapter = ArrayAdapter(this.activity!!.applicationContext, R.layout.listview_text, emailAddresses)
    adapter.notifyDataSetChanged()

    val mainView = inflater.inflate(R.layout.fragment_email, container, false)

    mainView.email_listView.adapter = adapter

    return mainView

【问题讨论】:

请添加更多代码来共享数据 我认为您的问题是您在将适配器添加到列表视图之前调用了 adapter.notifyDataSetChanged()。 在将适配器添加到列表视图后已尝试将 adapter.notifyDataSetChanged() 放入,但不起作用 您在哪里添加新项目? 在工厂点击 MainActivity。它会打开一个 AlertDialog 来添加项目。它有效,问题是打开 EmailFragment 时 ListView 不刷新 【参考方案1】:

使用 LiveData,LiveData 会观察变化并自动刷新适配器

【讨论】:

【参考方案2】:

解决方法

最后,我通过 hack 来“解决”我的问题。 只需重新加载片段。

主活动:

val emailFragment = EmailFragment.newInstance()
                openFragment(emailFragment)

打开片段:

private fun openFragment(fragment: Fragment) 
    val transaction = supportFragmentManager.beginTransaction()
    transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
    transaction.replace(R.id.container, fragment)
    transaction.addToBackStack(null)
    transaction.commit()

【讨论】:

这不是解决方案,这是一个 hack。它也很可能会干扰您的后退导航。 我知道,这就是我写“或类似的东西”的原因。无论如何,我会直接写“解决方法”而不是“解决方案” 老实说,您可能仍想针对***.com/questions/49046773/… 测试您的应用程序【参考方案3】:

只需调用

adapter.notifyDataSetChanged()

【讨论】:

以上是关于Kotlin Android - 当主活动添加项目时,从 Fragment 刷新 ListView的主要内容,如果未能解决你的问题,请参考以下文章

Android 中的 Firebase 通知 (Kotlin)

无法将 Kotlin Android 扩展添加到我的项目

为啥 Kotlin 插件为 Android 项目添加 kotlin-stdlib-jre7(不是 kotlin-stdlib)参考

Android java项目添加kotlin混合开发环境配置

Android Kotlin:如果当前活动或应用程序关闭,则进行集成测试

Android/Kotlin:将不同的活动“特征”组合成一个活动