修改include引入的partial布局中TextView文本报空指针如何解决?
问题解决方案
报错根因
MainActivity的onCreate执行时,Fragment还未完成视图渲染流程,你要操作的TextView还没被加载到Activity的视图树中,findViewById返回null,调用setText就会触发空指针异常。
推荐解决方案(无需修改父Fragment代码,适配所有Fragment加载场景)
通过FragmentManager注册全局Fragment生命周期回调,监听目标Fragment的视图创建完成事件后再操作控件,步骤如下:
- (可选,解决多同ID控件冲突问题)给
fragment.xml中的include标签添加唯一ID:
... <include android:id="@+id/partial_layout_root" layout="@layout/partial_layout" /> ...
- 修改
MainActivity.kt代码,替换原有直接查找控件的逻辑:
class MainActivity: SuperActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 注册Fragment生命周期监听 supportFragmentManager.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() { override fun onFragmentViewCreated( fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle? ) { super.onFragmentViewCreated(fm, f, v, savedInstanceState) // 匹配你要操作的目标Fragment,替换为你实际的父Fragment类名,也可通过Tag等方式判断 if (f.javaClass == TargetParentFragment::class.java) { // 查找控件,两种方式二选一即可 // 方式1:直接通过Fragment根视图查找 val textView = v.findViewById<TextView>(R.id.testString) // 方式2:如果给include加了ID,通过include根布局查找 // val partialRoot = v.findViewById<View>(R.id.partial_layout_root) // val textView = partialRoot.findViewById<TextView>(R.id.testString) textView?.text = "Some new text" // 只需要操作一次的话,操作完成后注销回调避免内存泄漏 supportFragmentManager.unregisterFragmentLifecycleCallbacks(this) } } }, false) } ... }
备选简易方案(仅适配Fragment静态写在Activity布局的场景)
如果你的Fragment是直接在Activity的布局文件中通过<fragment>标签静态引入的,可以把操作控件的逻辑移到onPostCreate生命周期中执行:
override fun onPostCreate(savedInstanceState: Bundle?) { super.onPostCreate(savedInstanceState) findViewById<TextView>(R.id.testString)?.text = "Some new text" }
内容的提问来源于stack exchange,提问作者Hadif Hatta
相关产品推荐
相关产品推荐

