• 废弃的kotlin-android-extensions,是时候接受ViewBinding了


    一、kotlin-android-extensions 是什么?

    kotlin-android-extensions是由Kotlin团队研发的可以让开发更简单的插件。当前仅仅包括了view的绑定。这个插件自动创建了很多的属性来让我们直接访问XML中的view。这种方式不需要你在开始使用之前明确地从布局中去找到这些views。

    二、kotlin-android-extensions用途

    如上所说kotlin-android-extensions的研发的主要目的是为了减轻代码中过渡繁琐的findViewById的使用。

    在Android Studio4.1以前我们新建kotlin项目ide会自动给我们引入该插件的引用,我们只需要像往常一样在xml中进行布局,在需要使用的代码中引入对应库文件即可直接使用,详细可以看下方对比。

    三、常见视图绑定对比

    .xml文件内容如下:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LinearLayout
    3. xmlns:android="http://schemas.android.com/apk/res/android"
    4. android:layout_height="match_parent"
    5. android:layout_width="match_parent"
    6. android:gravity="center">
    7. <Button
    8. android:id="@+id/btn_test"
    9. android:layout_width="wrap_content"
    10. android:layout_height="wrap_content"
    11. android:text="测试"/>
    12. </LinearLayout>
    • 第一种,传统方式绑定视图(findViewById)
    1. private var mTestBtn:Button
    2. override fun onCreate(savedInstanceState: Bundle?) {
    3. super.onCreate(savedInstanceState)
    4. setContentView(R.layout.activity_main)
    5. mTestBtn= findViewById(R.id.btn_test) as Button
    6. mTestBtn.setOnClickListener {
    7. Toast.makeText(this@MainActivity,"success",Toast.LENGTH_SHORT).show()
    8. }
    9. }

    以上为Android原生的视图绑定方式,使用findViewById进行关联控件id,最后强转类型。

    • 第二种,框架注解绑定视图(ButterKnife)
    1. @BindView(R.id.btn_login)
    2. var mTestBtn:Button
    3. override fun onCreate(savedInstanceState: Bundle?) {
    4. super.onCreate(savedInstanceState)
    5. setContentView(R.layout.activity_main)
    6. ButterKnife.bind(this)
    7. mTestBtn.setOnClickListener {
    8. Toast.makeText(this@MainActivity,"success",Toast.LENGTH_SHORT).show()
    9. }
    10. }

    上述是使用以前普遍使用的ButterKnife视图绑定框架进行的方式,在使用上述代码时需要自行引入ButterKnife相关的依赖包。

    • 第三种,插件绑定视图(Kotlin-Android-Extensions)

    这种就是我们说的Kotlin-Android-Extensions插件了,它的使用如下:

    1、引入库插件,这一步在Android Studio4.1以前创建项目时ide会自动帮我们做了这件事情。

    apply plugin: 'kotlin-android-extensions'

    2、在需要绑定视图的Activity、Fragment、Adapter及自定义View中引入资源文件

    import kotlinx.android.synthetic.main.activity_main.*

    3、在使用的位置,直接使用xml中对应的id访问视图,完整代码如下:

    1. import kotlinx.android.synthetic.main.activity_main.*
    2. class MainActivity : AppCompatActivity() {
    3. override fun onCreate(savedInstanceState: Bundle?) {
    4. super.onCreate(savedInstanceState)
    5. setContentView(R.layout.activity_main)
    6. btn_test.setOnClickListener {
    7. Toast.makeText(this@MainActivity,"success",Toast.LENGTH_SHORT).show()
    8. }
    9. }
    10. }

    四、kotlin-android-extensions常见的问题

    • 污染全局命名空间
    • 不能暴露可空性信息
    • 仅支持 Kotlin 代码

    五、ViewBinding是什么?

    随着Android studio3.6的发布,我们发现google官方推出了新的一套框架,那就是ViewBinding。那他能干嘛呢,我们先看看官方的描述:

    通过视图绑定功能,您可以更轻松地编写可与视图交互的代码。在模块中启用视图绑定之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。
    在大多数情况下,视图绑定会替代  findViewById

    也就是说我们通过使用ViewBinding也可以轻松的解决findViewById的繁琐使用问题,同样可以实现kotlin-android-extensions插件的类似功能。

    其实同时还能在java和kotlin中同时使用,解决了kotlin-android-extensions插件使用所带来的问题。另外针对使用MVVM的朋友来说ViewBinding还可以和databinding配合使用,非常的方便。

    所以是时候可以拥抱ViewBinding了~

    六、ViewBinding的使用

    1、项目集成

    需要使用ViewBinding的功能,需要在对应的module的build.gradle文件中启用ViewBinding支持。

    1. android {
    2. ...
    3. viewBinding {
    4. enabled = true
    5. }
    6. }

    如果您希望在生成绑定类时忽略某个布局文件,请将tools:viewBindingIgnore="true"属性添加到相应布局文件的根视图中:

    1. <LinearLayout
    2. ...
    3. tools:viewBindingIgnore="true" >
    4. ...
    5. LinearLayout>

    2、在Activity中使用

    如需设置绑定类的实例以供 Activity 使用,请在 Activity 的onCreate()方法中执行以下步骤:

    1. 调用生成的绑定类中包含的静态inflate()方法。此操作会创建该绑定类的实例以供 Activity 使用。
    2. 通过调用 getRoot()方法或使用kotlin语法获取对根视图的引用。
    3. 将根视图传递到setContentView,使其成为屏幕上的活动视图。
    1. private ActivityMainBinding binding;
    2. @Override
    3. protected void onCreate(Bundle savedInstanceState) {
    4. super.onCreate(savedInstanceState);
    5. binding = ActivityMainBinding .inflate(getLayoutInflater());
    6. View view = binding.getRoot();
    7. setContentView(view);
    8. }

    配置后使用方式如下:

    1. binding.btnTest.setText("test");
    2. binding.button.setOnClickListener(new View.OnClickListener() {
    3. // todo
    4. });

    3、在Fragment中使用

    如需设置绑定类的实例以供 Fragment 使用,请在 Fragment 的onCreateView()方法中执行以下步骤:

    1. 调用生成的绑定类中包含的静态inflate()方法。此操作会创建该绑定类的实例以供 Fragment 使用。
    2. 通过调用 getRoot()方法或使用kotlin语法获取对根视图的引用。
    3. 从onCreateView()方法返回根视图,使其成为屏幕上的活动视图。
    1. private ActivityMainBinding binding;
    2. @Override
    3. public View onCreateView (LayoutInflater inflater,
    4. ViewGroup container,
    5. Bundle savedInstanceState) {
    6. binding = ActivityMainBinding .inflate(inflater, container, false);
    7. View view = binding.getRoot();
    8. return view;
    9. }
    10. @Override
    11. public void onDestroyView() {
    12. super.onDestroyView();
    13. binding = null;
    14. }

    配置后使用方式如下:

    1. binding.btnTest.setText("test");
    2. binding.button.setOnClickListener(new View.OnClickListener() {
    3. // todo
    4. });

    4、在Adapter中使用ViewBinding

    我们以在Recyclerview的adapter中使用ViewBinding为例,代码如下:

    1. public class MainAdapter extends RecyclerView.Adapter {
    2. private List mList;
    3. public MainAdapter(List list) {
    4. mList = list;
    5. }
    6. @NonNull
    7. @Override
    8. public MainAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    9. //之前的写法
    10. //View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_comment, parent, false);
    11. //ViewHolder holder = new ViewHolder(view);
    12. //使用ViewBinding的写法
    13. LayoutCommentBinding commentBinding = LayoutCommentBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
    14. ViewHolder holder = new ViewHolder(commentBinding);
    15. return holder;
    16. }
    17. @Override
    18. public void onBindViewHolder(@NonNull MainAdapter.ViewHolder holder, int position) {
    19. holder.mTextView.setText(mList.get(position));
    20. }
    21. @Override
    22. public int getItemCount() {
    23. return mList.size();
    24. }
    25. static class ViewHolder extends RecyclerView.ViewHolder {
    26. TextView mTextView;
    27. //之前的写法
    28. //public ViewHolder(@NonNull View itemView) {
    29. // super(itemView);
    30. // mTextView = itemView.findViewById(R.id.tv_include);
    31. //}
    32. //使用ViewBinding的写法
    33. ViewHolder(@NonNull LayoutCommentBinding commentBinding) {
    34. super(commentBinding.getRoot());
    35. mTextView = commentBinding.tvInclude;
    36. }
    37. }
    38. }

    这里需要注意两个地方:

    • ViewHolder的构造器参数改为使用的Binding对象
    • 实例化ViewHolder的时候传入相应的Binding对象

    七、结束语

    以上为kotlin-android-extensions和ViewBinding的简单介绍说明,其实在最后我们使用ViewBinding的过程中,也难免会发现有很多地方在进行inflate的使用,所以建议大家在使用的过程中将ViewBinding的inflate初始化绑定操作进行二次封装后使用,这样才算是真正的简化了这部分的代码。

    关于二次封装,大家有兴趣可以自行尝试,我相信现在网上也有很多大牛有非常不错的封装方式了,后续我也会将我自己简单的封装方式分享出来~

  • 相关阅读:
    Mac下安装Hadoop
    C/C++指针之提高篇详解(二)
    The given SOAPAction http__xxxxx_xx does not match an operation
    MySQL面试重点-2
    sql:建表删表语句,其中delete,truncate,drop区别
    思科模拟器的远程连接交换机的实现
    240个Python练习案例附源码(百看不如一练)
    反序列化漏洞(1), 原理, 实验, 魔术方法
    gcc 好玩的 builtin 函数
    Halcon知识:用分箱实现OCR分类器
  • 原文地址:https://blog.csdn.net/Goals1989/article/details/126876290