开发中找到xml中对应的ui并设置对应的事件,一般用findViewById,然后设置onClick事件来实现,这样写起来比较麻烦,有没更简单的?Butterknife本场的主角闪亮登场.
Butterknife作用:
通过注解的方式来对Android View进行绑定.
Butterknife的Github源码如下:
https://github.com/JakeWharton/butterknife
对它的介绍可以看下面链接:
http://jakewharton.github.io/butterknife/
下面根据文档描述,简单的介绍下如何使用:
- 注解实例变量view 取代findViewById
class ExampleActivity extends Activity {
@BindView(R.id.title)
TextView title;//取代findViewByid(R.id.title)
@BindView(R.id.subtitle)
TextView subtitle;//取代findViewByid(R.id.subtitle)
@BindView(R.id.footer)
TextView footer;//取代findViewByid(R.id.footer)
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);//注意这里必须设置绑定当前Activity
// TODO Use fields...
//后续就可以直接使用比如
title.setText("Just test");
}
}
上面代码在butterknife内部生产类似下面的code
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);
}
- 对资源绑定注解
在Butterknife中定义如下对资源的注解
@BindBool, @BindColor, @BindDimen, @BindDrawable, @BindInt, @BindString 上面的可以对应获取android res目录下对应的资源。
举个:
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
// ...
}
- 不在Activity中如何使用butterknife
- bind对应的view通过它们的root view,举个例子在Fragment中
public class FancyFragment extends Fragment {
@BindView(R.id.button1) Button button1;
@BindView(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);//注意这里传入的是root view
// TODO Use fields...
return view;
}
}
或者是在ViewHolder中使用
static class ViewHolder {
@BindView(R.id.title) TextView name;
@BindView(R.id.job_title) TextView jobTitle;
public ViewHolder(View view) {
ButterKnife.bind(this, view);//这里对应的是bind(this,view)
}
}
- 绑定View List
@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List nameViews;
- 绑定View的事件
对应View onClick事件
@OnClick(R.id.submit)
public void submit(View view) {//其中submit方法中的参数是可选的
// TODO submit data to server...
}
对应ViewOnItemSelected事件
@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
// TODO ...
}
当然也可以多个view对应一个click事件如下:
@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();
}
}
在自定义View的绑定事件更简单如下:
public class FancyButton extends Button {
@OnClick
public void onClick() {
// TODO do something!
}
}
- 释放对应的bind资源
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();//在onDestoryView中释放对应的资源
}
}
- 其他较为少用的方法
TextView firstName = ButterKnife.findById(view, R.id.first_name);
//替换findViewById 不需要强转
//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);//设置
遇到版本问题,具体如下
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LogUtil.d("onCreate........................");
myLocationListener = new MyLocationListener(getLifecycle());
setContentView(R.layout.lifecycle_test);
ButterKnife.bind(this);
}
@OnClick(R.id.btnJump)
public void onClick(View view){
Intent intent = new Intent(this, DatabaseStudyActivity.class);
startActivity(intent);
}
发现点击Button无法响应对应的onClick时间,什么原因呢?google了下发现是build.grandle配置出现了问题,下面是build.gradle中的配置
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.jakewharton:butterknife-annotations:8.8.1'
ButterKnife从7.x到8.x后,运行时和编译器被分开来了,所以需要加入compiler在build.grandle中,如下所示:
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
这样整个build.gradle配置如下:
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.jakewharton:butterknife-annotations:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'