Android开发学习之路-让注解帮你简化代码,彻底抛弃findViewById

本文主要是记录注解的使用的学习笔记,如有错误请提出。

在通常的情况下,我们在Activity中有一个View,我们要获得这个View的实例是要通过findViewById这个方法,然后这个方法返回的是一个Object类型,我们还需要进行强制的类型转换,但是相信很多人都遇到过,当我们的一个布局中有很多个控件的时候,每一个控件都要进行上面的这个操作其实是很烦躁的,特别是强制类型转换,即使是用Alt+Enter,多按几次都累了。而今天要用的是通过注解的方式来简化这一个复杂的步骤,在我们编写好相应的代码之后,获取实例的方法就变成像下面这样简单了

@ViewInject(R.id.buy)
private Button buy;

通过上面这两行简单的代码,就能把id所对应的View实例化了,下面我们一步一步的来学习如何使用注解。

先说原理,我们都要知道,在Java中,通过反射,我们可以知道每一个类的详细信息,比如有什么字段,有什么方法,类名等等,我们通过注解和反射配合,使用反射调用类中的方法,然后读取注解的参数来进行方法的执行。简单的说,就是其实我们还是会调用findViewById这个方法,但是,这个方法可以放到工具类中执行了,我们只需要像上面那样给出参数就行了。

先说下反射,反射就是允许我们动态的操作一个类,获取类的字段,执行类的方法,获取类的名字等等,在这里我们一般会用到下面的这几个方法:

getMethod:获取类中的public方法

getDeclaredMethod:获取类中的所有方法

getField:获取类中的public字段(属性)

getDeclaredField:获取类中的所有字段

还有其他的请自行参考Class类的源码

 

再说注解,我们看到的最多的注解获取是@Override,当我们重写父类中的方法的时候,这个注解会被编译器自动生成出来,这个注解只是表明方法是重写了父类方法。

那么我们究竟该如何自定义我们想要的注解呢?其实很简单,直接看代码:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface  ViewInject{
    int value();
}

@Target的意思是我们注解作用的目标,这里是ElementType.FIELD,也就是作用于字段的

 ElementType的类型有以下几种:

   1.CONSTRUCTOR:用于描述构造器
 2.FIELD:用于描述字段
 3.LOCAL_VARIABLE:用于描述局部变量
 4.METHOD:用于描述方法
 5.PACKAGE:用于描述包
 6.PARAMETER:用于描述参数
 7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention的意思是注解的运行级别

  RetentionPolicy的类型有以下几种

   1.SOURCE:在源文件中有效(即源文件保留)
 2.CLASS:在class文件中有效(即class保留)
 3.RUNTIME:在运行时有效(即运行时保留)

@interface则是表明这个类是一个注解,@号不能漏掉,否则变成了接口了

如果想对注解了解得更多,可以参考:http://www.cnblogs.com/gmq-sh/p/4798194.html 这篇博文,很详细,对于我们想要的功能,以上的内容就足够了

定义好了注解,如果我们直接来使用,是没有任何效果的,因为注解只是一段代码,并没有关联上我们的控件,所以我们要编写一个工具类来做关联

