为何FragmentLoginBinding返回null?Stream SDK聊天应用空指针问题
问题原因
LoginFragment重写了onCreateView方法,并且在方法内部直接使用binding对象,但此时父类BindingFragment的onCreateView还未执行,_binding变量仍然是null,强制类型转换时触发NullPointerException。
解决方案
有两种修复方式,推荐第一种:
方式一:将视图初始化逻辑移至onViewCreated
子类不要重写onCreateView,而是在onViewCreated中处理控件绑定、事件监听等逻辑,此时父类已经完成binding的初始化:
修改后的LoginFragment代码:
@AndroidEntryPoint class LoginFragment : BindingFragment<FragmentLoginBinding>() { override val bindingInflater: (LayoutInflater) -> ViewBinding get() = FragmentLoginBinding::inflate private val viewModel : LoginViewModel by viewModels() // 移除重写的onCreateView,使用父类的实现 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.btnConfirm.setOnClickListener{ setUpConnectingUIState() viewModel.connectUser(binding.etUsername.text.toString()) } binding.etUsername.addTextChangedListener { binding.etUsername.error = null } subscribeToEvents() } private fun setUpConnectingUIState(){ binding.progressBar.isVisible = true binding.btnConfirm.isVisible = false } private fun setUpIdealUIState(){ binding.progressBar.isVisible = false binding.btnConfirm.isVisible = true } private fun subscribeToEvents(){ lifecycleScope.launch { viewModel.logInEvent.collect{event -> when(event){ is LoginViewModel.LogInEvent.ErrorInputTooShort->{ setUpIdealUIState() binding.etUsername.error = getString(R.string.error_username_too_short,Constants.MIN_USERNAME_LENGTH) } is LoginViewModel.LogInEvent.ErrorLogIn->{ setUpIdealUIState() Toast.makeText( requireContext(), event.error, Toast.LENGTH_LONG ).show() } is LoginViewModel.LogInEvent.Success->{ setUpIdealUIState() } } } } } }
方式二:重写onCreateView时先调用父类方法
如果必须重写onCreateView,需要先调用super.onCreateView()完成binding的初始化,再使用binding对象:
修改后的LoginFragment的onCreateView:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // 先调用父类方法初始化binding val view = super.onCreateView(inflater, container, savedInstanceState) binding.btnConfirm.setOnClickListener{ setUpConnectingUIState() viewModel.connectUser(binding.etUsername.text.toString()) } binding.etUsername.addTextChangedListener { binding.etUsername.error = null } subscribeToEvents() return view }
额外优化建议
可以给BindingFragment的binding属性添加空判断,避免潜在的空指针:
protected val binding: T get() = checkNotNull(_binding) { "Binding is only valid between onCreateView and onDestroyView" }
内容的提问来源于stack exchange,提问作者Navneet
相关产品推荐
相关产品推荐

