【12】利用注解反射实现findViewById

(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)好好活就是做有意义的事情.
(8)亡羊补牢,为时未晚
(9)科技领域,没有捷径与投机取巧。
(10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。
(11)基础不牢,地动天摇
(12)写博客初心:成长自己,辅助他人。当某一天离开人世,希望博客中的思想还能帮人指引方向.
(13)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~

利用注解与反射实现findViewById的功能

1.实现思路

(1)定义注解,标记需要注入的控件
(2)通过反射解析控件的注解标记信息,通过解析注解信息取得id值
(3)通过id找到控件
(4)通过反射为控件赋值,即实例化控件

2.定义注解

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

/**
 * @author XiongJie
 * @version appVer
 * @Package com.gdc.javabase.annotation
 * @file
 * @Description:
 * @date 2020/9/8 15:10
 * @since appVer
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectView {
    @IdRes int value();
}

3.定义注解解析器

(1)通过反射解析注解信息,取得控件id值
(2)通过id找到控件
(3)通过反射为控件赋值,即实例化控件

public class InjectUtils {

    //s1.反射是基于CLASS
    public static void injectView(Activity activity) {
        Class<? extends Activity> cls = activity.getClass();

        //s1.获得此类所有的成员变量
        Field[] fields = cls.getDeclaredFields();

        //s2.遍历
        for (Field field : fields) {
            //s3.判断属性是否被InjetView注解声明
            boolean ret = field.isAnnotationPresent(InjectView.class); if (ret) {
                //s4.判断这个属性上有注解了,此时就还需要获取这个注解
                InjectView injectView = field.getAnnotation(InjectView.class);
                //s5.获取注解中设置的id值
                int id = injectView.value();

                View view = activity.findViewById(id);
                //s6.反射设置属性的值
                //s7.设置访问权限,允许操作私有成员private属性,
                field.setAccessible(true);

                //s8.设置(反射赋值)
                try {
                    field.set(activity, view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

4.测试

4.1Activity源码

/**
 * 利用反射与注解完成findViewById的功能
 */
public class MainActivity extends AppCompatActivity {

    @InjectView(R.id.tv)
    private TextView tv;

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

        InjectUtils.injectView(this);
        tv.setText("控件初始化成功!");
    }
}

4.2布局文件源码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

5.打赏鼓励

感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!

5.1微信打赏

在这里插入图片描述

5.2支付宝打赏

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值