我们结合反射和注解技术,做一个简单的工具类,自动帮我们findViewById。
ButterKnift早期就是这样做的。
首先我们看使用方式
public class MainActivity extends AppCompatActivity {
@InjectView(R.id.tv)
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtil.injectView(MainActivity.this);
// 工具类自动帮我们findViewById了
// tv = findViewById(R.id.tv);
}
}
首先用注解@InjectView标注MainActivity的成员变量TextView,并传入资源id。
然后在onCreate方法调用InjectUtil的injectView方法。
因为工具类InjectUtil自动帮我们findViewById,所以我们不用手写findViewById了。
我们来看@InjectView注解
// 因为要结合反射技术,所以保留到运行时
@Retention(RetentionPolicy.RUNTIME)
// 注解作用于成员变量
@Target(ElementType.FIELD)
public @interface InjectView {
// 传入资源id
@IdRes int value();
}
再来看工具类injectView
public class InjectUtil {
public static void injectView(Activity activity) {
// 反射是基于Class的
// 首先获取Activity的class
Class<? extends Activity> aClass = activity.getClass();
// 获取Activity的所有成员变量
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
// 如果这个成员变量被注解InjectView标注了
if (field.isAnnotationPresent(InjectView.class)) {
// 获取这个成员变量的InjectView注解
InjectView annotation = field.getAnnotation(InjectView.class);
// 获取传入的id值
int id = annotation.value();
//接下来我们findViewById,并赋值给这个成员变量
View view = activity.findViewById(id);
// 设置允许访问
field.setAccessible(true);
try {
field.set(activity,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
享学课堂