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
中的工厂能够从 MainActivity
向 EmailFragment
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-stdlib-jre7(不是 kotlin-stdlib)参考
Android java项目添加kotlin混合开发环境配置