Android Kotlin使用注解和反射实现View绑定以及点击事件

前言

本文主要练习Kotlin中自定义注解以及反射的使用,加深注解和反射的印象,废话不多说,直接上代码;

相关实现

  • 自定义BindView以及OnClick注解(注意:使用java反射,需要使用AnnotationTarget.FIELD,同时保留源码到运行时)
  1. BindView
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
annotation class BindView(val value: Int)
  1. OnClick
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class OnClick(vararg val value: Int)
  • 新增注入工具类InjectUtils,实现注入后自动绑定View以及注册点击事件;
package com.crystal.view.annotation

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

/**
* 实现findViewById以及setOnClickListener功能
* on 2022/11/16
*/
class InjectUtils {

   companion object {
       /**
        * 绑定activity/fragment/view
        */
       fun bind(target: Activity) {
           findViewById(target)
           setOnClickListener(target)
       }


       private fun findViewById(target: Activity) {
           val clazz = target.javaClass
           //获取target中定义的所有属性
           val declaredFields = clazz.declaredFields
           for (field in declaredFields) {
               //获取对应的BindView注解
               val bindViewAnnotation = field.getAnnotation(BindView::class.java)
               if (bindViewAnnotation != null) {
                   field.isAccessible = true
                   //获取对应的value值
                   val value = bindViewAnnotation.value
                   val targetView = target.findViewById<View>(value)
                   field.set(target, targetView)
               }

           }
       }


       /**
        * 实现view.setOnClickListener方法
        */
       private fun setOnClickListener(target: Activity) {
           val clazz = target.javaClass
           //获取target中定义的所有方法
           val declaredMethods = clazz.declaredMethods
           for (method in declaredMethods) {
               method.isAccessible = true
               //获取对应的onClick注解
               val onClickAnnotation = method.getAnnotation(OnClick::class.java)
               if (onClickAnnotation != null) {
                   //获取对应的value数组
                   val values = onClickAnnotation.value
                   for (value in values) {
                       val targetView = target.findViewById<View>(value)
                       targetView.setOnClickListener {
                           method.invoke(target, targetView)
                       }
                   }

               }

           }
       }

   }


}

测试验证

/**
 * on 2022/10/20
 */
class MainActivity : AppCompatActivity() {
    @BindView(R.id.tv)
    private var tv: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        InjectUtils.bind(this)
        tv!!.text = "AAaaaaaaaaaaaaaa"
    }

    @OnClick(R.id.tv,R.id.tv)
    private fun onClick(view: View) {
        Toast.makeText(this, "Send Message for you", Toast.LENGTH_LONG).show()
    }

}

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值