Kotlin Android扩展已弃用。该怎么办?迁移说明

您可能已经听说过Kotlin的Kotlin Android扩展插件已被弃用。

不再建议使用kotlinx.android.synthetic。删除支持显式的findViewById


当然,这非常方便,特别是如果您完全在Kotlin中有一个项目。但是,世界在变化,现在我们需要寻找替代方法。在本文中,我们将快速了解一下Kotlin Android扩展插件是什么,出现了什么问题以及我们Android开发人员现在应该做什么。部分使用了本文中的材料所以走吧



Kotlin Android扩展一览



Kotlin Android Extensions是一个Kotlin插件,可让您从Activity,Fragments和Views还原视图,而无需编写诸如findViewById之类的标准样板代码。

该插件会生成其他代码,使您可以XML形式访问视图,就像处理定义结构时使用的名为id的属性一样。



它还创建一个本地视图缓存。首次使用该属性时,插件将执行标准的findViewById。随后,将从缓存中还原视图,因此对其的访问将更快。



如果这一切都那么方便,那为什么不推荐使用呢?



Kotlin Android扩展问题



  • 使用标识符的全局命名。当不同的视图在不同的布局中具有相同的标识符时,可能会出现这种情况-因此,只有在应用程序操作阶段,您才会发现您使用了错误的ID。
  • 仅可用于Kotlin项目(上限)
  • 缺少空安全性。在视图以一种配置显示而在另一种配置中不存在的情况下,可能会发生崩溃,因为没有对这种情况的处理
  • 不能在多模块项目中使用。一个非常常见的场景:您有一个UI Kit模块,该模块存储要在其他模块中重用的常见UI组件。仍然存在一些不太可能纠正的问题。在这种情况下,通常使用旧的findViewById :(
  • , , — , , . — Kotlin Android Extensions .




  • KotterKnife (, ).
  • FindViewById() — , .
  • AndroidAnnotations ( 2015)
  • View Binding Google — !


View Binding Google



因此,此列表中的赢家是Google的ViewBinding(不要与DataBinding混淆)。让我们快速看一下它是什么。



视图绑定是一种工具,可以使编写代码与视图交互的过程变得更加容易。在特定模块中启用“查看绑定”时,它将为模块中的每个布局文件生成绑定类。生成的绑定类的对象包含指向标记文件中所有视图的链接,该标记文件指定了android:id。



视图绑定的主要优点是Null安全和Type安全。



视图绑定入门



ViewBinding入门很容易。您需要添加一个build.gradle选项:



android {
    ...
    buildFeatures {
        viewBinding true
    }
}


之后,您就可以使用它了。每个生成的绑定类都包含指向标记的根视图(根)的链接以及指向具有id的所有视图的链接。生成的类的名称形成为“标记文件的名称”,翻译为驼峰大写+“绑定”。例如,对于标记文件result_profile.xml:



<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>


将生成一个ResultProfileBinding类,其中包含2个字段:TextView名称和Button按钮。



在活动中使用



例如,您具有以下布局:



<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


ViewBinding的结果:



public final class ActivityMainBinding implements ViewBinding {
  @NonNull
  private final ConstraintLayout rootView;

  @NonNull
  public final TextView textView;


您可以像这样使用viewBinding:



private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}


现在,在获得视图的链接之后:



binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }


如果您在片段中使用ViewBinding并将片段的链接保留在片段中(不仅在onCreateView()方法中),那么请不要忘记在onDestroyView()方法中清除链接。



例:



private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

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

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}


由于片段和视图的生命周期,必须完成此操作:



图片



通常,切换到ViewBinding还不够困难,尽管遗憾的是不建议使用Kotlin Android扩展。别忘了加入Telegram加入我们AndroidSchool.ru平台上发布适用于Android开发人员的有用材料和现代教程。



有用的链接:






All Articles