一般情況下我們開發Android應用,初始化控件使用findViewById(),可是一個項目開發完畢,你會發現很多這樣的代碼,其實是重復的。這個時候你就會發現Java自帶的注釋(Annotation)是多麼的方便了。
一、設計一個ContentView的注釋
因為這個注釋我們要運在Activity類上,所以我們要申明@Targrt(ElementType.TYPE)。
[java]
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
-
- public @interface ContentView {
- value();
- }
二、設計一個ContentWidget的注釋
因為這個注釋我們要運在類的成員變量上,所以我們要申明@Targrt(ElementType.FILELD)。類成員變量指定我們申明的控件對象
[java]
- @Target(ElementType.FIELD)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface ContentWidget {
- int value();
- }
三、設計一個工具類來提取並處理上述自定義的Annotation類的信息
[java]
- public static void injectObject(Object object, Activity activity) {
-
- ClassclassType = object.getClass();
-
- // 該類是否存在ContentView類型的注解
- if (classType.isAnnotationPresent(ContentView.class)) {
- // 返回存在的ContentView類型的注解
- ContentView annotation = classType.getAnnotation(ContentView.class);
-
-
- try {
-
-
- // 返回一個 Method 對象,它反映此 Class 對象所表示的類或接口的指定公共成員方法。
- Method method = classType
- .getMethod(setContentView, int.class);
- method.setAccessible(true);
- int resId = annotation.value();
- method.invoke(object, resId);
-
-
- } catch (NoSuchMethodException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
-
- }
-
-
- // 返回 Field 對象的一個數組,這些對象反映此 Class 對象表示的類或接口聲明的成員變量,
- // 包括公共、保護、默認(包)訪問和私有成員變量,但不包括繼承的成員變量。
- Field[] fields = classType.getDeclaredFields();
-
-
- if (null != fields && fields.length > 0) {
-
-
- for (Field field : fields) {
- // 該成員變量是否存在ContentWidget類型的注解
- if (field.isAnnotationPresent(ContentWidget.class)) {
-
-
- ContentWidget annotation = field
- .getAnnotation(ContentWidget.class);
- int viewId = annotation.value();
- View view = activity.findViewById(viewId);
- if (null != view) {
- try {
- field.setAccessible(true);
- field.set(object, view);
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
-
- }
-
-
- }
-
-
- }
-
-
- }
四、在Activity類中我們該怎麼使用我們定義的注釋
[java]
- @ContentView(R.layout.activity_main)
- public class MainActivity extends Activity {
-
- @ContentWidget(R.id.tv)
- private TextView textView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // setContentView(R.layout.activity_main);
- ViewUtils.injectObject(this, this);
-
- textView.setText(自定義注釋);
- }
雖然前期准備的工作有點多,但後序我們的開發過程中對於加載布局和初始化控件會省事不少,這個對於大型項目來說,尤為重要,磨刀不誤砍材工!
DEMO 地址