Android 中的 IOC 框架 【ViewInject】


要实现的目标结果如下 :


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

    @ViewInject(R.id.id_btn)
    private Button mBtn1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ViewUtil.inject(this);

1、定义注解

首先我们需要两个注解文件:

1.1

package com.zhy.ioc.view.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();
}

ContentView用于在类上使用,主要用于标明该Activity需要使用的布局文件

@ContentView(value = R.layout.activity_main)
public class MainActivity

1.2
package com.zhy.ioc.view.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();
}

在成员变量上使用,用于指定View的Id

@ViewInject(R.id.id_btn)
	private Button mBtn1;

此两个注解定义,需分别写在两个类文件上

ContentView.java
ViewInject.java

2、MainActivity

package com.example.administrator.camera;

import android.app.Activity;
import android.jni.ContentView;
import android.jni.ViewInject;
import android.jni.ViewUtil;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

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

    @ViewInject(R.id.id_btn)
    private Button mBtn1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ViewUtil.inject(this);
        
//        mBtn1.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                Toast.makeText(MainActivity.this, "how old are you ?", Toast.LENGTH_SHORT).show();
//            }
//        });
        mBtn1.setOnClickListener(this);
    }

    public void onClick(View v)
    {
        switch (v.getId())
        {
            case R.id.id_btn:
                Toast.makeText(MainActivity.this, "Why do you click me ?",
                        Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

注解都写好了,核心的代码就是 
ViewUtil.inject(this);
 

ViewUtil.inject(this);


ViewUtil.java

如下:

package android.jni;

import android.app.Activity;
import android.util.Log;

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

/**
 * Created by Administrator on 2017-11-20.
 */

/**
 * 核心控制类
 *
 * @author leilu
 *
 */
public class ViewUtil {

    public static void inject(Activity activity)
    {

        injectContentView(activity);
        injectViews(activity);

    }



    private static final String METHOD_SET_CONTENTVIEW = "setContentView";
    /**
     * 注入主布局文件
     *
     * @param activity
     */
    private static void injectContentView(Activity activity)
    {
        Class<? extends Activity> clazz = activity.getClass();
        // 查询类上是否存在ContentView注解
        ContentView contentView = clazz.getAnnotation(ContentView.class);
        if (contentView != null)// 存在
        {
            int contentViewLayoutId = contentView.value();
            try
            {
                Method method = clazz.getMethod(METHOD_SET_CONTENTVIEW,
                        int.class);
                method.setAccessible(true);
                method.invoke(activity, contentViewLayoutId);
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }



    private static final String METHOD_FIND_VIEW_BY_ID = "findViewById";
    /**
     * 注入所有的控件
     *
     * @param activity
     */
    private static void injectViews(Activity activity)
    {
        Class<? extends Activity> clazz = activity.getClass();
        Field[] fields = clazz.getDeclaredFields();
        // 遍历所有成员变量
        for (Field field : fields)
        {

            ViewInject viewInjectAnnotation = field
                    .getAnnotation(ViewInject.class);
            if (viewInjectAnnotation != null)
            {
                int viewId = viewInjectAnnotation.value();
                if (viewId != -1)
                {
                    Log.e("TAG", viewId+"");
                    // 初始化View
                    try
                    {
                        Method method = clazz.getMethod(METHOD_FIND_VIEW_BY_ID,
                                int.class);
                        Object resView = method.invoke(activity, viewId);
                        field.setAccessible(true);
                        field.set(activity, resView);
                    } catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

参考文献:http://android.jobbole.com/81051/

                  http://android.jobbole.com/81053/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值