android findviewbyid的简单注解实现

</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注入,有空在补上其他注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值