java 中的 自定义viewUtils框架

在前面学习的基础上,我们自己编写一个ViewUtils注解框架类,不清楚的原理看前面的源代码

 

复制代码
package im.weiyuan.com.viewutils;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;



public class MainActivity extends AppCompatActivity {
    @ViewInject(R.id.tv_main_title)
    private TextView tv_main_title;
    private Button btn_main;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //这里一定要初始化注解
         ViewUtils.inject(this);
    }


    //login的参数必须是 View view
    @OnClick(R.id.btn_main)
    public  void login(View view ){
        Toast.makeText(MainActivity.this,"事件被点击了",Toast.LENGTH_LONG).show();
   }
}
复制代码

 

复制代码
package im.weiyuan.com.viewutils;

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

/**
 * Created by wei.yuan on 2017/7/21.
 */
//指定注解的声明周期
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnClick {
    int value(); 
}
复制代码
复制代码
package im.weiyuan.com.viewutils;

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

/**
 * Created by wei.yuan on 2017/7/21.
 */
//指定注解的声明周期
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface  ViewInject{
    int value(); //如果这里定义成id int id();用户在使用的时候必须写成     @ViewInject(id = R.id.tv_main_title),如果定义成int value();
    // 用户访问可以写成@ViewInject(R.id.tv_main_title)
}
复制代码
复制代码
package im.weiyuan.com.viewutils;

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

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

/**
 * Created by wei.yuan on 2017/7/21.
 */

public class ViewUtils {
    public  static  void inject(Activity activity){
               bindView(activity);
               bindBtn(activity);
    }


    /**
    * 对按钮进行操作
    * **/

    private static void bindBtn(final Activity activity) {
      Class clazz = activity.getClass();

        /**
         * 获得所有的方法
         * */
        Method[] methods = clazz.getDeclaredMethods();

        /***
         * 多所有的方法进行遍历
         * */
        for(final Method method:methods){
            /**
             * 看该方法上是否存在注解标签
             * */
            final OnClick annotation = method.getAnnotation(OnClick.class);
            if(annotation != null){
                /**
                 * 获得注解标签中的值 @OnClick(R.id.btn_main) ,这里的值就是 R.id.btn_main
                 * */
                int resId = annotation.value();

                /**
                 * 获得该对象
                 * */
                final View btnView = activity.findViewById(resId);

                /**
                 * 给view 绑定点击监听事件
                 * */

               btnView.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View v) {
                       /**
                        * 在点击事件之后执行反射的回调方法
                        * 匿名内部类访问当前函数的局部变量,局部变量声明为final类型
                        * */
                       method.setAccessible(true);
                       try {
                           method.invoke(activity,btnView);
                       } catch (IllegalAccessException e) {
                           e.printStackTrace();
                       } catch (InvocationTargetException e) {
                           e.printStackTrace();
                       }
                   }
               });

            }
        }
    }


    private   static  void bindView(Activity activity){
        //首先获得activity的所有字段,利用反射
        Class clazz = activity.getClass();
        //获得该字节码中的所有字段信息
        Field[] fields = clazz.getDeclaredFields();
        //对字段进行遍历,看给那些字段添加了注解的标签
        for(Field field :fields){
            ViewInject annotation = field.getAnnotation(ViewInject.class);
            if(annotation != null){
                /**
                 * 获得当中注解上的值
                 * */
                int resId = annotation.value();

                /**
                 * 通过activity 的findViewById获得当前的控件
                 * */
                View view = activity.findViewById(resId);

                /**
                 * 通过反射将view的值设置给当前的字段
                 * */
                field.setAccessible(true);

                /**
                 * 给activity的field字段赋值为view对象
                 * */

                try {
                    field.set(activity,view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
复制代码

xml文件:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="im.weiyuan.com.viewutils.MainActivity">

    <TextView
        android:id="@+id/tv_main_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

    <Button
        android:text="点击"
        android:id="@+id/btn_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
复制代码

相当的经典

posted on   luzhouxiaoshuai  阅读(177)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示