最近出现在了一个这样的警告:

The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.

kotlinx.android.synthetic 不再是推荐的做法,删除支持显式findViewById,用ViewBinding替代

ViewBinding

与 Kotlin Extensions相比,它增加了视图查找和类型安全的编译时检查。但视图绑定后,可让您更轻松地编写与视图交互的代码。启用视图绑定后,它会为该模块中存在的每个 XML 布局文件生成一个绑定类。

如何启用视图ViewBinding?

在build.gradle中添加:

android {
..
    buildFeatures {
       viewBinding true
    }
}

如何使用ViewBinding?

  • 如果为模块启用了视图绑定,则会为模块包含的每个 XML 布局文件生成一个绑定类。
  • 每个绑定类都包含对根视图和所有具有 ID 的视图的引用。
  • 绑定类的名称是通过将 XML 文件的名称转换为 Pascal 大小写并Binding在末尾添加单词来生成的。

在Activity中使用ViewBinding

private lateinit var binding: ActivityMainBinding

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

使用binding对象访问View

binding.name.text = "this is ViewBinding"

在Fragment中使用ViewBinding

在Fragment中使用ViewBinding需要注意,因为ViewBinding不能很好地与Fragment一起使用,如果不在OnDestroy清除,则它不会从内存中清除,导致内存泄漏。

private var _binding: FragmentMainBinding? = null
private val binding get() = _binding!!

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

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

像在activity中一样使用对象访问视图

binding.name.text = "this is ViewBinding"
备注

ViewBinding将为模块中的每个XML布局生成一个绑定对象,例如:activity_main.xml

<?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将生成 ActivityMainBinding.java

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

  @NonNull
  public final TextView textView;
...
}

ViewBinding将为每个具有指定id. 在ActivityMainBinding.java中,ViewBinding生成一个公共inflate方法。
它调用bind将绑定属性的位置,并进行一些错误检查。