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