描述

现阶段代替findViewById

引入使用

启用

1
2
3
4
5
6
7
8
9
android {
...
viewBinding {
//开启视图绑定,用来替代findViewById
//官方文档:https://developer.android.com/topic/libraries/view-binding
enabled = true
}
}

然后 onCreate里面就可以这样:

1
2
3
4
5
6
7
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivitySplashBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
//setContentView(R.layout.activity_splash);
}

然后想要那个带 id 的控件,就不用再 findViewById 了。

直接 binding.id

封装

ViewModelActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import android.os.Bundle;

import androidx.viewbinding.ViewBinding;

import com.example.superutils.reflect.ReflectUtil;

/**
* 通用ViewModel Activity
* 包括ViewBinding,主要是处理每次要setContentView
*/
public class BaseViewModelActivity<VB extends ViewBinding> extends BaseLogicActivity{
protected VB binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//调用inflate方法,创建viewBinding
binding = ReflectUtil.newViewBinding(getLayoutInflater(),this.getClass());
setContentView(binding.getRoot());
}
}

反射方法类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import android.view.LayoutInflater;

import androidx.viewbinding.ViewBinding;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

/**
* 反射工具类
*/
public class ReflectUtil {
/**
* 创建view binding
*/
public static <VB extends ViewBinding> VB newViewBinding(LayoutInflater layoutInflater, Class<?> clazz) {
try {
//获取泛型参数对象
ParameterizedType type;
try {
type = (ParameterizedType) clazz.getGenericSuperclass();
} catch (ClassCastException e) {
type = (ParameterizedType) clazz.getSuperclass().getGenericSuperclass();
}

//type.actualTypeArguments[0]:ViewBinding
Class<VB> clazzVB = (Class<VB>) type.getActualTypeArguments()[0];

//获取inflate方法
Method inflateMethod = clazzVB.getMethod("inflate", LayoutInflater.class);

return (VB) inflateMethod.invoke(null, layoutInflater);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}

融合

想要用ViewBinding的直接继承自这个类,然后后面泛型写好对应的类型。

1
public class SplashActivity extends BaseViewModelActivity<ActivitySplashBinding> {

然后那个 onCreate 就可以全部删了

Fragment

BaseViewModelDialogFragment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.viewbinding.ViewBinding;

import com.example.superutils.reflect.ReflectUtil;

public abstract class BaseViewModelDialogFragment<VB extends ViewBinding> extends BaseDialogFragment{
protected VB binding;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//调用inflate方法,创建viewBinding
binding = ReflectUtil.newViewBinding(getLayoutInflater(),this.getClass());
}

@Override
protected View getLayoutView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return binding.getRoot();
}

@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

使用

1
public class TermServiceDialogFragment extends BaseViewModelDialogFragment<FragmentDialogTermServiceBinding> {

然后就一样用了

同时要特别注意。如果使用的 Fragment 中有 getLayoutView方法。

记得去掉。