Ioc依赖注入,使你的项目告别findViewById

本文介绍了一种在Android开发中使用的视图注入技术,通过自定义注解和反射机制实现UI组件的自动绑定及事件监听。该方法简化了代码编写过程,提高了开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MainActivity

package test.dbing.com.ioctest;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import test.dbing.com.ioctest.ioc.IocView;

public class MainActivity extends BaseActivity {

    @IocView(id = R.id.main_name_bt,click="btnClick",longClick = "longClk")Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void btnClick(View v){
        Toast.makeText(MainActivity.this,"click",Toast.LENGTH_LONG).show();
    }

    public void longClk(View v){
        Toast.makeText(MainActivity.this,"longClk",Toast.LENGTH_LONG).show();
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/main_name_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>

BaseActivity

import android.app.Activity;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import java.lang.reflect.Field;
import test.dbing.com.ioctest.ioc.IocEventListener;
import test.dbing.com.ioctest.ioc.IocSelect;
import test.dbing.com.ioctest.ioc.IocView;

public class BaseActivity extends Activity {

    @Override
    public void setContentView(int layoutResID) {
        super.setContentView(layoutResID);
        initIocView();
    }

    @Override
    public void setContentView(View view) {
        super.setContentView(view);
        initIocView();
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        super.setContentView(view, params);
    }

    public void initIocView(){
        Field[] fields = getClass().getDeclaredFields();
        if(fields!=null && fields.length>0){
            for(Field field : fields){
                try {
                    field.setAccessible(true);

                    if(field.get(this)!= null )
                        continue;

                    IocView viewInject = field.getAnnotation(IocView.class);
                    if(viewInject!=null){

                        int viewId = viewInject.id();
                        field.set(this,findViewById(viewId));

                        setListener(field,viewInject.click(), IocEventListener.CLICK);
                        setListener(field,viewInject.longClick(), IocEventListener.LONGCLICK);
                        setListener(field,viewInject.itemClick(), IocEventListener.ITEMCLICK);
                        setListener(field,viewInject.itemLongClick(), IocEventListener.ITEMLONGCLICK);

                        IocSelect select = viewInject.select();
                        if(!TextUtils.isEmpty(select.selected())){
                            setViewSelectListener(field,select.selected(),select.noSelected());
                        }

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

    /**
     * 设置view的监听器.
     *
     * @param field the field
     * @param methodName the method name
     * @param method the method
     * @throws Exception the exception
     */
    private void setListener(Field field,String methodName,int method)throws Exception{
        if(methodName == null || methodName.trim().length() == 0)
            return;

        Object obj = field.get(this);

        switch (method) {
            case IocEventListener.CLICK:
                if(obj instanceof View){
                    ((View)obj).setOnClickListener(new IocEventListener(this).click(methodName));
                }
                break;
            case IocEventListener.ITEMCLICK:
                if(obj instanceof AbsListView){
                    ((AbsListView)obj).setOnItemClickListener(new IocEventListener(this).itemClick(methodName));
                }
                break;
            case IocEventListener.LONGCLICK:
                if(obj instanceof View){
                    ((View)obj).setOnLongClickListener(new IocEventListener(this).longClick(methodName));
                }
                break;
            case IocEventListener.ITEMLONGCLICK:
                if(obj instanceof AbsListView){
                    ((AbsListView)obj).setOnItemLongClickListener(new IocEventListener(this).itemLongClick(methodName));
                }
                break;
            default:
                break;
        }
    }

    /**
     * 设置view的监听器.
     *
     * @param field the field
     * @param select the select
     * @param noSelect the no select
     * @throws Exception the exception
     */
    private void setViewSelectListener(Field field,String select,String noSelect)throws Exception{
        Object obj = field.get(this);
        if(obj instanceof View){
            ((AbsListView)obj).setOnItemSelectedListener(new IocEventListener(this).select(select).noSelect(noSelect));
        }
    }
}

将下面三个类copy到你的项目中即可

IocEventListener

import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;

import java.lang.reflect.Method;

public class IocEventListener implements OnClickListener, OnLongClickListener, OnItemClickListener, OnItemSelectedListener,OnItemLongClickListener {

    /** The handler. */
    private Object handler;

    /** The click method. */
    private String clickMethod;

    /** The long click method. */
    private String longClickMethod;

    /** The item click method. */
    private String itemClickMethod;

    /** The item select method. */
    private String itemSelectMethod;

    /** The nothing selected method. */
    private String nothingSelectedMethod;

    /** The item long click mehtod. */
    private String itemLongClickMehtod;

    /**
     * Instantiates a new ab ioc event listener.
     *
     * @param handler the handler
     */
    public IocEventListener(Object handler) {
        this.handler = handler;
    }

    /**
     * Click.
     *
     * @param method the method
     * @return the ab ioc event listener
     */
    public IocEventListener click(String method){
        this.clickMethod = method;
        return this;
    }

    /**
     * Long click.
     *
     * @param method the method
     * @return the ioc event listener
     */
    public IocEventListener longClick(String method){
        this.longClickMethod = method;
        return this;
    }

    /**
     * Item long click.
     *
     * @param method the method
     * @return the ioc event listener
     */
    public IocEventListener itemLongClick(String method){
        this.itemLongClickMehtod = method;
        return this;
    }

    /**
     * Item click.
     *
     * @param method the method
     * @return the ioc event listener
     */
    public IocEventListener itemClick(String method){
        this.itemClickMethod = method;
        return this;
    }

    /**
     * Select.
     *
     * @param method the method
     * @return the ioc event listener
     */
    public IocEventListener select(String method){
        this.itemSelectMethod = method;
        return this;
    }

    /**
     * No select.
     *
     * @param method the method
     * @return the ioc event listener
     */
    public IocEventListener noSelect(String method){
        this.nothingSelectedMethod = method;
        return this;
    }

    public boolean onLongClick(View v) {
        return invokeLongClickMethod(handler,longClickMethod,v);
    }

    public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
        return invokeItemLongClickMethod(handler,itemLongClickMehtod,arg0,arg1,arg2,arg3);
    }

    public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

        invokeItemSelectMethod(handler,itemSelectMethod,arg0,arg1,arg2,arg3);
    }

    public void onNothingSelected(AdapterView<?> arg0) {
        invokeNoSelectMethod(handler,nothingSelectedMethod,arg0);
    }

    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

        invokeItemClickMethod(handler,itemClickMethod,arg0,arg1,arg2,arg3);
    }

    public void onClick(View v) {

        invokeClickMethod(handler, clickMethod, v);
    }


    /**
     * Invoke click method.
     *
     * @param handler the handler
     * @param methodName the method name
     * @param params the params
     * @return the object
     */
    private Object invokeClickMethod(Object handler, String methodName,  Object... params){
        if(handler == null) return null;
        Method method = null;
        try{   
            method = handler.getClass().getDeclaredMethod(methodName,View.class);
            if(method!=null)
                return method.invoke(handler, params);  
            else
                throw new Exception("no such method:"+methodName);
        }catch(Exception e){
            e.printStackTrace();
        }

        return null;

    }


    /**
     * Invoke long click method.
     *
     * @param handler the handler
     * @param methodName the method name
     * @param params the params
     * @return true, if successful
     */
    private boolean invokeLongClickMethod(Object handler, String methodName,  Object... params){
        if(handler == null) return false;
        Method method = null;
        try{   
            //public boolean onLongClick(View v)
            method = handler.getClass().getDeclaredMethod(methodName,View.class);
            if(method!=null){
                Object obj = method.invoke(handler, params);
                return obj==null?false:Boolean.valueOf(obj.toString()); 
            }
            else
                throw new Exception("no such method:"+methodName);
        }catch(Exception e){
            e.printStackTrace();
        }

        return false;

    }

    /**
     * Invoke item click method.
     *
     * @param handler the handler
     * @param methodName the method name
     * @param params the params
     * @return the object
     */
    private Object invokeItemClickMethod(Object handler, String methodName,  Object... params){
        if(handler == null) return null;
        Method method = null;
        try{   
            ///onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
            method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class,View.class,int.class,long.class);
            if(method!=null)
                return method.invoke(handler, params);  
            else
                throw new Exception("no such method:"+methodName);
        }catch(Exception e){
            e.printStackTrace();
        }

        return null;
    }


    /**
     * Invoke item long click method.
     *
     * @param handler the handler
     * @param methodName the method name
     * @param params the params
     * @return true, if successful
     */
    private boolean invokeItemLongClickMethod(Object handler, String methodName,  Object... params){

        Method method = null;
        try{   
            if(handler == null){
                throw new Exception("invokeItemLongClickMethod: handler is null :");
            }
            ///onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,long arg3)
            method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class,View.class,int.class,long.class);
            if(method!=null){
                Object obj = method.invoke(handler, params);
                return Boolean.valueOf(obj==null?false:Boolean.valueOf(obj.toString()));    
            }
            else
                throw new Exception("no such method:"+methodName);
        }catch(Exception e){
            e.printStackTrace();
        }

        return false;
    }


    /**
     * Invoke item select method.
     *
     * @param handler the handler
     * @param methodName the method name
     * @param params the params
     * @return the object
     */
    private Object invokeItemSelectMethod(Object handler, String methodName,  Object... params){
        if(handler == null) return null;
        Method method = null;
        try{   
            ///onItemSelected(AdapterView<?> arg0, View arg1, int arg2,long arg3)
            method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class,View.class,int.class,long.class);
            if(method!=null)
                return method.invoke(handler, params);  
            else
                throw new Exception("no such method:"+methodName);
        }catch(Exception e){
            e.printStackTrace();
        }

        return null;
    }

    /**
     * Invoke no select method.
     *
     * @param handler the handler
     * @param methodName the method name
     * @param params the params
     * @return the object
     */
    private Object invokeNoSelectMethod(Object handler, String methodName,  Object... params){
        if(handler == null) return null;
        Method method = null;
        try{   
            //onNothingSelected(AdapterView<?> arg0)
            method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class);
            if(method!=null)
                return method.invoke(handler, params);  
            else
                throw new Exception("no such method:"+methodName);
        }catch(Exception e){
            e.printStackTrace();
        }

        return null;
    }

}

IocSelect

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

/**
 * The Interface IocSelect.
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) 
public @interface IocSelect {

    /**
     * Selected.
     *
     * @return the string
     */
    public String selected();

    /**
     * No selected.
     *
     * @return the string
     */
    public String noSelected() default "";

}

IocView

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

/**
 * The Interface IocView.
 */
/*
    @Retention用来声明注解的保留策略,
    有CLASS、RUNTIME和SOURCE这三种,
    分别表示注解保存在类文件、JVM运行时刻和源代码中只有当声明为RUNTIME的时候,
    才能够在运行时刻通过反射API来获取到注解的信息。
    @Target用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) 
public @interface IocView {

    /**
     * Id.
     *
     * @return the int
     */
    public int id();

    /**
     * Click.
     *
     * @return the string
     */
    public String click() default "";

    /**
     * Long click.
     *
     * @return the string
     */
    public String longClick() default "";

    /**
     * Item click.
     *
     * @return the string
     */
    public String itemClick() default "";

    /**
     * Item long click.
     *
     * @return the string
     */
    public String itemLongClick() default "";

    /**
     * Select.
     *
     * @return the ab ioc select
     */
    public IocSelect select() default @IocSelect(selected="") ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉辰56

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值