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>

相当的经典

时间: 2024-08-03 09:44:18

java 中的 自定义viewUtils框架的相关文章

Java中的自定义数组队列

在Java中,作为所有数据结构中存储和获取速度最快的一种,数组凭借其这种简单易用的优势在各个方面都能大显神威.但是数组也有自身的局限性.数组的长度必须是固定的一旦定义之后就无法动态的更改,这就会造成这样的问题,如果数组已满,就无法继续添加数据(当然你可以定义一个"足够大的数组",但问题是多大才是足够大呢?太小不够,太大浪费内存空间).如果删除一个数据,它的内存空间空着没有被使用.另外数组只能存储同一类型的数据,如果把它设置成Object类型的话,是可以存不同类型的数据了,但是设想这样一

java中常见的rpc框架介绍

姓名:邓勇  班级:软件151 RPC是远程过程调用的简称,广泛应用在大规模分布式应用中,作用是有助于系统的垂直拆分,使系统更易拓展.Java中的RPC框架比较多,各有特色,广泛使用的有RMI.Hessian.Dubbo等.RPC还有一个特点就是能够跨语言,本文只以JAVA语言里的RPC为例. 其他的框架结构也类似,区别在于对象的序列化方法,传输对象的通讯协议,以及注册中心的管理与failover设计(利用zookeeper).客户端和服务端可以运行在不同的JVM中,Client只需要引入接口,

Java中泛型在集合框架中的应用

泛型是Java中的一个重要概念,上一篇文章我们说过,当元素存入集合时,集合会将元素转换为Object类型存储,当取出时也是按照Object取出的,所以用get方法取出时,我们会进行强制类型转换,并且通过代码也可以看出来,我们放入其他类型时,如字符串,编译器不会报错,但是运行程序时会抛出类型错误异常,这样给开发带来很多不方便,用泛型就解决了这个麻烦 泛型规定了某个集合只能存放特定类型的属性,当添加类型与规定不一致时,编译器会直接报错,可以清楚的看到错误 当我们从List中取出元素时直接取出即可,不

Java中的自定义注解

自定义注解的语法要求 定义自定义注解的关键字为@interface 成员以无参无异常方式声明,可以给成员指定一个默认值(default):成员的类型是受限制的,合法的类型有基本数据类型及String,Class,Annotation,Enumeration;如果注解只有一个成员,则必须取名为value(),使用时可以忽略成员名和"=" 注解类可以没有成员,此时称为标识注解 _________________________________________________________

JAVA中的Fork/Join框架

看了下Java Tutorials中的fork/join章节,整理下. 什么是fork/join框架 fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核处理器的优势,编写出并行执行的程序,提高应用程序的性能:设计的目的是为了处理那些可以被递归拆分的任务. fork/join框架与其它ExecutorService的实现类相似,会给线程池中的线程分发任务,不同之处在于它使用了工作窃取算法,所谓工作窃取,指的是对那些处理完自身任务的线程,会从其它线程窃

java中的类集框架

1.什么是类集框架 1.是一组类和接口 2.位于java.util包当中 3.主要用于用户存储和管理对象 4.主要分为三大类——集合.列表和映射 2.类集框架图 虚线框的表示接口,实线框的表示实现类 Collection接口中的主要方法 Iterator中的主要方法是hasnext()和next()方法 例子: 3.Map和HashMap的使用方法‘ 什么是映射 4.JDK帮助文档的使用方法

Java中常见的集合框架

1. 一.collection (有序)接口的实现的接口 set  list 其中set接口的实现类是HashSet,List接口的实现类是ArrayList.LinkList.Vector 二.Map(无序)接口的实现类是HashMap.HashTable ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synch

Java中常用的集合框架

BlockingQueue A线程可以知道b线程的存在 是一个接口并非一个具体实现: ArrayBlockingQueue ArrayBlockingQueue的内部元素都放置在一个对象数组中:final Object[] items; Offer():当队列已经满了,会立即返回false Put():如果队列满了会一直等待 Pool():弹出元素,如果为空返回null Take():弹出元素,如果为空等待到有元素即可. Take方法: public E take() throws Interr

Java中的APT的工作过程

Java中的APT的工作过程 APT即Annotatino Processing Tool, 他的作用是处理代码中的注解, 用来生成代码, 换句话说, 这是用代码生成代码的工具, 减少boilerplate代码. 我们通过一个简单的例子来简单APT的工作过程, 因为本文demo不设计ide及gradle等, 请注意包名及import问题. 根据上一篇博客Java中的自定义注解, 首先设计一个自定义注解MyAnnotation. package com.example; import java.l