Passing a value from Activity to Fragment in Kotlin

时光毁灭记忆、已成空白 提交于 2020-02-06 11:31:58

问题


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)

回答1:


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!



来源:https://stackoverflow.com/questions/53964718/passing-a-value-from-activity-to-fragment-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!