butterknife简化android开发
butterknife库非常不错的依赖注入库
http://jakewharton.github.io/butterknife/
maven引入 http://www.mvnrepository.com/artifact/com.jakewharton/butterknife/7.0.1
<dependency>
<groupId>com.jakewharton</groupId>
<artifactId>butterknife</artifactId>
<version>7.0.1</version>
</dependency>
Introduction
Annotate fields with @Bind
and a view ID for Butter Knife to find and automatically cast the corresponding view in your layout.
class ExampleActivity extends Activity {
@Bind(R.id.title) TextView title;
@Bind(R.id.subtitle) TextView subtitle;
@Bind(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...
}
}
Instead of slow reflection, code is generated to perform the view look-ups. Calling bind
delegates to this generated code that you can see and debug.
The generated code for the above example is roughly equivalent to the following:
public void bind(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);
}
RESOURCE BINDING
Bind pre-defined resources with @BindBool
, @BindColor
, @BindDimen
, @BindDrawable
, @BindInt
,@BindString
, which binds an R.bool
ID (or your specified type) to its corresponding field.
class ExampleActivity extends Activity {
@BindString(R.string.title) String title;
@BindDrawable(R.drawable.graphic) Drawable graphic;
@BindColor(R.color.red) int red; // int or ColorStateList field
@BindDimen(R.dimen.spacer) Float spacer; // int (for pixel size) or float (for exact value) field
// ...
}
NON-ACTIVITY BINDING
You can also perform binding on arbitrary objects by supplying your own view root.
public class FancyFragment extends Fragment {
@Bind(R.id.button1) Button button1;
@Bind(R.id.button2) Button button2; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}
}
Another use is simplifying the view holder pattern inside of a list adapter.
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 {
@Bind(R.id.title) TextView name;
@Bind(R.id.job_title) TextView jobTitle; public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
You can see this implementation in action in the provided sample.
Calls to ButterKnife.bind
can be made anywhere you would otherwise put findViewById
calls.
Other provided binding APIs:
- Bind arbitrary objects using an activity as the view root. If you use a pattern like MVC you can bind the controller using its activity with
ButterKnife.bind(this, activity)
. - Bind a view's children into fields using
ButterKnife.bind(this)
. If you use<merge>
tags in a layout and inflate in a custom view constructor you can call this immediately after. Alternatively, custom view types inflated from XML can use it in theonFinishInflate()
callback.
VIEW LISTS
You can group multiple views into a List
or array.
@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
The apply
method allows you to act on all the views in a list at once.
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
Action
and Setter
interfaces allow specifying simple behavior.
static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
@Override public void apply(View view, int index) {
view.setEnabled(false);
}
};
static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
@Override public void set(View view, Boolean value, int index) {
view.setEnabled(value);
}
};
An Android Property
can also be used with the apply
method.
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
LISTENER BINDING
Listeners can also automatically be configured onto methods.
@OnClick(R.id.submit)
public void submit(View view) {
// TODO submit data to server...
}
All arguments to the listener method are optional.
@OnClick(R.id.submit)
public void submit() {
// TODO submit data to server...
}
Define a specific type and it will automatically be cast.
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
}
Specify multiple IDs in a single binding for common event handling.
@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();
}
}
Custom views can bind to their own listeners by not specifying an ID.
public class FancyButton extends Button {
@OnClick
public void onClick() {
// TODO do something!
}
}
BINDING RESET
Fragments have a different view lifecycle than activities. When binding a fragment in onCreateView
, set the views to null
in onDestroyView
. Butter Knife has an unbind
method to do this automatically.
public class FancyFragment extends Fragment {
@Bind(R.id.button1) Button button1;
@Bind(R.id.button2) Button button2; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
ButterKnife.bind(this, view);
// TODO Use fields...
return view;
} @Override public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
}
OPTIONAL BINDINGS
By default, both @Bind
and listener bindings are required. An exception will be thrown if the target view cannot be found.
To suppress this behavior and create an optional binding, add a @Nullable
annotation to the field or method.
Note: Any annotation named @Nullable
can be used for this purpose. It is encouraged to use the@Nullable
annotation from Android's "support-annotations" library, see Android Tools Project.
@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere; @Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
// TODO ...
}
MULTI-METHOD LISTENERS
Method annotations whose corresponding listener has multiple callbacks can be used to bind to any one of them. Each annotation has a default callback that it binds to. Specify an alternate using the callback
parameter.
@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
// TODO ...
} @OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)
void onNothingSelected() {
// TODO ...
}
BONUS
Also included are findById
methods which simplify code that still has to find views on a View
,Activity
, or Dialog
. It uses generics to infer the return type and automatically performs the cast.
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);
Add a static import for ButterKnife.findById
and enjoy even more fun.
Download
The source code to the library and sample application as well as this website is available on GitHub. The Javadoc is also available to browse.
MAVEN
If you are using Maven for compilation you can declare the library as a dependency.
<dependency>
<groupId>com.jakewharton</groupId>
<artifactId>butterknife</artifactId>
<version>(insert latest version)</version>
</dependency>
GRADLE
compile 'com.jakewharton:butterknife:(insert latest version)'
Be sure to suppress this lint warning in your build.gradle
.
lintOptions {
disable 'InvalidPackage'
}
Some configurations may also require additional exclusions.
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
IDE CONFIGURATION
Some IDEs require additional configuration in order to enable annotation processing.
- IntelliJ IDEA — If your project uses an external configuration (like a Maven
pom.xml
) then annotation processing should just work. If not, try manual configuration. - Eclipse — Set up manual configuration.
PROGUARD
Butter Knife generates and uses classes dynamically which means that static analysis tools like ProGuard may think they are unused. In order to prevent them from being removed, explicitly mark them to be kept. To prevent ProGuard renaming classes that use @Bind on a member field thekeepclasseswithmembernames
option is used.
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * {
@butterknife.* <fields>;
} -keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
butterknife简化android开发的更多相关文章
- Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)
作者:Antonio Leiva 时间:Jan 5, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin/ 由于Lambda表达式允许更简单的方式建模式 ...
- Android开发人员应该知道的Kotlin
本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/01/kotlin-android Android开发人员在语言限制方面面临着 ...
- Android开发之手把手教你写ButterKnife框架(三)
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52672188 本文出自:[余志强的博客] 一.概述 上一篇博客讲了, ...
- Android ButterKnife注解式开发
在Android开发中findViewById和setOnClickListener解脱写法. 在任意的一个类中 @Bind(R.id.et) EditText editText; @OnClick( ...
- Android开发之手把手教你写ButterKnife框架(二)
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52664112 本文出自:[余志强的博客] 上一篇博客Android开 ...
- Android开发之手把手教你写ButterKnife框架(一)
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52662376 本文出自:[余志强的博客] 一.概述 JakeWhar ...
- 【转】Android开发规范
转自:https://github.com/Blankj/AndroidStandardDevelop 摘要 1 前言 2 AS 规范 3 命名规范 4 代码样式规范 5 资源文件规范 6 版本统一规 ...
- 【转】Android 开发规范(完结版)
摘要 1 前言 2 AS 规范 3 命名规范 4 代码样式规范 5 资源文件规范 6 版本统一规范 7 第三方库规范 8 注释规范 9 测试规范 10 其他的一些规范 1 前言 为了有利于项目维护.增 ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
随机推荐
- 《Excel图表之道》读书笔记
一.突破常规的作图方法 突破Excel的默认颜色 非数据元素用淡色 突破Excel的图表布局 图表要素:主标题.副标题.图例.绘图.脚注 竖向构图 标明数据来源.图表注释.坐标轴截断符号 专业的水蓝色 ...
- Python的面向对象3
接下来,我们接着讲Python的面向对象,在上一次的博客中,我们详细介绍了类与对象的属性,今天,我们来详细介绍一下面向对象中的方法! 1.定义实例方法 一个实例的私有属性就是以__开头的属性,无法被外 ...
- openssl Mac编译小记
1. 下载openssl包 2. 解压 3. 打开控制台, 进入包目录, 执行 ./Configure darwin64-x86_64-cc 4. make 5. 得到 libcrypto.a lib ...
- Apple 公司开发者账号注册
苹果公司开发者账号注册流程详解 这段时间在给朋友申请苹果账号,从个人开发者账号.公司账号到企业账号,申请了个遍.这里对申请流程做一下介绍,方便其他朋友,少走弯路,账号早日申请通过. 1.首先介绍下 ...
- bzoj 1138: [POI2009]Baj 最短回文路 dp优化
1138: [POI2009]Baj 最短回文路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 161 Solved: 48[Submit][Sta ...
- CrystalDiskMark 的使用方法
CrystalDiskMark 是一个测试你的硬盘或者存储设备的小巧硬盘测试工具.简单易于操作的界面让你随时可以测试你的存储设备,测试存储设备大小和测试数字都可以选择,还可测试可读和可写的速度. 具体 ...
- C++ Socket TCP "Hello World!"
这是C++ SOCKET网络程序中的C/S结构之TCP "Hello World !",共两个控制台工程: //////////////////////////////////// ...
- 匿名hash
[root@oadb test]# cat a1.pl use Data::Dumper; my @a=qw/1 3 5 7 9/; push @b ,{@a}; print Dumper(@b); ...
- Chapter 17 Replication
Chapter 17 Replication Table of Contents 17.1 Replication Configuration 17.2 Replication Implementat ...
- 只要把鼠标移上Div方框,方框就自动顺时针旋转
这是一个CSS3特效,IE下看不到效果.一个Div方框,在CSS3代码的作用下,只要把鼠标移上Div方框,方框就自动顺时针旋转.代码量不大,甚至有些简单,作为一个基础的CSS3实例,我想还是比较不错的 ...