android 教您打造属于自己的注解(@interface) 优雅与便捷并行(二)

      昨天介绍了一下在activity中初始化控件用注解的方式实现。其实注解就是利用的java反射机制在编译好的class文件字节码通过放射获取到的。但是这只是activity中,在android 任何一个类中需要绑定view需要初始化控件怎么办呢。所以这时候就需要动动脑筋了。想想就把activity 换成Object不就行了吗?废话少说,代码敲起来。

package com.jxust.eddie.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {

	int value();
	int parentId() default 0;
}


跟上篇文章一样。定义了一个注解类。

package com.jxust.eddie.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
	
	int value();
}

 

今儿又稍稍加了另外一个注解,需要注意的是@Target元注解的类型是ElmentType.TYPE。表明本人定义的是一个类注解,比如struts2中的@controller。

 

下面写了一个辅助类ViewFinder。

package com.jxust.eddie.annotation;

import android.app.Activity;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
import android.view.View;

/**
 * Author: Eddie
 */
public class ViewFinder {

    private View view;
    private Activity activity;
    public ViewFinder(View view) {
        this.view = view;
    }

    public ViewFinder(Activity activity) {
        this.activity = activity;
    }

    public View findViewById(int id) {
        return activity == null ? view.findViewById(id) : activity.findViewById(id);
    }

    public View findViewById(int id, int pid) {
        View pView = null;
        if (pid > 0) {
            pView = this.findViewById(pid);
        }

        View view = null;
        if (pView != null) {
            view = pView.findViewById(id);
        } else {
            view = this.findViewById(id);
        }
        return view;
    }
}

下面最重要的环节就要出现了,那就是注解解析了。

package com.jxust.eddie.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import android.app.Activity;
import android.view.View;

/**
 * 
 * @author Eddie
 * 
 */
public class ViewUtils {

	public static void inject(Object handler,View view) {
		injectObject(handler, new ViewFinder(view));
	}

	public static void inject(Activity activity) {
		injectObject(activity, new ViewFinder(activity));
	}

	/**
	 * 我的理解是java反射机制中获取类handlerType中的方法
	 * @author Eddie
	 * @param String name 这个是方法名
	 * @param Class<?> parameterType 这个是方法对应的参数类型
	 * @description  
	 */
 public static void injectObject(Object handler, ViewFinder finder) {
		Class<?> handlerType = handler.getClass();
		//实现类注解 绑定view
		ContentView contentView = handlerType.getAnnotation(ContentView.class);
		if (contentView != null) {
			try {
			Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
			setContentViewMethod.invoke(handler, contentView.value());
			} catch (Throwable e) {
		}
	}

		Field[] fields = handlerType.getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				ViewInject viewInject = field.getAnnotation(ViewInject.class);
				if (viewInject != null) {
					try {
						View view = finder.findViewById(viewInject.value(),
								viewInject.parentId());
						if (view != null) {
							field.setAccessible(true);
							field.set(handler, view);
						}
					} catch (Throwable e) {
					}
				}
			}
		}
	}
}


好了,注解介绍完了。开用。

import java.util.ArrayList;
import java.util.List;

import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import com.jxust.eddie.adapter.MainFragmentAdapter;
import com.jxust.eddie.annotation.ContentView;
import com.jxust.eddie.annotation.ViewInject;
import com.jxust.eddie.annotation.ViewUtils;
import com.jxust.eddie.redtourism.fragment.FindFragment;
import com.jxust.eddie.redtourism.fragment.HomeFragment;
import com.jxust.eddie.redtourism.fragment.MeFragment;
import com.jxust.eddie.redtourism.fragment.TripFragment;

@ContentView(R.layout.activity_main)
public class MainActivity extends BaseActivity implements OnClickListener{

	private static final String TAG = "MainActivity";
	private static final int FOOT_HOME = 0;
	private static final int FOOT_TRIP = 1;
	private static final int FOOT_FIND = 2;
	private static final int FOOT_ME = 3;
	@ViewInject(R.id.id_viewpager)
	private ViewPager mViewPager;
		@Override
	public void initView() {
		ViewUtils.inject(this);



 

你可能感兴趣的:(android 教您打造属于自己的注解(@interface) 优雅与便捷并行(二))