public class AnnotateUtils {
    public static void injectViews(Activity activity) {
        Class<? extends Activity> object = activity.getClass(); // 获取activity的Class
        Field[] fields = object.getDeclaredFields(); // 通过Class获取activity的所有字段
        for (Field field : fields) { // 遍历所有字段
            // 获取字段的注解,如果没有ViewInject注解,则返回null
            ViewInject viewInject = field.getAnnotation(ViewInject.class); 
            if (viewInject != null) {
                int viewId = viewInject.value(); // 获取字段注解的参数,这就是我们传进去控件Id
                if (viewId != -1) {
                    try {
                        // 获取类中的findViewById方法,参数为int
                        Method method = object.getMethod("findViewById", int.class);
                        // 执行该方法,返回一个Object类型的View实例
                        Object resView = method.invoke(activity, viewId);
                        field.setAccessible(true);
                        // 把字段的值设置为该View的实例
                        field.set(activity, resView);
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

在工具类中,我们获取到了activity的Class,接着获得类中的所有字段,遍历字段,如果有ViewInject注解,则获取注解的中的值,通过获取并执行类中的方法(findViewById)来获得对应View的实例,最后把实例赋值给当前的字段,整个过程就完成了。

当我们需要使用注解的时候,我们只需要在定义View的时候,在View的字段上添加对应的注解,把Id传入,然后在onCreate方法中调用上面这个工具类的方法即可。

@ViewInject(R.id.buy)
private Button buy;
@ViewInject(R.id.money)
private TextView money;
@ViewInject(R.id.tv_power)
private TextView power;
@ViewInject(R.id.tv_life)
private TextView life;
@ViewInject(R.id.tv_dex)
private TextView dex;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    AnnotateUtils.injectViews(this);
}

 

最后,有几点说明:

①如果注解中的值不是value,那么在进行注解是时候,需要给出对应的值的名字,假如我们在注解中做了如下定义:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface  ViewInject{
    int id();
}

那么在注解的时候,需要这样:

@ViewInject(id = R.id.buy)
private Button buy;

因为value这个名字是默认的,如果我们定义为value,那么注解的时候可以省略

②注解还可以帮我们注入布局,设置监听等,如果有兴趣,可以继续探讨下去

③使用注解的时候,句末不能加“;”

 

转载于:https://www.cnblogs.com/Fndroid/p/5354644.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在Android应用程序中使用bga-qrcode-zbar库,可以按照以下步骤进行操作: 1. 在项目根目录的build.gradle文件中添加以下代码: ``` allprojects { repositories { maven { url 'https://jitpack.io' } } } ``` 2. 在app模块的build.gradle文件中添加以下依赖项: ``` dependencies { implementation 'com.github.yipianfengye:zbar:1.9.8' implementation 'cn.bingoogolapple:bga-qrcode-zbar:1.2.6' } ``` 3. 在代码中使用BGAQRCodeUtil类来生成和扫描二维码。例如,以下代码将生成一个包含指定字符串的二维码并显示在ImageView中: ``` String content = "https://www.example.com"; ImageView imageView = findViewById(R.id.image_view); BGAQRCodeUtil.setImageViewQRCodeWithLogo(this, imageView, content, BitmapFactory.decodeResource(getResources(), R.drawable.logo)); ``` 希望这可以助你成功使用bga-qrcode-zbar库。 ### 回答2: 要在Android中使用bga-qrcode-zbar库,首先需要在项目的build.gradle文件中添加以下依赖项: ``` dependencies { implementation 'cn.bingoogolapple:bga-qrcode-zbar:latestVersion' } ``` 然后,在需要使用二维码扫描的Activity中,先在布局文件中添加一个SurfaceView,用于显示相机预览,并在代码中初始化和使用扫描功能。 1. 在布局文件中添加SurfaceView: ```xml <SurfaceView android:id="@+id/sv_qrcode" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在Activity中进行初始化和使用: ```java public class QRCodeScanActivity extends AppCompatActivity implements BGAQRCodeUtil.Delegate { private SurfaceView mSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_qrcode_scan); mSurfaceView = findViewById(R.id.sv_qrcode); // 初始化扫描工具类 BGAQRCodeUtil.setDelegate(this); } @Override protected void onResume() { super.onResume(); // 打开相机并进行预览 BGAQRCodeUtil.onResume(this); } @Override protected void onPause() { super.onPause(); // 关闭相机预览并释放资源 BGAQRCodeUtil.onPause(this); } @Override protected void onDestroy() { super.onDestroy(); // 释放资源 BGAQRCodeUtil.onDestroy(this); } // 扫描结果回调 @Override public void onScanQRCodeSuccess(String result) { // 扫描成功后的处理逻辑 } // 扫描出错回调 @Override public void onScanQRCodeOpenCameraError() { // 打开相机出错的处理逻辑 } } ``` 这样,你就可以在Android应用中使用bga-qrcode-zbar库提供的功能了。记得在AndroidManifest.xml中添加相机权限:`<uses-permission android:name="android.permission.CAMERA" />`。 ### 回答3: 在Android中引用bga-qrcode-zbar的代码需要按照以下步骤进行操作: 1. 首先,在项目的build.gradle文件中的dependencies中添加以下代码依赖: ``` implementation 'cn.bingoogolapple:bga-qrcode-zbar:2.2.8' implementation 'cn.bingoogolapple:bga-qrcode-core:2.2.8' ``` 2. 然后,在布局文件的合适位置添加BGAQRCodeCaptureView控件,例如: ``` <cn.bingoogolapple.qrcode.zbar.ZBarView android:id="@+id/zbarview" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 3. 在Activity或Fragment中,找到控件并初始化: ``` private ZBarView mZBarView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mZBarView = findViewById(R.id.zbarview); } @Override protected void onResume() { super.onResume(); mZBarView.startCamera(); mZBarView.startSpot(); } @Override protected void onPause() { super.onPause(); mZBarView.stopCamera(); } @Override protected void onDestroy() { super.onDestroy(); mZBarView.onDestroy(); } ``` 4. 最后,在AndroidManifest.xml文件中添加摄像头的权限: ``` <uses-permission android:name="android.permission.CAMERA" /> ``` 现在你可以在Android应用中使用bga-qrcode-zbar库了,它提供了扫描二维码的功能。为了更好的体验,在使用该库之前,你需要检查设备是否有摄像头,并且在需要的时候请求相机权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值