Passing a value from Activity to Fragment in Kotlin

17,693

Here is an example of the newInstance pattern for creating Fragments.

This is within a companion object, which is pretty much just a way to say "these things are Static."

First, you should define constants for your Bundle names, this will help keep everything aligned. Next, define a newInstance method that takes your parameters, such as the name.

And within there, you will create your Fragment and return it. This way, your Activity doesn't have to worry about the Bundle or anything. All your logic is within one place, for storing/retrieving, all within your Fragment.

class TestOneFragment {

    companion object {
        const val ARG_NAME = "name"


        fun newInstance(name: String): TestOneFragment {
            val fragment = TestOneFragment()

            val bundle = Bundle().apply {
                putString(ARG_NAME, name)
            }

            fragment.arguments = bundle

            return fragment
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val name = arguments?.getString(ARG_NAME)
        // ...
    }
}

And now, you can easily get your Fragment by doing the following.

class Test : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        // ...

        val name = intent.getStringExtra("name")

        // Creating the new Fragment with the name passed in.
        val fragment = TestFragment.newInstance(name)
    }

}

Hopefully that helps!

Share:
17,693

Related videos on Youtube

Zoe stands with Ukraine
Author by

Zoe stands with Ukraine

Pronouns: she/her Stand with Ukraine

Updated on June 04, 2022

Comments

  • Zoe stands with Ukraine
    Zoe stands with Ukraine almost 2 years

    I created a bottom navigation activity in my project, which contains one activity and two fragments. In Main Activity I have value stored in a variable but if I pass the value to the fragments then I am getting NullPointer Exception error. I am using kotlin in my project and any help is appreciated. Expectation

    Get Value into Fragment from MainActivity. MainActivity--->TestOneFragment
    

    Language Used

    Kotlin
    

    Main Activity

    class Test : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener
    {
        private val KEY_POSITION = "keyPosition"
        private var navPosition: BottomNavigationPosition = BottomNavigationPosition.ONE
        private lateinit var toolbar: Toolbar
        private lateinit var bottomNavigation: BottomNavigationView
    
        override fun onCreate(savedInstanceState: Bundle?)
        {
            super.onCreate(savedInstanceState)
            restoreSaveInstanceState(savedInstanceState)
            setContentView(R.layout.activity_test)
            toolbar = findViewById(R.id.toolbar)
            bottomNavigation = findViewById(R.id.bottom_navigation)
            setSupportActionBar(toolbar)
            initBottomNavigation()
            initFragment(savedInstanceState)
            var Name:String=intent.getStringExtra("name")
            println("Test CLLicked: $Name")
    
    
            //This code is to pass the value to Fragment
            var bundle=Bundle()
            bundle.putString("name",Name)
            var frag=TestFragment()
            frag.arguments=bundle
        }
    
        override fun onSaveInstanceState(outState: Bundle?)
        {
            outState?.putInt(KEY_POSITION, navPosition.id)
            super.onSaveInstanceState(outState)
        }
    
        override fun onNavigationItemSelected(item: MenuItem): Boolean
        {
            navPosition = findNavigationPositionById(item.itemId)
            return switchFragment(navPosition)
        }
    
        private fun restoreSaveInstanceState(savedInstanceState: Bundle?)
        {
            savedInstanceState?.also {
                val id = it.getInt(KEY_POSITION, BottomNavigationPosition.ONE.id)
                navPosition = findNavigationPositionById(id)
            }
        }
    
        private fun initBottomNavigation()
        {
            bottomNavigation.active(navPosition.position)
            bottomNavigation.setOnNavigationItemSelectedListener(this)
        }
    
        private fun initFragment(savedInstanceState: Bundle?)
        {
            savedInstanceState ?: switchFragment(BottomNavigationPosition.ONE)
        private fun switchFragment(navPosition: BottomNavigationPosition): Boolean {
            return supportFragmentManager.findFragment(navPosition).let {
                if (it.isAdded) return false
                supportFragmentManager.detach() // Extension function
                supportFragmentManager.attach(it, navPosition.getTag()) // Extension function
                supportFragmentManager.executePendingTransactions()
            }
        }
        private fun FragmentManager.findFragment(position: BottomNavigationPosition): Fragment
        {
            return findFragmentByTag(position.getTag()) ?: position.createFragment()
        }
    }
    

    TestOneFragment

     override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
        val testName= arguments!!.getString("name")
    ....
    }
    

    Error

    kotlin.KotlinNullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
            at android.app.ActivityThread.-wrap11(Unknown Source:0)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    
    • Shubham AgaRwal
      Shubham AgaRwal over 5 years
      You can share proper logs like where you are getting NPE and try to add more details of your code like in which function you are passing/accessing the data etc.
    • Adrian Coman
      Adrian Coman over 5 years
      when are you calling arguments!!.getString("name")? As well, try to avoid force unwrapping (using !!) in your code.
    • Admin
      Admin over 5 years
      @AdrianComan thanks for your comment. If I do then I am getting null in my variable output. val testName= arguments?.getString("name")
    • Adrian Coman
      Adrian Coman over 5 years
      correct, because arguments is null, but when or where in the code are you calling it? can you post a sample of your fragment class?
    • Admin
      Admin over 5 years
      I am calling this inside onCreateView function.
  • Admin
    Admin over 5 years
    Thanks for your comment. Can you explain little bit more about MyActivity code. I am not sure where to write that piece of code like either in activity or in fragment
  • advice
    advice over 5 years
    @JoshJo - The MyActivity code goes into whatever Activity you're in. Say you're on your MainActivity and you want to show your TestOneFragment, your MainActivity can call the TestOneFragment.newInstance("name"), get the Fragment all prepared, and just display it however you want to.
  • advice
    advice over 5 years
    If you edit your question to include how you're going to display your Fragment in your MainActivty, I'll edit my answer to be more specific.
  • Admin
    Admin over 5 years
    I am looking otherway round. I need to get Activity Value into Fragment. MainActivity---->TestOneFragment
  • advice
    advice over 5 years
    Yes, I understand. MainActivty has some data, and you want to create a new Fragment with that data. Right?
  • advice
    advice over 5 years
    @JoshJo Okay, edit your question to include more of your MainActivity code, to include what you want to do with the new Fragment, and I'll edit my answer to help more.
  • advice
    advice over 5 years
    @JoshJo, Ok, I updated my code to kind of use your code for an example of how you'd use that in your actual code. Hopefully that helps.
  • Admin
    Admin over 5 years
    still getting null value after the above changes.
  • advice
    advice over 5 years
    @JoshJo I think it may be related to how you're using the Fragment. In the MainActivity class, you're not actually using that instance. You're just creating it, and ignoring it. How are you using your Fragments? Are you creating them some other way?
  • advice
    advice over 5 years
    Add the entire callstack, it should point to the exact line that has a KotlinNullPointerException.
  • Zorayr
    Zorayr over 3 years
    What if I am using NavigationHost which then automatically creates the Fragments?