热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android注解使用之ButterKnife8.0详解

这篇文章主要为大家详细介绍了Android注解使用之ButterKnife8.0的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

前言:

     App项目开发大部分时候还是以UI页面为主,这时我们需要调用大量的findViewById以及setOnClickListener等代码,控件的少的时候我们还能接受,控件多起来有时候就会有一种想砸键盘的冲动。所以这个时候我们想着可以借助注解的方式让我们从这种繁重的工作中脱离出来,也让代码变得更加简洁,便于维护,今天主要学习一下只专注View、Resource、Action注解框架ButterKnife。

ButterKnife介绍

    ButterKnife是一个专注于Android系统的View、Resource、Action注入框架。

    官网:http://jakewharton.github.io/butterknife/

    gitHub:https://github.com/JakeWharton/butterknife/

ButterKnife使用前后对比:

    看看没有使用View注解之前我们是如何做的

1.)使用之前

public class ExampleActivity extends AppCompatActivity {
 private final static String TAG = ExampleActivity.class.getSimpleName();
 String butterKnifeStr;
 Drawable butterKnifeDrawable;
 Button butterKnifeBtn;
 ImageView butterKnifeIv;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_butter_knife);
  initResource();
  initViews();
 }

 private void initViews() {
  butterKnifeBtn = (Button) findViewById(R.id.btn_butter_knife);
  butterKnifeBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    Log.e(TAG, "onButterKnifeBtnClick");
   }
  });
  butterKnifeIv = (ImageView) findViewById(R.id.iv_butter_knife);
  butterKnifeBtn.setText(butterKnifeStr);
  butterKnifeIv.setImageDrawable(butterKnifeDrawable);
 }

 private void initResource() {
  butterKnifeStr = getString(R.string.title_btn_butter_knife);
  butterKnifeDrawable = getDrawable(R.mipmap.ic_launcher);
 }
}

2.)使用之后

public class ButterKnifeActivity extends AppCompatActivity {
 private final static String TAG = ButterKnifeActivity.class.getSimpleName();
 private Unbinder unbinder;
 @BindString(R.string.title_btn_butter_knife)
 String butterKnifeStr;
 @BindDrawable(R.mipmap.ic_launcher)
 Drawable butterKnifeDrawable;
 @BindView(R.id.btn_butter_knife)
 Button butterKnifeBtn;
 @BindView(R.id.iv_butter_knife)
 ImageView butterKnifeIv;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_butter_knife);
  unbinder = ButterKnife.bind(this);
  initViews();
 }

 private void initViews() {
  butterKnifeBtn.setText(butterKnifeStr);
  butterKnifeIv.setImageDrawable(butterKnifeDrawable);
 }

 @OnClick(R.id.btn_butter_knife)
 public void onButterKnifeBtnClick(View view) {
  Log.e(TAG, "onButterKnifeBtnClick");
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  unbinder.unbind();
 }
}

3.)ButterKnife 优势

通过上面使用前后对比来分析下ButterKnife优势

  • 强大的View绑定和Click事件处理功能,简化代码,提升开发效率
  • 方便的处理Adapter里的ViewHolder绑定问题
  • 运行时不会影响APP效率,使用配置方便
  • 代码清晰,可读性强

使用前后对比之后有没有觉得非常的简单易用。接下来来看下具体怎么使用的?

ButterKnife如何使用:

1).在Project的build.gradle中添加如下配置

buildscript {
 repositories {
 mavenCentral()
 }
 dependencies {
 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
 }
}

2.)在Module的build.gradle添加如下配置

apply plugin: 'com.neenbedankt.android-apt'

android {
 ...
}

dependencies {
 compile 'com.jakewharton:butterknife:8.1.0'
 apt 'com.jakewharton:butterknife-compiler:8.1.0'
}

3.)注入和重置注入

Activity

class ExampleActivity extends Activity {
 @BindView(R.id.title) TextView title;
 @BindView(R.id.subtitle) TextView subtitle;
 @BindView(R.id.footer) TextView footer;

 @Override public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.simple_activity);
 ButterKnife.bind(this);
 // TODO Use fields...
 }
}

Fragment:由于不同的视图生命周期,所以需要在onCreateView bind,在onDestroyView unbind

public class FancyFragment extends Fragment {
 @BindView(R.id.button1) Button button1;
 @BindView(R.id.button2) Button button2;
 private Unbinder unbinder;

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 View view = inflater.inflate(R.layout.fancy_fragment, container, false);
 unbinder = ButterKnife.bind(this, view);
 // TODO Use fields...
 return view;
 }

 @Override public void onDestroyView() {
 super.onDestroyView();
 unbinder.unbind();
 }
}

ViewHolder

