Android通过注解来初始化控件

时间:2022-02-05 16:35:49

Android通过注解来初始化控件

     对于Android大神的思想与能力我只能膜拜与学习了,这里就从大神哪里学来的通过注解来初始化控件简单的概述一下,省去了那么繁琐的findViewById步骤(找到了还要强转,真心醉了)。

原理

   原理是在Activity加载好后通过找到Activity中使用注解的字段,再通过Java反射的方式,动态的给这个字段设置值。

一、定义注解类ViewId.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Created 2015/9/7 Administrator tianzhao
 */
// 表示用在字段上
@Target(ElementType.FIELD)
// 表示是在声明周期运行的
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewId {
	int value() default 0;
}
二、定义BaseActivity.java基础类,在这个类中解析注解类
import android.app.Activity;
import android.os.Bundle;
import java.lang.reflect.Field;

public abstract class BaseActivity extends Activity {

	/**
	 * 返回布局的ID
	 */
	public abstract int getLayoutId();
	/**
	 * 初始化
	 */
	public abstract void init();
	/**
	 * 设置监听
	 */
	public abstract void setListener();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(getLayoutId());
		autoInjectAllField();
		init();
		setListener();
	}

	public void autoInjectAllField() {
		try {
			Class<?> clazz = this.getClass();
			Field[] fields = clazz.getDeclaredFields();// 获得Activity中声明的字段
			for (Field field : fields) {
				// 查看这个字段是否有我们自定义的注解类标志的
				if (field.isAnnotationPresent(ViewId.class)) {
					ViewId inject = field.getAnnotation(ViewId.class);
					int id = inject.value();
					if (id > 0) {
						field.setAccessible(true);
						field.set(this, this.findViewById(id));// 给我们要找的字段设置值
					}
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}
	}
}
三、最后就是MainActivity.java了
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends BaseActivity {

	@ViewId(R.id.tv)
	private TextView tv;

	@ViewId(R.id.bt)
	private Button bt;

	/**
	 * 处理一些在onCreate里处理的事情
	 */
	@Override
	public void init() {

	}

	@Override
	public void setListener() {
		tv.setText("TextView注解成功");
		bt.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				tv.setText("Button注解成功");
			}
		});
	}

	@Override
	public int getLayoutId() {
		return R.layout.activity_main;
	}

}
    OK,就是这么简单,通过java的反射机制简化了多少代码,提高了多少开发效率。不过貌似这种方式会对效率有点影响。