android - 我可以在我的 Android fragment 中消除 View 模型和 View 绑定(bind)样板代码吗?

标签 android kotlin android-viewmodel boilerplate android-viewbinding

我发现自己为我创建的每个新 fragment 编写样板代码。 这包括设置 View 模型和 View 绑定(bind),这是我的代码中不相互依赖的两个不同部分,因此其中一个的解决方案仍然很棒。

fragment 代码示例:

class MyFragment : Fragment() {

    // View binding
    private var _binding: FragmentMyBinding? = null

    // View model
    private lateinit var model : MyViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Model init
        model = ViewModelProvider(this).get(MyViewModel::class.java)

        //binding init
        _binding = FragmentMyBinding.inflate(inflater, container, false)

        return _binding!!.root
    }

}

class MyViewModel : ViewModel()

最佳答案

ViewModel documentation page 上所见, Kotlin 代码不应使用 ViewModelProvider(this),而应使用 by viewModels()这是 fragment-ktx 依赖项的一部分。这取代了 lateinit var model 的使用并且必须在 onCreateView() 中做任何事情,这意味着你的 fragment 变成:

class MyFragment : Fragment() {

    // View binding
    private var _binding: FragmentMyBinding? = null

    // View model
    private val model: MyViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //binding init
        _binding = FragmentMyBinding.inflate(inflater, container, false)

        return _binding!!.root
    }
}

您可以采用 this one 等方法并避免捕获绑定(bind)。这种方法意味着您的 fragment 将是:

class MyFragment : Fragment(R.layout.my_fragment) {

    // View model
    private val model: MyViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val binding = FragmentMyBinding.bind(view)
        // Now use the binding and your ViewModel
    }
}

另一种选择是复制 AutoClearedValue进入您的项目并使用它,这会使它看起来像:

class MyFragment : Fragment() {

    // View binding
    private var binding by autoCleared<FragmentMyBinding>()

    // View model
    private val model: MyViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentMyBinding.inflate(inflater, container, false)
        // Now use the binding and your ViewModel

        return binding.root
    }
}

此时,无论使用哪种解决方案,您都最多使用 3 行共享代码,所有这些都不同,因此尝试构建基本 fragment 并处理泛型会使事情变得更加复杂,并且会我不建议这样做。

关于android - 我可以在我的 Android fragment 中消除 View 模型和 View 绑定(bind)样板代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61282998/

相关文章:

java - 在android中使用默认应用程序打开文件

intellij-idea - 全局禁止 NOTHING_TO_INLINE 警告

java - ViewPager2/Tabs 问题与 ViewModel 状态

Android创建自定义溢出菜单项

android - 如何使用ActiveAndroid保存所有嵌套类?

android - 在外部级别添加项目作为对模块的依赖

android - 如何旋转可组合项并将进度监听器添加到旋转中?

android - 从Health Kit发送步骤后,步骤在Huawei Health应用程序上不可见

java - Android Paging Library如何知道加载更多数据?

android - 如何使用 ViewModel 的新保存状态模块