public class MyAdapter extends BaseAdapter {
 @Override public View getView(int position, View view, ViewGroup parent) {
 ViewHolder holder;
 if (view != null) {
  holder = (ViewHolder) view.getTag();
 } else {
  view = inflater.inflate(R.layout.whatever, parent, false);
  holder = new ViewHolder(view);
  view.setTag(holder);
 }

 holder.name.setText("John Doe");
 // etc...

 return view;
 }

 static class ViewHolder {
 @BindView(R.id.title) TextView name;
 @BindView(R.id.job_title) TextView jobTitle;

 public ViewHolder(View view) {
  ButterKnife.bind(this, view);
 }
 }
}

4.)view注入 @BindView,@BindViews

@BindView(R.id.btn_butter_knife)
Button butterKnifeBtn;
@BindViews({R.id.tv_butter_knife1,R.id.tv_butter_knife2,R.id.tv_butter_knife3})
List textViews;


5.)Resource注入

@BindString(R.string.title_btn_butter_knife)
 String butterKnifeStr;//string注解使用
 @BindDrawable(R.mipmap.ic_launcher)
 Drawable butterKnifeDrawable;//Drawable注解使用
 @BindBitmap(R.mipmap.ic_launcher)
 Bitmap butterKnifeBitmap;;//Bitmap注解使用
 @BindArray(R.array.day_of_week)
 String weeks[];//数组
 @BindColor(R.color.colorPrimary)
 int colorPrimary;//color注解使用
 @BindDimen(R.dimen.activity_horizontal_margin)
 Float spacer;

6).单事件注入

一个控件指定一个事件回调

 /**
  * 带参数
  */
 @OnClick(R.id.btn_butter_knife)
 public void onButterKnifeBtnClick() {
 }

 /**
  * 带参数
  */
 @OnClick(R.id.btn_butter_knife)
 public void onButterKnifeBtnClick(View view) {
  Log.e(TAG, "onButterKnifeBtnClick");
 }

 /**
  * 带参数
  * @param button
  */
 @OnClick(R.id.btn_butter_knife)
 public void onButterKnifeBtnClick(Button button) {
  Log.e(TAG, "onButterKnifeBtnClick");
 }

也可以多个控件指定一个事件回调

 /**
  * 两个不同的button都相应onButterKnifeBtnClick事件回调
  *
  * @param button
  */
 @OnClick({R.id.btn_butter_knife, R.id.btn_butter_knife1})
 public void onButterKnifeBtnClick(Button button) {
  Log.e(TAG, "onButterKnifeBtnClick");
 }

自定义的控件不通过ID也可以绑定到自己的事件

public class FancyButton extends Button {
 @OnClick
 public void onClick() {
 // TODO do something!
 }
}

7.)多事件回调

有一些View的listener是有多个回调方法的,比如EditText添加addTextChangedListener

 editText.addTextChangedListener(new TextWatcher() {
   @Override
   public void beforeTextChanged(CharSequence s, int start, int count, int after) {

   }

   @Override
   public void onTextChanged(CharSequence s, int start, int before, int count) {

   }

   @Override
   public void afterTextChanged(Editable s) {

   }
  });

可以使用注解方式改成如下

 @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
 void beforeTextChanged(CharSequence s, int start, int count, int after) {

 }
 @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
 void onTextChanged(CharSequence s, int start, int before, int count) {

 }
 @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
 void afterTextChanged(Editable s) {

 }

8.)选择性注入

默认情况下,@Bind 和listener的注入都是必须的,如果target view没有被发现,则会报错. 为了抑制这种行为,可以用@Optional注解来标记field和方法,让注入变成选择性的,如果targetView存在,则注入, 不存在,则什么事情都不做.或者使用 Android's "support-annotations" library.中的@Nullable来修饰

@Nullable @BindView(R.id.might_not_be_there)
TextView mightNotBeThere;

@Optional @OnClick(R.id.maybe_missing) 
void onMaybeMissingClicked() {
 // TODO ...
}

9.)ButterKnife.apply()函数

可以通过ButterKnifeapply()函数对view集合元素或者单个view的Action, Setter和Property进行修改

ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);

static final ButterKnife.Action DISABLE = new ButterKnife.Action() {
 @Override public void apply(View view, int index) {
 view.setEnabled(false);
 }
};
static final ButterKnife.Setter ENABLED = new ButterKnife.Setter() {
 @Override public void set(View view, Boolean value, int index) {
 view.setEnabled(value);
 }
};

ButterKnife.apply(nameViews, View.ALPHA, 0.0f);

10.)ButterKnife.findById()

ButterKnife 也提供了findById函数,通过findById()可以获取Activity、Dialog、View中的view,并且是泛型类型不需要强转

