</pre><pre name="code" class="java">
public @interface AutoView {
/**
* UI主键的id,不填写自动识别名称
* @return
*/
int value() default -1;
}
这个是注解接口
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoVIewForClass {
/**
* 需要注解的UI组件的class数组
* @return
*/
Class[] value();
}
这个是第二个注解
上面两个注解第一个是放在属性上,第二个是放在类上的。做用是一样的。
下面是实现注入的类。
public class SetAutoView {
/**
* 针对AutoView注解
* 需要在setContentView()之后执行
* 自动注入AutoView对象的UI对象
* @param t 继承自Acitvity 可直接填写this
*/
public static <T extends Activity> void antoView(T t){
Class c = t.getClass();
Field[] fields = c.getDeclaredFields();
try {
for (Field f : fields) {
AutoView av = f.getAnnotation(AutoView.class);
if (av != null) {
Class type = f.getClass();
f.setAccessible(true);
int id = av.value()!= -1 ? av.value():getId(f.getName());
if(id == -1){
throw new Exception("R.id下没有找到资源:"+f.getName());
}
f.set(t,t.findViewById(id));
}
}
} catch (Exception e) {
Log.e("SetAutoView", e.getMessage());
e.printStackTrace();
}
}
/**
* 针对AutoView注解
* 需要在setContentView()之后执行
* 自动注入AutoView对象的UI对象
* @param t 继承自View 可直接填写this
*/
public static <T extends Object,V extends View> void antoView(T t,V v){
Class c = t.getClass();
Field[] fields = c.getDeclaredFields();
try {
for (Field f : fields) {
AutoView av = f.getAnnotation(AutoView.class);
if (av != null) {
Class type = f.getClass();
f.setAccessible(true);
int id = av.value()!= -1 ? av.value():getId(f.getName());
if(id == -1){
throw new Exception("R.id下没有找到资源:"+f.getName());
}
f.set(t,v.findViewById(id));
}
}
} catch (Exception e) {
Log.e("SetAutoView", e.getMessage());
e.printStackTrace();
}
}
/**
* 根据名称获取R.id下的id值
* @param name
* @return 错误返回0
*/
public static int getId(String name){
Class c = R.id.class;
try {
Field f = c.getField(name);
int i = (Integer) f.get(c);
return i;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
/**
* 针对AutoVIewForClass注解
* 需要在setContentView()之后执行
* 自动注入AutoVIewForClass注解类下的参数类中对应对象的UI对象
* 处理类上注解 注解参数数组为需要注入的类型
* @param t 继承自Acitvity
*/
public static <T extends Activity> void antoViewForClass(T t){
AutoVIewForClass avc = t.getClass().getAnnotation(AutoVIewForClass.class);
if(avc == null){
return ;
}
Class c = t.getClass();
Field[] fields = c.getDeclaredFields();
try {
for (Field f : fields) {
if(Arrays.asList(avc.value()).contains(f.getType())){
int id = getId(f.getName());
if(id == -1){
throw new Exception("R.id下没有找到资源:"+f.getName());
}
f.setAccessible(true);
f.set(t,t.findViewById(id));
}
}
} catch (Exception e) {
Log.e("SetAutoView", e.getMessage());
e.printStackTrace();
}
}
/**
* 针对AutoVIewForClass注解
* 需要在setContentView()之后执行
* 自动注入AutoVIewForClass注解类下的参数类中对应对象的UI对象
* 处理类上注解 注解参数数组为需要注入的类型
* @param t 继承自View
*/
public static <T extends Object,V extends View> void antoViewForClass(T t,V v){
AutoVIewForClass avc = t.getClass().getAnnotation(AutoVIewForClass.class);
if(avc == null){
return ;
}
Class c = t.getClass();
Field[] fields = c.getDeclaredFields();
try {
for (Field f : fields) {
if(Arrays.asList(avc.value()).contains(f.getType())){
int id = getId(f.getName());
if(id == -1){
throw new Exception("R.id下没有找到资源:"+f.getName());
}
f.setAccessible(true);
f.set(t,v.findViewById(id));
}
}
} catch (Exception e) {
Log.e("SetAutoView", e.getMessage());
e.printStackTrace();
}
}
}
这个类新手写的可能部太全面。
下面是使用
@AutoVIewForClass({ ActionProcessButton.class, EditText.class })
public class AtyLogin extends BaseActivity {
private EditText etLoginUsername;
private EditText etLoginPassword;
private ActionProcessButton btnLogin;
private String username;
private String password;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aty_login);
SetAutoView.antoViewForClass(this);
initView();
overridePendingTransition(R.anim.in_pop, R.anim.out_pop);
}
上面是类上的使用,在setContentView之后可以执行SetAutoView.antoViewForClass(thsi)方法会自动注入注解参数中的相应类型,(属性名称需要与xml中id相同)
第二种使用方式
public class FragmentHistory extends BaseFragment<AtyShowInfo> implements OnTouchListener , OnGestureListener{
private View view ;
private Info info;
private TableLayout tl;
@AutoView
private ScrollView svHistory;
@AutoView
private HorizontalScrollView hsvHistory;
private GestureDetector detector;
public class FragmentNotApprove extends BaseFragment<AtyShowList> implements OnGestureListener,OnTouchListener, OnRefreshListener2<ListView>{
private View view ;
@AutoView(R.id.lvNotApprove)
private PullToRefreshListView lv;
注入方法
public void initView(){
view = View.inflate(activity, R.layout.frag_notapprove, null);
// lv = (ListView) view.findViewById(R.id.lvNotApprove);
SetAutoView.antoView(this, view);
lv.setOnRefreshListener(this);
这个是属性上面的注解,注解与xml的id不同名可以赋值形式传入进去如第二个示例。然后一样在设置fragment的设置view后执行相应的SetAutoView.antoView(this, view);方法
写的很槽,但可以自己实现简单view注入,有空在补上其他注入。