2022年了Android开发的你还在用ButterKnife?kotlin-android-extensions?来试试ViewBinding吧

96 阅读2分钟

有关ViewBinding 的相关介绍官方介绍的比我详细

👇
详见官方文档

此文只记录如何简洁的在Android开发中base类中如何配置使用viewBinding来提高开发效率.

  • Activity中

 class BaseActivity<T extends ViewBinding> extends AppCompatActivity{
protected T mBinding;
}

  • 然后在onCreate中加入以下代码

        Type superclass = getClass().getGenericSuperclass();
        Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
        Method method = aClass.getDeclaredMethod("inflate", LayoutInflater.class);
        mBinding = (T) method.invoke(null, getLayoutInflater());
        setContentView(mBinding.getRoot());

  • 使用方法

    新建Activty继承Base类 传入对应的xml文件自动生成的Binding类
    如:public class MainActivity extends BaseActivity<ActivityMainBinding>
    然后使用时仅需要mBinding.xxx即可调用对应ID的View,xml文件与ID映射在本文结尾会提到


  • Fragment中

            Type superclass = getClass().getGenericSuperclass();
            Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
            Method method = aClass.getDeclaredMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
            mBinding = (T) method.invoke(null, getLayoutInflater(), container, false);


  • Dialog中

            Type superclass = getClass().getGenericSuperclass();
            Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
            Method method = aClass.getDeclaredMethod("inflate", LayoutInflater.class);
            mBinding = (T) method.invoke(null, getLayoutInflater());
            setContentView(mBinding.getRoot());


  • View中

因为viewBinding的静态方法只有三个
- inflate(LayoutInflater)
- inflate(LayoutInflater,ViewGroup ,boolean)
- bind(View)
根据参数来看inflate方法并不适用view ,bind方法更合适,因此反射不再反射Inflate 而是反射bind获取ViewBinding对象,先用View类自带的inflate从xml生成View 然后用反射调用bind方法。
代码如下:

            View v = inflate(context, getLayoutId(), this);
            Type superclass = getClass().getGenericSuperclass();
            Class<?> aClass = (Class<?>) ((ParameterizedType) superclass).getActualTypeArguments()[0];
            Method method = aClass.getDeclaredMethod("bind", View.class);
            mBinding = (T) method.invoke(null, v);

获取资源文件id
public abstract int getLayoutId();

RecyclerView 的adapter因为用的BQA,就没去研究怎么适配ViewBinding。


后记:

1.xml文件映射规则:
文件名映射后 首字母大写 下划线+小写会变成大写 其他不变 然后在最后加上Binding. 如 activity_main.xml将变为ActivityMainBinding
view id同上 但不会加Binding后缀,如 tv_text-> tvText

已知BUG

1.编译时如果有明显报错导致编译中断,后续改好了还是会一直报viewBinding有错误。
解决方法:Build->clear Project 然后重新run 或直接Rebuild Project

本文转自 blog.csdn.net/Dullyoung/a…,如有侵权,请联系删除。