Butter Knife:一个安卓视图注入框架

2014年5月8日 星期四

14:52

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

GitHub地址: https://github.com/JakeWharton/butterknife

JavaDocs地址: http://jakewharton.github.io/butterknife/javadoc/

注:本随笔翻译自官网,做了一些整理和注释。来自我的OneNote笔记

大纲:

  1. @InjectView (Activity,Fragment)
  2. @InjectViews
  3. apply
  4. @OnClick
  5. reset
  6. @Optional
  7. @OnItemSelected
  1. TextView firstName = ButterKnife.findById(view, R.id.first_name);

Activity的注入方法:


//基本使用方法:在onCreate方法中调用ButterKnife.inject(this),然后就可以调用注解了

class ExampleActivity extends Activity {

@InjectView(R.id.title) TextView title;

@InjectView(R.id.subtitle) TextView subtitle;

@InjectView(R.id.footer) TextView footer;

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.simple_activity);

ButterKnife.inject(this);

// TODO Use "injected" views...

}

}

这个注入不是通过反射实现了(反射比较慢),而是直接生成代码。上面的三个注入最后生成如下的代码


public void inject(ExampleActivity activity) {

activity.subtitle = (android.widget.TextView) activity.findViewById(2130968578);

activity.footer = (android.widget.TextView) activity.findViewById(2130968579);

activity.title = (android.widget.TextView) activity.findViewById(2130968577);

}

Fragment的注入方法:


public class FancyFragment extends Fragment {

@InjectView(R.id.button1) Button button1;

@InjectView(R.id.button2) Button button2;

@Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fancy_fragment, container, false);

//仅仅是这里的区别

ButterKnife.inject(this, view);

// TODO Use "injected" views...

return view;

}

}

简化ViewHolder的使用 


public class MyAdapter extends BaseAdapter {

@Override public View getView(int position, View view, ViewGroup parent) {

//ViewHolder是一个普通的类,这个类包含了一个Adapter需要的所有View,然后设置到了tag中,方便复用

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 convertView;

}

//这里是ViewHolder:可以这样进行注入

static class ViewHolder {

@InjectView(R.id.title) TextView name;

@InjectView(R.id.job_title) TextView jobTitle;

public ViewHolder(View view) {

ButterKnife.inject(this, view);

}

}

}

注入一个View列表:@InjectViews


//注入一个View列表

@InjectViews({ R.id.first_name, R.id.middle_name, R.id.last_name })

List<EditText> nameViews;

//调用apply方法批量给View设置属性

ButterKnife.apply(nameViews, DISABLE);

ButterKnife.apply(nameViews, ENABLED, false);

//其中,DISABLE和ENABLED是两个接口的实现:Action,Setter

static final Action<View> DISABLE = new Action<>() {

@Override public void apply(View view, int index) {

view.setEnabled(false);

}

}

static final Setter<View, Boolean> ENABLED = new Setter<>() {

@Override public void set(View view, Boolean value, int index) {

view.setEnabled(value);

}

}

////View所有的属性都可以在apply方法中调用

ButterKnife.apply(nameViews, View.ALPHA, 0);

点击监听器的注入:OnClickListener -> @OnClick


//简单使用

@OnClick(R.id.submit)ren

public void submit() {

// TODO submit data to server...

}

//你可以传入一个参数,Butter Knife会自动将注入的View转换为对应的类型

@OnClick(R.id.submit)

public void sayHi(Button button) {

button.setText("Hello!");

}

//当然,也可以指定多个视图的IDs,用来进行通用的处理

@OnClick({ R.id.door1, R.id.door2, R.id.door3 })

public void pickDoor(DoorView door) {

if (door.hasPrizeBehind()) {

Toast.makeText(this, "You win!", LENGTH_SHORT).show();

} else {

Toast.makeText(this, "Try again", LENGTH_SHORT).show();

}

}

注入的重置:reset

Fragment中,我们需要在onDestroyView中设置这些View为null,但是只要调用reset方法,Butter Knife会自动执行这个步骤。


public class FancyFragment extends Fragment {

@InjectView(R.id.button1) Button button1;

@InjectView(R.id.button2) Button button2;

@Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fancy_fragment, container, false);

ButterKnife.inject(this, view);

// TODO Use "injected" views...

return view;

}

@Override void onDestroyView() {

super.onDestroyView();

ButterKnife.reset(this);

}

}

可选的注入 @Optional

默认情况下,@InjectView和@OnClick注入是必须了,所以,如果找不到目标View就会抛出异常。如果想抑制这种情况,可以通过@Optional注解:


@Optional @InjectView(R.id.might_not_be_there) TextView mightNotBeThere;

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

// TODO ...

}

多方法的监听@OnItemSelected

有些监听注解响应的方法有多个回调函数,所以,我们可以通过指定回调参数来实现多个回调方法的绑定。


@OnItemSelected(R.id.list_view)

void onItemSelected(int position) {

// TODO ...

}

@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)

void onNothingSelected() {

// TODO ...

}

BONUS:其实就是一个方便的静态方法而已

一般我们实例化一个View的时候是通过findById(id),然后强制转换实现的,这样的代码看着不雅观。所以,ButterKnife有一个方法自动帮我们进行这样的转换(Context可以为View和Activity),如下面的例子:


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);

最新版本:5.0.1

集成方法

Maven:


<dependency>

<groupId>com.jakewharton</groupId>

<artifactId>butterknife</artifactId>