View view = LayoutInflater.from(context).inflate(R.layout.thing, null);
TextView firstName = ButterKnife.findById(view, R.id.first_name);
TextView lastName = ButterKnife.findById(view, R.id.last_name);
ImageView photo = ButterKnife.findById(view, R.id.photo);

ButterKnife自动生成插件安装:

在AndroidStudio->File->Settings->Plugins->搜索Zelezny下载添加就行 ,可以快速生成对应组件的实例对象,不用手动写。使用时,在要导入注解的Activity 或 Fragment 或 ViewHolder的layout资源代码上,右键——>Generate——Generate ButterKnife Injections,然后就出现如图的选择框。

 插件gitHub地址:https://github.com/avast/android-butterknife-zelezny

 上面给了一个使用流程图,不过流程图不会针对最新的8.0.1版本的,但是都是差不多的

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • ABP框架是ASP.NET Boilerplate的简称,它不仅是一个开源且文档丰富的应用程序框架,还提供了一套基于领域驱动设计(DDD)的最佳实践架构模型。本文将详细介绍ABP框架的特点、项目结构及其在Web API优先架构中的应用。 ... [详细]
  • 本文分享了作者在不同版本的Ubuntu系统上尝试编译VLC for Android的经历,包括遇到的技术难题及解决方案,旨在帮助开发者避免常见的编译问题。 ... [详细]
  • 本文介绍了 LaiFengcode 在 GitHub 上的两个主要开源项目:SopCastComponent 和 iOS 相关组件。 ... [详细]
  • 在Effective Java第三版中,建议在方法返回类型中优先考虑使用Collection而非Stream,以提高代码的灵活性和兼容性。 ... [详细]
  • 协程作为一种并发设计模式,能有效简化Android平台上的异步代码处理。自Kotlin 1.3版本引入协程以来,这一特性基于其他语言的成熟理念,为开发者提供了新的工具,以增强应用的响应性和效率。 ... [详细]
  • 探讨密码安全的重要性
    近期,多家知名网站如CSDN、人人网、多玩、开心网等的数据库相继被泄露,其中大量用户的账户密码因明文存储而暴露无遗。本文将探讨黑客获取密码的常见手段,网站如何安全存储用户信息,以及用户应如何保护自己的密码。 ... [详细]
  • 在Ubuntu 18.04上使用Nginx搭建RTMP流媒体服务器
    本文详细介绍了如何在Ubuntu 18.04上使用Nginx和nginx-rtmp-module模块搭建RTMP流媒体服务器,包括环境搭建、配置文件修改和推流拉流操作。适用于需要搭建流媒体服务器的技术人员。 ... [详细]
  • GreenPlum采纳ShareNothing的架构,良好的施展了便宜PC的作用。自此IO不在是DW(datawarehouse)的瓶颈,相同网络的压力会大很多。然而GreenPlum的查问优化策略可能防止尽量少的网络替换。对于首次接触GreenPlum的人来说,必定耳目一新。 ... [详细]
  • 本文介绍了三种解决 Git Push 冲突的方法,包括创建新分支、手动解决冲突和强行推送。这些方法适用于不同的开发场景,如版本迭代、多人协作和个人开发。 ... [详细]
  • MyBatisCodeHelperPro 2.9.3 最新在线免费激活方法
    MyBatisCodeHelperPro 2.9.3 是一款强大的代码生成工具,适用于多种开发环境。本文将介绍如何在线免费激活该工具,帮助开发者提高工作效率。 ... [详细]
  • 本文介绍了多种常用的开发工具,包括PyCharm、Appium、Jenkins、Postman、Fiddler、Charles、Airtest、Android Studio、Navicat和Typora,并提供了它们的基本使用方法。 ... [详细]
  • iOS 百度地图使用指南:基本定位与地理编码
    本文详细介绍如何在 iOS 应用中集成百度地图,实现基本的地图定位和地理编码功能。配置详情请参考官方文档:http://developer.baidu.com/map/index.php?title=iossdk ... [详细]
  • RocketMQ 运维监控实践指南
    本文详细介绍了如何实现 RocketMQ 的运维监控,包括监控平台的搭建、常用运维命令及其具体用法。适合对 RocketMQ 监控感兴趣的读者参考。 ... [详细]
  • 本文探讨了为何产品团队提出的某些需求在研发完成后未能获得用户的认可,并提供了改进方法。主要分析了功能不完整或存在bug以及用户体验不佳的原因。 ... [详细]
  • PostgreSQL 12 版本预览:分离 max_wal_senders 和 max_connections 的连接槽处理
    本文介绍了 PostgreSQL 12 中的一项重要改进,即 max_wal_senders 参数不再计入 max_connections,从而解决了流复制连接槽不足的问题。 ... [详细]
author-avatar
nnamyp_826
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有