android 巧妙利用反射机制获取控件id,避免大量冗杂的findviewbyid和butterknife注解

一、反射机制概述
Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为 Java 的反射机制。

Class 类与 java.lang.reflect 类库一起对反射的概念进行了支持,该类库包含了 Field,Method,Constructor 类 (每个类都实现了 Member 接口)。这些类型的对象时由 JVM 在运行时创建的,用以表示未知类里对应的成员。

这样你就可以使用 Constructor 创建新的对象,用 get() 和 set() 方法读取和修改与 Field 对象关联的字段,用 invoke() 方法调用与 Method 对象关联的方法。另外,还可以调用 getFields() getMethods() 和 getConstructors() 等很便利的方法,以返回表示字段,方法,以及构造器的对象的数组。这样匿名对象的信息就能在运行时被完全确定下来,而在编译时不需要知道任何事情。

简单无脑直接上代码。

package com.example.zsh.reflect_idtest;import android.app.Activity;
import android.content.res.Resources;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;import java.lang.reflect.Field;
import java.lang.reflect.Method;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button mbtn_ok;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);smartInject();}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.mbtn_ok:Toast.makeText(this, "dsadxsa", Toast.LENGTH_SHORT).show();break;}}/*** 使用java反射机制* 设置Activity不用findViewbyid*/private void smartInject() {try {Class<? extends Activity> clz = getClass();while (clz != BaseActivity.class) {Field[] fs = clz.getDeclaredFields();Resources res = getResources();String packageName = getPackageName();for (Field field : fs) {if (!View.class.isAssignableFrom(field.getType())) {continue;}int viewId = res.getIdentifier(field.getName(), "id", packageName);if (viewId == 0)continue;field.setAccessible(true);try {View v = findViewById(viewId);field.set(this, v);Class<?> c = field.getType();Method m = c.getMethod("setOnClickListener", View.OnClickListener.class);m.invoke(v, this);} catch (Throwable e) {}field.setAccessible(false);}clz = (Class<? extends Activity>) clz.getSuperclass();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/mbtn_ok"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Hello World!" /></LinearLayout>

这里需要注意的是 布局文件ID 和 全局变量声明的ID还有 onClick的ID要一致,否则无法获取到点击事件,这或许是利用反射避免findviewbyid的一种弊端吧。

android 巧妙利用反射机制获取控件id,避免大量冗杂的findviewbyid和butterknife注解相关推荐

  1. C# 利用反射机制开启控件双缓存

    /// <summary> /// 设置控件的双缓存 /// </summary> /// <param name="c">所需设置双缓存的控件 ...

  2. 利用反射机制获取未知类型的枚举的信息

    原文:利用反射机制获取未知类型的枚举的信息 开发游戏设置选项遇到一个问题,我有两个枚举,一个是屏幕分辨率,一个是语言 我需要在不知道一个枚举到底是哪一个枚举类型的情况下,获取这个枚举的值以及这个枚举类 ...

  3. Android开发之Android Studio 3.6新特性之获取控件id的高级方式ViewBinding

    一般获取id有如下几种方式: 访问布局控件ID方式 优点 缺点 findViewById 系统提供有保障 特别繁琐代码量大 第三方注解 快捷简单 引用三方可能有不确定因素 kotlinx.androi ...

  4. android 获取控件 id 工具,如何使用appium desktop 获取Android APP 控件的id

    背景: 随着Android 版本的更新,你会发现我们之前用的最新的版本的Appium 1.5.3无法启动我们的 Android APP 在模拟器为7.0的设备上,所以我们有必要了解如何使用 appiu ...

  5. Android 在onCreate()方法中获取控件宽高值为0解决方案

    大家很多时候需要在Activity或者Fragment的onCreate()方法中获取声明的空间的高度或者宽度,进行位置移动或者其他操作,但是当调用 view.getHeight() 或者 view. ...

  6. 页面JS获取不到控件ID

    为了使页面更加的友好,我们不可避免的要在页面上使用JS,所以在页面上使用javascript获取控件ID是很常见的事情.但是最近在使用JS的使用,遇到了一件让我很头疼的事情,在获取控件ID时,抱错了, ...

  7. android利用反射调用截屏api,Android利用反射机制调用截屏方法和获取屏幕宽高的方法...

    想要在应用中进行截屏,可以直接调用 View 的 getDrawingCache 方法,但是这个方法截图的话是没有状态栏的,想要整屏截图就要自己来实现了. 还有一个方法可以调用系统隐藏的 screen ...

  8. Android在OnCreate中获取控件的宽度和高度

    在Android中,有时需要对控件进行测量,得到的控件宽度和高度可以用来做一些计算.在需要自适应屏幕的情况下,这种计算就显得特别重要.另一方便,由于需求的原因,希望一进入界面后,就能得到控件的宽度和高 ...

  9. Android如何在onCreate()方法中获取控件的高度和宽度

    在Android中,有时我们需要测量控件的宽度和高度进行一些运算,特别是在自适应屏幕的时候,这些计算就变得特别必要,但是,如果我们直接在onCreate,或者onStart.onResume(第一次执 ...

最新文章

  1. R语言创建频数表和列联表
  2. 如何计算递归算法的时间复杂度
  3. 一些机器学习数据集(Dataset)
  4. 剑指offer之把字符串里面空格替换成百分之20[时间复杂度是O(n)]
  5. Java语言跨平台性质的优点和缺点_机器人热门编程语言及优缺点分析
  6. 【机器学习-西瓜书】四、决策树:信息熵;信息增益;增益率;ID3;C4.5
  7. phprpc的简单使用
  8. qt调用SSDP协议
  9. android会员充值功能,微信会员卡充值功能怎么开通?
  10. hive支持update、delete
  11. 开源项目ruoyi-springboot-vue源码分析之LogAspect日志打印
  12. Android设备的电池续航时间优化(Optimizing Battery Life)——(一)监听电池电量和电池的充电状态
  13. phpstudy安装和使用
  14. 耳机不分主从是什么意思_音质出色,降噪服众,千元机档位王者南卡A1主动降噪耳机深度评测...
  15. h0206. 区间选点
  16. a java rnvironme_分析113个前缀在各大考纲词汇中的作用(一)
  17. java 泛型 type_轻触开源(一)-Java泛型Type类型的应用和实践
  18. 7.论文学习Multi-phase Liver Tumor Segmentation with Spatial Aggregation and Uncertain Region Inpainting
  19. 如何判断域名的潜力和价值?
  20. 华兴资本业绩预增三倍:IPO首日破发后,历经两年半重回发行价

热门文章

  1. 「Matlab」“矩阵对矩阵求导的方法”讲解
  2. [记录]hololens导出时报错 缺少命名空间“Windows.Devices.Haptics”
  3. 用Linux+IPChains代替Windows+WinGate
  4. 牛视系统源码定制开发come here,抖音矩阵系统。
  5. C++的成员函数声明与定义 —— 类外定义成员函数以及inline函数
  6. 百余名人辞世,刚过去的2016是被诅咒的一年吗?MIT数据分析预测这只是个开始……...
  7. 《信息学奥赛》1354:括弧匹配检验
  8. 基于WTK6900H语音识别芯片在智能语音识别晾衣架的应用设计方案介绍
  9. 和数集团董事长唐毅先生受邀出席“文旅产业与数字艺术新形态”高峰文化论坛
  10. webpack开发配置API代理解决跨域问题-devServer