<version>5.0.1</version>

</dependency>

Gradle:

  1. 添加依赖

compile ‘com.jakewharton:butterknife:5.0.1‘

  1. 消除lint warning

lintOptions {

disable ‘InvalidPackage‘

}

  1. Some configurations may also require additional exclusions.

packagingOptions {

exclude ‘META-INF/services/javax.annotation.processing.Processor‘

}

Procuard配置:(这个配置是为了打包apk的时候不至于把你的那些貌似没有用过的程序片段给删掉了)


-dontwarn butterknife.internal.**

-keep class **$$ViewInjector { *; }

-keepnames class * { @butterknife.InjectView *;}

Butter Knife:一个安卓视图注入框架

时间: 2024-11-08 22:36:46

Butter Knife:一个安卓视图注入框架的相关文章

Android RoboGuice开源框架、Butter Knife开源框架浅析

Google Guice on Android(RoboGuice) 今天介绍一下Google的这个开源框架RoboGuice, 它的作用跟之前讲过的Dagger框架差点儿是一样的,仅仅是Dagger比它的功能更强大一些. Dagger通过专注于一种简化的功能集以一种不同的方式达到了更好的性能.有人觉得RoboGuice节约了大量的时间.较少的代码意味着较少的错误.较少的样板代码意味着能够把很多其它的时间放到应用的核心逻辑上.所以这就是为什么我们要使用这些开源框架来开发的原因. 以下我们来说说R

【Butter Knife】依赖注入方式简化代码提高开发效率

Butter Knife是一款非常不错的开源框架,其目的是简化代码,提高项目的开发效率. 以往的开发我们经常需要用findViewById(R.xx.xxx);几乎没个页面都会涉及到,无论Activity还是Fragment甚至listView.GridView中的 Adapter.这些重复性的代码会让人觉得很枯燥,因为闭上眼都不会敲错的代码,每天重复几百遍是有点耗时,尽管有代码提示.而且可能会因为不同field的忘记书写而导致NullPoint空指针. 那么还是直接进入主题: 步骤: 第三方框

安卓开发 第一篇 关于依赖注入框架dagger2的使用和理解

(这篇博客真是磨难重重啊,写到一半电脑蓝屏了,还好markdown编辑器保持了部分类容) 最近开始重构项目,在重构项目中用到了依赖注入框架dagger2,发现它确实很方便,能大大加快我们编写代码的速度,同时也很方便我们对于功能模块的解耦.在这里就不过多介绍dagger2了,大家谷歌 百度一下就能得到很多关于dagger2的介绍.学习dagger2是需要一定的学习成本的,我自己开始学习的时候也差不多花了一周的时间才弄明白怎样使用dagger2,下面就说说自己对dagger2的理解和使用方法. da

[ASP.NET Core 3框架揭秘] 依赖注入:一个Mini版的依赖注入框架

在前面的章节中,我们从纯理论的角度对依赖注入进行了深入论述,我们接下来会对.NET Core依赖注入框架进行单独介绍.为了让读者朋友能够更好地理解.NET Core依赖注入框架的设计与实现,我们按照类似的原理创建了一个简易版本的依赖注入框架,也就是我们在前面多次提及的Cat. 源代码下载 普通服务的注册与消费泛型服务的注册与消费多服务实例的提供服务实例的生命周期 一.编程体验 虽然我们对这个名为Cat的依赖注入框架进行了最大限度的简化,但是与.NET Core框架内部使用的真实依赖注入框架相比,

Android Butterknife 注入框架

 简介 ButterKnife是一个专注于Android系统的View注入框架,当一个布局十分复杂时,需要引入执行大量的findViewById代码来找到View的对象,有了ButterKnife可以很轻松的省去这些步骤.是大神JakeWharton的力作,目前使用很广.最重要的一点,使用ButterKnife对性能基本没有损失,因为ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的class.项目集成起来也是特别方便,使用起来也是特别简单. ButterKnife的

ButterKnife--View注入框架

俗话说:"不会偷懒的程序员不是好的程序员!".作为一名Android开发,是不是经常厌烦了大量的findViewById以及setOnClickListener代码,而ButterKnife是一个专注于Android系统的View注入框架,让你从此从这些烦人臃肿的代码中解脱出来.先来看一段代码示例说明下ButterKnife是如何简化代码的: 注意:如果你是使用的Eclipse引用该library,你需要参考这里Eclipse Configuration做一些配置,否则会运行出错. c

Butter Knife使用详解

转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6610529.html Butter Knife Github地址: https://github.com/JakeWharton/butterknife 官方说明给出的解释是 Bind Android views and callbacks to fields and methods. Field and method binding for Android views which uses annot

Android ButterKnife注入框架

常常听到这么一个口号,叫做“努力做个爱偷懒的程序猿”.显然,Android ButterKnife也在一定程度上帮助了你成为一名偷懒的程序猿.作为Android开发者,你肯定对findViewById(),setOnClickListener(),setOnClickListener()等等非常熟悉,久而久之,是不是厌烦了这些东西,简单没营养,又不得不写,这时候,诸如Android ButterKnife,AndroidAnnotations等开源框架就出现了. ButterKnife新特性:

六款值得推荐的android(安卓)开源框架简介

1.volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载: (2) 网络请求的排序(scheduling) (3) 网络请求的优先级处理 (4) 缓存 (5) 多级别取消请求 (6) 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求) 2.android-async-http 项目地址:https://github.com/loopj/android-async-http