ButterKnife是一个通过对Android View添加注解的方式来提高开发效率的开源库。
1.配置
在项目中配置ButterKnife有下面几种方式:
JAR
旧式导jar包:Butter Knife v6.1.0 JAR
MAVEN
如果你使用maven,可以添加butterknife库作为依赖
1 2 3 4 5
| <dependency> <groupId>com.jakewharton</groupId> <artifactId>butterknife</artifactId> <version>6.1.0</version> </dependency>
|
GRADLE
如果你使用gradle构建android项目(Android Studio默认构建方式),则可以在app -> build.gradle -> dependencies节点添加下面配置
1
| compile 'com.jakewharton:butterknife:6.1.0'
|
如果项目编译时出现类似InvalidPackage: Package not included in Android
错误,则需要在app -> build.gradle -> android节点添加下面配置(不过我没出现这错误…)
1 2 3 4 5 6 7 8 9 10
| android { ... lintOptions { disable 'InvalidPackage' }
packagingOptions { exclude 'META-INF/services/javax.annotation.processing.Processor' } }
|
2.使用
2.1 ACTIVITY INJECTION
1 2 3 4 5 6 7 8 9 10 11 12
| 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); } }
|
2.2 NON-ACTIVITY INJECTION
也可以对除Activity之外的view对象进行注入,不过要在获取到view root对象后。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class FancyFragment extends Fragment { @InjectView(R.id.button1) Button button1; @InjectView(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.inject(this, view); return view; } @Override public void onDestroyView() { super.onDestroyView(); ButterKnife.reset(this); } }
|
2.3 ViewHolder INJECTION
也可以简化list adapter中的View Holder模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| 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");
return view; }
static class ViewHolder { @InjectView(R.id.title) TextView name; @InjectView(R.id.job_title) TextView jobTitle;
public ViewHolder(View view) { ButterKnife.inject(this, view); } } }
|
2.4 LISTENER INJECTION
可以对事件监听进行注入(方法的参数可以按需添加)
1 2 3 4
| @OnClick(R.id.submit) public void submit() { }
|
可以一次指定多个id,同时加事件
1 2 3 4 5 6 7 8
| @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(); } }
|
可以给listview的item点击事件添加注入
1 2 3 4
| @OnItemClick(R.id.list_view) void onItemClick(AdapterView<?> parent, View view, int position, long id) { }
|
自定义的view不用指定具体id也可以绑定它的listeners
1 2 3 4 5 6
| public class FancyButton extends Button { @OnClick public void onClick() { } }
|
2.5 OPTIONAL INJECTIONS
通常情况下不会出现the target view cannot be found
情况,但为了避免出现而报异常,可以在变量或者方法前面加上 @Optional
注解
1 2 3 4 5
| @Optional @InjectView(R.id.might_not_be_there) TextView mightNotBeThere;
@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() { }
|
2.6 其他
有一些View, Activity, or Dialog可能还是会去find views id,butterknife提供了findById方法,它会自动强转为正确类型。
1 2 3 4
| 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);
|
3.混淆
如果你在打包apk时需要对代码进行混淆处理,这时为了避免那些使用了butterknife注解的文件被认为无用而删除,可以在app -> proguard-rules.pro 文件中添加下面混淆规则:
1 2 3 4 5 6 7 8 9 10 11 12
| -keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewInjector { *; }
-keepclasseswithmembernames class * { @butterknife.* <fields>; }
-keepclasseswithmembernames class * { @butterknife.* <methods>; }
|
更多相关内容请查看源码和官方说明:
ButterKnife Github
ButterKnife Introduction