Android View事件绑定工具 @Bind @OnClick

非常讨厌android事件绑定和findViewById()代码太繁琐。今天在阅读代码的时候看见,网上有类似的控件。可是我又不想下。于是乎就随手写了个。平时写个Demo用还行。用于项目可能会有bug。毕竟只是我简单的封装。后续可能会优化
@OnClick 和 @Bind 和 核心代码处理类。这些使用者不需要关心。下面会有使用方法。

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnClick {
    int value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Bind {
    int value();
}
import android.app.Activity;
import android.util.Log;
import android.view.View;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class EventUtils {
    private static String TAG = "EventUtils";
    private static Map<Integer, View> bindMap = new HashMap<>();

    public static void bind(Activity activity) {

        try {
            final Class<? extends Activity> aClass = activity.getClass();
            initBindField(activity, aClass, activity);
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(OnClick.class)) {
                    if (!method.getGenericReturnType().equals(Void.TYPE)) {
                        Log.e(TAG, "The return value class must be void");
                        return;
                    }
                    int value = method.getAnnotation(OnClick.class).value();
                    if (bindMap.containsKey(value)) {
                        View view = bindMap.get(value);
                        bindOnClickEvent(activity, method, view);
                    } else {
                        View view = activity.findViewById(value);
                        bindOnClickEvent(activity, method, view);
                    }

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void bindOnClickEvent(final Activity instance, final Method method, View view) {
        if (!method.isAccessible()) {
            method.setAccessible(true);
        }
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes != null && parameterTypes.length > 0 && parameterTypes[0].equals(View.class)) {
                    invoke(method, instance, v);
                } else {
                    invoke(method, instance);
                }
            }
        });
    }

    private static void initBindField(Activity activity, Class<? extends Activity> aClass, Activity instance) throws IllegalAccessException {
        for (Field field : aClass.getDeclaredFields()) {
            if (field.isAnnotationPresent(Bind.class)) {
                int value = field.getAnnotation(Bind.class).value();
                if (View.class.isAssignableFrom(field.getType())) {
                    if (!field.isAccessible()) {
                        field.setAccessible(true);
                    }
                    View view = activity.findViewById(value);
                    field.set(instance, view);
                    bindMap.put(value, view);
                }
            }
        }
    }

    private static Object invoke(Method method, Object instance, Object... args) {
        if (!method.isAccessible()) {
            method.setAccessible(true);
        }
        try {
            return method.invoke(instance, args);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

}

使用方法:

 @Bind(R.id.result)
 private TextView textView;

 @OnClick(R.id.clearBtn)
 public void click(View v) {}

 //View参数可选。
 //@Bind @OnClick 可以任意使用其中一个,也可以同时使用。
 //下面是最重要的一步。

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //注意:初始化下绑定
        EventUtils.bind(this);
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值