You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Android View Binding与Kotlin时,能否避免处处使用!!操作符?

解决Fragment中ViewBinding频繁使用!!的几种方案

方案一:可空变量+作用域函数(无额外依赖)

保持binding为可空类型,通过run或let作用域函数包裹binding的操作逻辑,既避免重复写!!,又能在视图销毁时置空binding防止内存泄漏。

修改后代码:

class XFragment : Fragment() {
    
    private var binding: FragmentXBinding? = null

    override fun onCreateView(inflater: LayoutInflater,
                          container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = FragmentXBinding.inflate(inflater, container, false)
        return binding?.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding?.run {
            slPower.addOnChangeListener(this@XFragment)
            btnClearTagList.setOnClickListener(this@XFragment)
        }
    }

    private fun updateUi(){
        binding?.run {
            someTextView.text = getSomeTextViewText()
            someSlider.value = getSomeSliderValue()
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding = null // 销毁视图时清空引用,避免内存泄漏
    }
}

方案二:使用lateinit延迟初始化

利用lateinit关键字声明非空的binding变量,因为我们能保证在onCreateView中完成初始化,且在onViewCreated到onDestroyView的生命周期内binding一定非空,符合lateinit的使用规则。

注意:这种方式无法在onDestroyView中置空binding,若Fragment涉及配置变化(如屏幕旋转),可能存在潜在的内存泄漏风险,适合简单场景使用。

代码示例:

class XFragment : Fragment() {
    
    private lateinit var binding: FragmentXBinding

    override fun onCreateView(inflater: LayoutInflater,
                          container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = FragmentXBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.slPower.addOnChangeListener(this)
        binding.btnClearTagList.setOnClickListener(this)
    }

    private fun updateUi(){
        binding.someTextView.text = getSomeTextViewText()
        binding.someSlider.value = getSomeSliderValue()
    }
}

方案三:Android KTX委托(最简洁)

借助Android KTX提供的viewBinding委托,自动处理binding的初始化和生命周期销毁,无需手动管理,代码最简洁。

首先确保引入KTX依赖(版本可根据项目调整):

implementation "androidx.fragment:fragment-ktx:1.6.1"

修改后代码:

class XFragment : Fragment() {
    // 委托自动绑定视图,无需手动初始化
    private val binding by viewBinding(FragmentXBinding::bind)

    override fun onCreateView(inflater: LayoutInflater,
                          container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_x, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.slPower.addOnChangeListener(this)
        binding.btnClearTagList.setOnClickListener(this)
    }

    private fun updateUi(){
        binding.someTextView.text = getSomeTextViewText()
        binding.someSlider.value = getSomeSliderValue()
    }
}

该委托会在onViewCreated时自动绑定视图,onDestroyView时自动清空binding引用,彻底避免!!和内存泄漏问题。


内容的提问来源于stack exchange,提问作者Kamil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:01:22