简体   繁体   English

在Kotlin中将值从Activity传递给Fragment

[英]Passing a value from Activity to Fragment in Kotlin

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. 在Main Activity中,我将值存储在变量中,但是如果将值传递给片段,则会收到NullPointer Exception错误。 I am using kotlin in my project and any help is appreciated. 我在项目中使用kotlin,对您的帮助表示赞赏。 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 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)

Here is an example of the newInstance pattern for creating Fragments . 这是用于创建FragmentsnewInstance模式的示例。

This is within a companion object , which is pretty much just a way to say "these things are Static." 这是在companion object ,这几乎只是说“这些东西是静态的”的一种方式。

First, you should define constants for your Bundle names, this will help keep everything aligned. 首先,您应该为Bundle名称定义常量,这将有助于使所有内容保持一致。 Next, define a newInstance method that takes your parameters, such as the name . 接下来,定义一个采用您的参数(例如namenewInstance方法。

And within there, you will create your Fragment and return it. 在其中,您将创建Fragment并将其返回。 This way, your Activity doesn't have to worry about the Bundle or anything. 这样,您的Activity就不必担心Bundle或其他任何东西。 All your logic is within one place, for storing/retrieving, all within your Fragment . 您所有的逻辑都在一个Fragment内,用于存储/检索,所有这些都在您的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. 现在,您可以通过执行以下操作轻松获得Fragment

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! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM