Kotlin Android开发:Activity向MenuFragment传session ID失败怎么解决
Kotlin Android Fragment 数据传递问题修复方案
问题根因定位
Activity侧问题
你在Home类顶部已经初始化了全局的MenuFragment实例,底部导航切换时使用的也是这个全局实例,但你在onCreate末尾创建了一个临时的独立MenuFragment对象设置Bundle,这个临时对象从未被挂载到页面上,全局实例没有拿到Bundle,所以传值失效。
Fragment侧问题
- 取值时机错误:
onCreate生命周期阶段Fragment的视图还未加载完成,此时直接操作emailAddressText控件会触发空指针异常,赋值逻辑需要延后到视图加载完成的onViewCreated阶段执行。 - 取值方式错误:
arguments?.let { it.toString() }打印的是整个Bundle对象的序列化内容,并非你存入的EXTRA_SESSION_ID对应的值,需要通过key明确取出字符串。
修复后代码
修复后的Home.kt
class Home : AppCompatActivity() { // 变量名调整为小驼峰,避免和类名重名混淆 private val homeFragment = HomeFragment() private val creditsFragment = CreditsFragment() private val busFragment = BusFragment() private val notificationsFragment = NotificationsFragment() private val menuFragment = MenuFragment() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.home) val sessionId = intent.getStringExtra("EXTRA_SESSION_ID") textView4.text = sessionId // 直接给全局使用的menuFragment实例设置Bundle val bundle = Bundle() bundle.putString("EXTRA_SESSION_ID", sessionId) menuFragment.arguments = bundle replaceFragment(homeFragment) bottomNavBar.setOnNavigationItemSelectedListener{ when (it.itemId){ R.id.menu_home -> replaceFragment(homeFragment) R.id.menu_credits -> replaceFragment(creditsFragment) R.id.menu_bus -> replaceFragment(busFragment) R.id.menu_notification -> replaceFragment(notificationsFragment) R.id.menu_menu -> replaceFragment(menuFragment) } true } } private fun replaceFragment(fragment:Fragment){ val transaction = supportFragmentManager.beginTransaction() transaction.replace(R.id.fragment_container, fragment) transaction.addToBackStack(null) transaction.commit() } }
修复后的MenuFragment.kt
class MenuFragment : Fragment() { // 统一声明Bundle key,避免拼写错误 private val EXTRA_SESSION_ID = "EXTRA_SESSION_ID" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_menu, container, false) } // 视图加载完成后再操作控件、取值 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 先绑定控件,若使用视图绑定可省略findViewById步骤 val emailAddressText = view.findViewById<TextView>(R.id.emailAddressText) arguments?.let { val sessionId = it.getString(EXTRA_SESSION_ID) sessionId?.let { id -> emailAddressText.text = id } } } companion object { // 可选优化:官方推荐的Fragment传值统一入口,降低传值出错概率 fun newInstance(sessionId: String): MenuFragment { val fragment = MenuFragment() val args = Bundle() args.putString(EXTRA_SESSION_ID, sessionId) fragment.arguments = args return fragment } } }
内容的提问来源于stack exchange,提问作者ABI
相关产品推荐
相关产品推荐

