在 Kotlin 中将值从 Activity 传递到 Fragment
Posted
技术标签:
【中文标题】在 Kotlin 中将值从 Activity 传递到 Fragment【英文标题】:Passing a value from Activity to Fragment in Kotlin 【发布时间】:2019-05-26 15:27:50 【问题描述】:我在我的项目中创建了一个底部导航活动,其中包含一个活动和两个片段。在主活动中,我将值存储在一个变量中,但如果我将值传递给片段,那么我会收到 NullPointer 异常错误。我在我的项目中使用 kotlin,感谢您的帮助。 期待
Get Value into Fragment from MainActivity. MainActivity--->TestOneFragment
使用的语言
Kotlin
主要活动
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")
....
错误
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)
【问题讨论】:
您可以分享正确的日志,例如您在哪里获得 NPE,并尝试添加更多代码细节,例如您在哪个函数中传递/访问数据等。 你什么时候调用参数!!.getString("name")?同时,尽量避免在代码中强制展开(使用!!)。 @AdrianComan 感谢您的评论。如果我这样做了,那么我的变量输出中就会出现空值。 val testName= arguments?.getString("name") 正确,因为参数为空,但是您在代码中何时何地调用它?您可以发布片段类的示例吗? 我在 onCreateView 函数中调用它。 【参考方案1】:以下是用于创建Fragments
的newInstance
模式示例。
这是在companion object
中,这几乎只是一种表达“这些东西是静态的”的方式。
首先,您应该为您的Bundle
名称定义常量,这将有助于保持所有内容对齐。接下来,定义一个接受参数的newInstance
方法,例如name
。
在那里,您将创建您的Fragment
并返回它。这样,您的Activity
就不必担心Bundle
或其他任何事情。您所有的逻辑都在一个地方,用于存储/检索,都在您的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)
// ...
现在,您可以通过执行以下操作轻松获取您的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)
希望对您有所帮助!
【讨论】:
感谢您的评论。你能解释一下关于 MyActivity 代码的更多信息吗?我不确定在哪里写那段代码,比如在活动中还是在片段中 @JoshJo -MyActivity
代码进入您所在的任何Activity
。假设您在您的MainActivity
上,并且您想显示您的TestOneFragment
,您的MainActivity
可以调用TestOneFragment.newInstance("name")
,准备好Fragment
,然后随心所欲地显示它。
如果您编辑您的问题以包括您将如何在您的MainActivty
中显示您的Fragment
,我将编辑我的答案更具体。
我正在寻找另一个方向。我需要将活动值放入片段中。 MainActivity---->TestOneFragment
是的,我明白了。 MainActivty
有一些数据,您想用这些数据创建一个新的Fragment
。对吗?以上是关于在 Kotlin 中将值从 Activity 传递到 Fragment的主要内容,如果未能解决你的问题,请参考以下文章
如何将值从基本适配器传递到 Android 中的 Activity
如何在 QWebEngineView 中将值从 QML 传递到 JavaScript