注解小结--实例--findViewById和Click点击事件

最近来到一家新公司, 公司的项目用到了很多第三方框架, 比如Retrofit, ButterKnife, EventBus等等, 里面很多地方都用到了注解.现在项目上线了, 闲来无事, 也随手写一下类似于ButterKnife的功能, 就以findViewById和Onclick事件为内容, 利用注解实现其功能. 下面闲话少说, 上代码~~~~~~


首先创建一个关于findViewById的注解类. 基本形式@interface.

为了实现注解能够存活且在jvm中运行需要加上元注解@Retention(RetentionPolicy.RUNTIME).

package com.example.chanp.testannotation.annotation;

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

/**
 * Created by sjx on 2018/4/16.
 */

@Retention(RetentionPolicy.RUNTIME)
public @interface FindId {
    int value() default 0;
}

创建一个OnClick的注解类

package com.example.chanp.testannotation.annotation;

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

/**
 * Created by sjx on 2018/4/16.
 */

@Retention(RetentionPolicy.RUNTIME)
public @interface FindClick {
    int id() default 0;
}

测试用的Activity

package com.example.chanp.testannotation;

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

import com.example.chanp.testannotation.annotation.AnnotationHelper;
import com.example.chanp.testannotation.annotation.FindClick;
import com.example.chanp.testannotation.annotation.FindId;

/**
 * Created by sjx on 2018/4/16.
 */

public class TestActivity extends AppCompatActivity implements View.OnClickListener{

    @FindId(R.id.text_1)
    TextView text_1;
    @FindId(R.id.text_2)
    TextView text_2;

    TextView text_3;

    @FindClick(id=R.id.text_onclick)
    TextView text_onclick;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_test_annotation);

        AnnotationHelper.getInstance().init(this);

        if (text_1 != null){
            text_1.setText(this.getClass().getSimpleName()+" onCreate text_1");
        }

        if (text_2 != null){
            text_2.setText(this.getClass().getSimpleName()+" onCreate text_2");
        }

    }

    public void onClick(View view){
        switch (view.getId()){
            case R.id.text_onclick:
                Toast.makeText(this, "text_onclick Onclick...", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

xml:

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

    <TextView
        android:id="@+id/text_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="22dip"
        android:textSize="20sp"/>

    <TextView
        android:id="@+id/text_2"
        android:layout_marginTop="20dip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/text_3"
        android:layout_marginTop="20dip"
        android:text="text_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/text_onclick"
        android:layout_marginTop="20dip"
        android:text="Onclick"
        android:padding="10dip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

下面就是注解的读取, 注解提取和处理, 是给编译器和APT(Annotation Processing Tool)用的.

下面就是利用反射读取值,并且赋值的过程.

package com.example.chanp.testannotation.annotation;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.View;

import java.lang.reflect.Field;

/**
 * Created by sjx on 2018/4/16.
 */

public class AnnotationHelper {
    private static final String TAG = "AnnotationHelper";
    private static class InstanceHelper{
        public static final AnnotationHelper instance = new AnnotationHelper();
    }

    public static AnnotationHelper getInstance(){
        return InstanceHelper.instance;
    }

    public void init(Activity ctx){
        Class clzz = ctx.getClass();
        Field[] fields = clzz.getDeclaredFields();
        for (Field field : fields){
            field.setAccessible(true);

            if (field.isAnnotationPresent(FindId.class)){ //参数
                FindId findId = field.getAnnotation(FindId.class);
                Log.i(TAG, "field name : " + field.getName() + "   value : " + findId.value());

                try {
                    field.set(ctx, ctx.findViewById(findId.value()));

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

            if (field.isAnnotationPresent(FindClick.class)){
                FindClick findClick = field.getAnnotation(FindClick.class);
                try {
                    Log.i(TAG, "field name : " + field.getName() + "   value : " + findClick.id());
                    View view = ctx.findViewById(findClick.id());
                    view.setOnClickListener((View.OnClickListener) ctx);
                    field.set(ctx, view);


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

        }
    }
}

然后赋值和点击事件就出来了~

效果图:

   


随手一写, Mark一下.

阅读更多
上一篇Android 引用完整工程包括Activity和资源文件
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