• AndroidStudio ViewBinding详解


    前言

      在Android开发,代码里获取View一般是使用findViewById()获取目标布局文件里的指定View。但是这样使用会有大量代码重复工作并且有空指针危险。为了减少重复工作有很多大神都八仙过海各显神通,但是这些神通多多少少都有缺点。

    • 大名鼎鼎的黄油刀bufferknife,缺点增加了编译速度(因为原理是它需要生成一份对应查找View的代码),并且需要时刻更新最新版本否则AndroidStudio更新后可能会出现无法编译的问题。(另外bufferknife与ViewBinding是冲突的)
    • DataBinding,缺点更明显,需要更多的xml编写工作量,并且一不小心会延伸到一些邪恶的用法,那就是在xml写逻辑判断,甚至在xml增加一些业务功能。这对代码维护是恐怖的,因为xml逻辑的可读性可比纯Java代码差多了。并且如果混乱到2头都写逻辑判断,维护起来十分痛苦。
    • AndroidStudio的插件功能自动生成代码,比如LayoutCreator,减少了工作量但是并没有减少代码的冗余,代码看起来一样是不简洁的。

    google在AndroidStudio 3.6 版本后推出了ViewBinding,一方面可以让代码更加简洁并且提高编译速度防止空指针。另一方面AndroidStudio是支持ViewBinding进行关联互动的,所以让你在Java代码与xml之间的跳转更方便。

    前提条件

      AndroidStudio 需要更新到3.6版本以上。

    在build.gradle文件里增加下面的代码,开启viewBinding

    android {
        
        //略...
    
        viewBinding{
            enabled = true;
        }
    }

    各处简单的使用Demo

    首先你需要知道一个关键点,在启用ViewBinding后。每一个layout文件都会自动生成一份Java类。它会自动根据下划线进行驼峰命名。比如一个叫 activity_mian_demo.xml 的布局文件,它对应自动生成的类叫ActivityMianDemoBinding。这就意味着我们可以在任何需要导入布局的地方都使用ViewBinding。

    Activity里:

    public class MainActivity extends AppCompatActivity {
        private ActivityMianDemoBinding mBinding;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBinding = ActivityMianDemoBinding.inflate(getLayoutInflater());
            setContentView(mBinding.getRoot());
            mBinding.btn1.setText("这是按键1");
            mBinding.btn1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                }
            });
        }
    }

    Fragment里:

    public class FragmentDemo extends Fragment {
        private FragmentDemoBinding mBinding;
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            mBinding = FragmentDemoBinding.inflate(getLayoutInflater());
            return mBinding.getRoot();
        }
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            mBinding.textView.setText("textView");
        }
    }

    在Dialog里:

    public class DemoDialog extends Dialog {
        private DialogDemoBinding mBinding;
        public DemoDialog(@NonNull Context context) {
            super(context);
            mBinding = DialogDemoBinding.inflate(getLayoutInflater());
            setContentView(mBinding.getRoot());
            mBinding.textView.setText("hello");
        }
    }

    Adapter里:

    public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.ViewHolder> {
        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return new ViewHolder(ItemDemoBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
        }
        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            holder.binding.textView2.setText("demo");
    
        }
        @Override
        public int getItemCount() {
            return 0;
        }
        public static class ViewHolder extends RecyclerView.ViewHolder {
            ItemDemoBinding binding;
            public ViewHolder(@NonNull ItemDemoBinding itemDemoBinding) {
                super(itemDemoBinding.getRoot());
                this.binding = itemDemoBinding;
            }
        }
    }

    xml属性include

    在之前其他人的博客里有说ViewBinding还不支持include属性。但是在这篇博客发布的时间,最新版本AndroidStudio4.0的已经支持使用了include属性。

    使用include的布局:

    <?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">
    
        <include
            android:id="@+id/title"
            layout="@layout/title_layout"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"/>
    
        <Button
            android:id="@+id/btn_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="A1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/title" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

    activity里:

    public class MainActivity extends AppCompatActivity {
        private ActivityMianDemoBinding mBinding;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBinding = ActivityMianDemoBinding.inflate(getLayoutInflater());
            setContentView(mBinding.getRoot());
            mBinding.title.titleContent.setText("内容");
            mBinding.title.titleContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this, "点击", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    假如你有需求要分离include的布局,单独使用这个include布局的类,可以参考如下实现:

    public class MainActivity extends AppCompatActivity {
        private ActivityMianDemoBinding mBinding;
        private TitleLayoutBinding mTitleLayoutBinding;
        @Override
    
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBinding = ActivityMianDemoBinding.inflate(getLayoutInflater());
            setContentView(mBinding.getRoot());
            mTitleLayoutBinding = TitleLayoutBinding.bind(mBinding.getRoot());
            mTitleLayoutBinding.titleContent.setText("内容11");
        }
    }

    End

  • 相关阅读:
    页式管理
    Chord算法(原理)
    php实现反转链表(链表题一定记得画图)(指向链表节点的指针本质就是一个记录地址的变量)($p->next表示的是取p节点的next域里面的数值,next只是p的一个属性)
    js进阶ajax的XMLHttpRequest对象的status和statustext属性(如果ajax和php联合使用的话:open连接服务器的第二个参数文件路径改成请求php的url即可)
    js进阶ajax基本用法(创建对象,连接服务器,发送请求,获取服务器传过来的数据)
    js进阶课程ajax简介(ajax是浏览器来实现的)
    php面试题四
    heredoc(实现模板与代码的分离)
    如何查看计算机所连接的打印机
    php面试题三
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/13234469.html
Copyright © 2020-2023  润新知