'How to pass array list data to a fragment from main activity when using bottom navigation view and Android Navigation component?

I am trying to pass array list data to one of my fragments in the nav bar from main activity. Is there a simple way to implement this? Or should I use activity instead of the fragment? I need to pass the array list data to my HomeFragment and use recycler view adapter in the fragment, but now the issue is I don't know how to pass data because I am using bottom navigation view and Android Navigation component.

Main Activity

package com.example.a5t1v2

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import android.widget.GridView
import androidx.navigation.NavArgument
import androidx.navigation.NavController
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomnavigation.BottomNavigationView

class MainActivity : AppCompatActivity() {
    private lateinit var bottomNavigationView: BottomNavigationView
    private lateinit var navController: NavController
    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var shoppingItemList:MutableList<Item>
    private lateinit var recyclerView: RecyclerView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initUI()

        val dbHelper = DBHelper(this)
        populateDB(dbHelper)
        shoppingItemList = dbHelper.getAlItems()

    }


    private fun populateDB(dbHelper: DBHelper) {
        dbHelper.insertItem(Item("Bread",1,"Default", urgent = true, bought = false,null))
        dbHelper.insertItem(Item("Chocolate Bar",1,"Small", urgent = false, bought = false,null))
        dbHelper.insertItem(Item("Instant noodle",1,"Default", urgent = false, bought = false,null))
        dbHelper.insertItem(Item("Juice",2,"Large", urgent = false, bought = false,null))
        dbHelper.insertItem(Item("Milk",3,"Large", urgent = true, bought = false,null))

        dbHelper.insertItem(Item("Shampoo",1,"Small", urgent = false, bought = true,"24 Aug 2020"))
        dbHelper.insertItem(Item("Shower Gel",1,"Large", urgent = false, bought = true,"24 Aug 2020"))
    }

    private fun initUI() {
        appBarConfiguration = AppBarConfiguration(setOf(R.id.urgentListFragment, R.id.homeFragment, R.id.completedListFragment))
        bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottomNavigationView)
        navController = findNavController(R.id.fragmentContainerView)
        setupActionBarWithNavController(navController,appBarConfiguration)
        bottomNavigationView.setupWithNavController(navController)
    }
}


Solution 1:[1]

An easy and good way would be to use a sharedViewModel.

Create a ViewModel and declare a LiveData in it.

class MainViewModel: ViewModel () {
    private val arrayListLiveData = MutableLiveData<ArrayList<Item>>()

}

Inside Activity, create an instance of this ViewModel in the acitivity, and you can send your arrayList from here using post on the liveData

class MainActivity : AppCompatActivity() {

    private lateinit var mainViewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        
        mainViewModel.arrayListLiveData.post(YOUR_ARRAY_LIST_DATA)
    }
}

You can observe the same liveData inside the fragment, and would receive the posted arrayList there, from the Activity

class TestFragment : Fragment(R.layout.test) {

    private lateinit var mainViewModel: MainViewModel

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mainViewModel = ViewModelProvider(requireActivity()).get(MainViewModel::class.java)

        mainViewModel.arrayListLiveData.observe(viewLifecycleOwner) { arrayList ->
            //Perform desired operation with the array list
        }
    }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Praveen