Android Butterknife终结者---ViewBin
2020-07-17 本文已影响0人
liys_android
一. 关于findViewById常用的方式, 只看java版
- 手写findViewById.
- 插件生成findViewById, 例如: FindViewByMe
- 注解的方式, 用反射解析, 例如:XUtils中的@ViewInject
- Butterknife, 这个应该是到目前为止, 大部分人使用的方案了.
- databinding, 主要的方向不在findViewById这个问题上, 所以也不好比较。
- ViewBinding, 只看findViewById的话, 应该是目前比较好的解决方案了.
二. ViewBinding认可度
我们先看看在 Butterknife的github地址上, 一开始就可以看到这样一段话(如下图):
大概意思是:Butterknife已经停止维护更新, 推荐我们使用ViewBinding.
连Butterknife的作者Jack大神都觉得ViewBinding比Butterknife更好用, 所以我觉得很有必要去了解一下.
二. ViewBinding基本使用
1. app/build.gradle下
android {
viewBinding {
enabled = true
}
}
2. Activity中
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.tvText.setText("测试");
}
}
三. BaseActivity的封装
关键点:利用泛型+反射获取Binding对象.
如果追求完美,不喜欢用反射,也可以子类重写getBinding()方法.
public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActivity {
T binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = getBinding();
setContentView(binding.getRoot());
init();
}
protected abstract void init();
protected T getBinding(){
try {
Type superClass = getClass().getGenericSuperclass();
Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
Class<?> clazz = ClassUtils.getRawType(type);
Method method = clazz.getMethod("inflate", LayoutInflater.class);
return (T) method.invoke(null, getLayoutInflater());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class MainActivity extends BaseActivity<ActivityMainBinding>{
@Override
protected void init() {
binding.tvText.setText("1234567890");
}
}
四. RecyclerView中的使用
关键点: ViewHolder对象维护一个Binding泛型对象就可以了. 具体Adapter怎么封装看个人了.
public class BaseViewHolder<T extends ViewBinding> extends RecyclerView.ViewHolder{
T viewbinding;
public BaseViewHolder(@NonNull T viewbinding) {
super(viewbinding.getRoot());
this.viewbinding = viewbinding;
}
}
五. 原理:
- 我们每个xml布局,都会生成对应的Binding类(如下图)
- xml文件里,只要有id命名的控件,都会在这里初始化, 生成一个public的成员变量
- 正因为是根据id自动生成的, 所以也就不存在View与id不匹配的错误.
- Binding类里面的代码都挺简单的, 这里就不贴出来了,太占篇幅了, 有兴趣的可以自己去看看.
补充说明:
- 如果某个xml文件不想使用ViewBinding, 怎么办? 在xml根布局添加 tools:viewBindingIgnore="true".
<LinearLayout
...
tools:viewBindingIgnore="true">
-
如果使用了DataBinding,就没必要用ViewBinding了,因为DataBinding也生成有对应Binding类,已经包含了ViewBinding的功能.
-
我们使用Butterknife的时候, OnClick也是自动生成,现在是要手写吗?
可以参考我上一篇文章OnClickMe一款自动生成OnClick代码的插件