2

I have a BottomNavigationView with 2 sub menu, Home and Email, and a fab to add items to Email.

I'm using the fragment EmailFragment to handle sub menu click. Now, in EmailFragment I have a ListView. The fab in BottomNavigationMenu is able to add items to EmailFragment ListView from MainActivity and it works fine. The problem is, I see new ListView items only when I reopen EmailFragment with its layout.

I want that when I add items to this ListView appear without reopening fragment.

This is how I add items in 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()

                }
            }

This is how I save data from 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
}

This is how I get data from 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
}
Arfmann
  • 684
  • 9
  • 30

3 Answers3

1

Use LiveData, LiveData will observe the changes and automatically refresh adapter

0

WORKAROUND

Finally, I went to a hack to "resolve" my problem. Just reload the fragment.

MainActivity:

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

openFragment:

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()
}
Arfmann
  • 684
  • 9
  • 30
  • That's no solution, that's a hack. It will most likely mess with your back navigation, too. – EpicPandaForce Aug 07 '19 at 10:28
  • I know, this is why I written "or something similiar". Anyway, I'll write directly "Workaround" instead of "Solution" – Arfmann Aug 07 '19 at 10:30
  • Honestly, you might still want to test your app for https://stackoverflow.com/questions/49046773/singleton-object-becomes-null-after-app-is-resumed/49107399#49107399 – EpicPandaForce Aug 07 '19 at 12:00
-1

Just simply call

adapter.notifyDataSetChanged()
Lukas
  • 812
  • 1
  • 14
  • 43