自定义butterknife
butterknife是一个View的注入框架,而我要说的是我自己写的自定义butterknife,我一般用着初始化控件和一些点击事件,当然也可以用在一些方法中,看自己了。不过其中也用到了反射和android的注解。
1.想要实现初始化控件时,创建Java文件时,不要选择Class,而是Annotation
2.初始化控件的类
package com.example.android6;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 运行时的注解
* */
@Retention(RetentionPolicy.RUNTIME)
/*
* 要是初始化控件的话,Target中要写FIELD,代表控件
* */
@Target(ElementType.FIELD)
public @interface InjectView {
/*
* 在此说明一下,这里的ID不是一个方法,而是一个格式
* */
int ID();
}
3.初始化点击事件,也可以相当于方法
package com.example.custom_butterknife;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 运行时的注解
* */
@Retention(RetentionPolicy.RUNTIME)
/*
* 要是初始化方法的话,Target中要写METHOD,代表方法
* */
@Target(ElementType.METHOD)
public @interface OnClick {
/*
* 在此说明一下,这里的ID不是一个方法,而是一个格式
* */
int value();
}
4.注解的工具类,中其中用反射写初始化控件和方法
package com.example.android6;
import android.app.Activity;
import android.view.View;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ViewUtils {
public static void bind(Activity activity){
/*
* 注解控件的方法
* */
bindFeild(activity);
/*
* 注解方法的方法
* */
bindOnClick(activity);
}
private static void bindOnClick(Activity activity) {
/*
* 反射
* */
final Class<? extends Activity> aClass = activity.getClass();
//得到所有方法,无论私有还是公有
Method[] methods = aClass.getDeclaredMethods();
for (final Method method : methods) {
OnClick onClick = method.getAnnotation(OnClick.class);
if (onClick != null){
int value = onClick.value();
//找到方法中的控件
View view = activity.findViewById(value);
//暴力访问
method.setAccessible(true);
//控件的点击事件
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
method.invoke(activity);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
});
}
}
}
private static void bindFeild(Activity activity) {
/*
* 发射
* */
Class<? extends Activity> aClass = activity.getClass();
//找到控件,无论私有还是公有
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
InjectView annotation = field.getAnnotation(InjectView.class);
if (annotation != null){
int id = annotation.ID();
//找到控件
View view = activity.findViewById(id);
//暴力方法
field.setAccessible(true);
try {
field.set(activity,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
5.最后是Activity了
/*
*第一种是控件
*/
public class MainActivity extends AppCompatActivity {
@InjectView(ID = R.id.btn_one)
Button btn_one;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.bind(this);
btn_one.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "你写的是初始化控件", Toast.LENGTH_SHORT).show();
}
});
}
}
/*
*第二种是方法
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.bind(this);
}
@OnClick(value = R.id.btn_one)
private void onClick(){
Toast.makeText(this, "你写的是初始化方法", Toast.LENGTH_SHORT).show();
}
}