ButterKnife,俗称黄油刀,在Android开发经常使用的一个专注于Android系统的View注入框架,简短findViewById来获取View对象的代码长度是它的功能之一,此外它还可以缩减监听事件的长度,并对其性能影响不大,但编译时间会有所加长,不过你是感受不出来的
GitHub地址:https://github.com/JakeWharton/butterknife
官方文档:http://jakewharton.github.io/butterknife/
ButterKnife主要采用编译时注解,就是用 apt 生成代码,详细解释:ButterKnife 原理
这里我们介绍在Java中添加ButterKnife依赖和在kotlin中添加ButterKnife依赖,适用于Android X库
在你的build.gradle(module:app)中的dependencies{ }里添加如下两条语句:
//引入ButterKnife
implementation "com.jakewharton:butterknife:10.0.0"
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
同样在如上相同的文件中,加入以下两条语句
implementation 'com.jakewharton:butterknife:10.2.1'
kapt 'com.jakewharton:butterknife-compiler:10.2.1'
打开Android studio,点击File 》》Settings》》Plugins》》Marketplace中搜索ButterKnife
点击安装后,需要重启Android studio,才会启用
首先在你的资源文件中设置ID
android:id="@+id/id"
然后在activity中引用该资源文件
setContentView(R.layout.activity_main);
将光标放在绑定视图的括号中,右键如图操作:
勾选onclick,还可以自动生成点击事件
@OnClick({R.id.main_page_container, R.id.main_bottn})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.main_page_container:
break;
case R.id.main_bottn:
break;
}
}
Activity里在onCreate方法中加入ButterKnife.bind(this)
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定初始化ButterKnife
ButterKnife.bind(this);
}
}
Fragment中先使用inflater返回一个view,再使用ButterKnife.bind(this, view)绑定即可,注意:你需要在适当的时候对其进行解绑
public class ButterknifeFragment extends Fragment{
private Unbinder unbinder;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container, false);
//返回一个Unbinder值(进行解绑),注意这里的this不能使用getActivity()
unbinder = ButterKnife.bind(this, view);
return view;
}
/**
* onDestroyView中进行解绑操作
*/
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
Adapter的ViewHolder中使用,将ViewHolder加一个构造方法,在new ViewHolder的时候把view传递进去。使用ButterKnife.bind(this, view)进行绑定,代码如下:
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.testlayout, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
}
holder.name.setText("Donkor");
holder.job.setText("Android");
// etc...
return view;
}
static class ViewHolder {
@BindView(R.id.title) TextView name;
@BindView(R.id.job) TextView job;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
单个控件id注解
@BindView(R.id.main_bottn)
BottomNavigationView mbottomNavigationView;
布局内多个控件id注解
public class MainActivity extends AppCompatActivity {
@BindViews({ R.id.button1, R.id.button2, R.id.button3})
public List<Button> buttonList ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
buttonList.get( 0 ).setText( "hello 1 ");
buttonList.get( 1 ).setText( "hello 2 ");
buttonList.get( 2 ).setText( "hello 3 ");
}
}
绑定图片资源为Bitmap:
@BindBitmap( R.mipmap.wifi )
Bitmap bitmap;
绑定一个String 资源为一个String变量及数组
绑定string里面array数组:
```java
<resources>
<string name="app_name">城市</string>
<string-array name="city">
<item>北京市</item>
<item>天津市</item>
<item>哈尔滨市</item>
<item>大连市</item>
<item>香港市</item>
</string-array>
</resources>
------------------------------------------------------------------------------
public class MainActivity extends AppCompatActivity {
@BindView(R2.id.button) //绑定button 控件
public Button button ;
@BindString(R2.string.app_name) //绑定资源文件中string字符串
String str;
@BindArray(R2.array.city) //绑定string里面array数组
String [] citys ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定activity
ButterKnife.bind( this ) ;
button.setText(citys[0]);
}
}
绑定color 资源为一个int变量:
@BindColor(R.color.colorAccent)
int black;
绑定Dimen资源:
@BindDimen(R.dimen.borth_width)
int mBorderWidth;
绑定Drawable
@BindDrawable(R.drawable.test_pic)
Drawable mTestPic;
绑定Int类型
@BindInt(R.int.columns)
int columns;
绑定Bool类型
@BindBool(R.bool.is_tablet)
boolean isTablet;
绑定Float类型
// 可绑定 float 类型的 dimen 资源
@BindFloat(R.dimen.image_ratio)
float imageRatio;
绑定单个OnClick和OnLongClick事件
public class MainActivity extends AppCompatActivity {
@OnClick(R.id.button1)
public void onViewClicked() {
Toast.makeText(this, "这是绑定的点击事件", Toast.LENGTH_SHORT).show();
}
@OnLongClick( R1.id.button1 ) //给 button1 设置一个长按事件
public boolean onViewClickeds(){
Toast.makeText(this, "这是绑定的长按事件", Toast.LENGTH_SHORT).show();
return true ;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定activity
ButterKnife.bind( this ) ;
}
}
绑定多个点击事件
@OnClick({R.id.button1, R.id.main_button2})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button1:
break;
case R.id.main_button2:
break;
}
}
在RadioGroup+RadioButton中使用OnCheckedChanged事件绑定
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RadioGroup
android:id="@+id/rg_main"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:background="@color/white"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rg_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:text="@string/nav_one" />
<RadioButton
android:id="@+id/rg_wealth"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:text="@string/nav_two" />
<RadioButton
android:id="@+id/rg_account"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="false"
android:text="@string/nav_four" />
</RadioGroup>
</LinearLayout>
-------------------------------------------------------------------------
@OnCheckedChanged({R.id.rg_home,R.id.rg_wealth,R.id.rg_account})
public void OnCheckedChangeListener(CompoundButton view, boolean ischanged ){
switch (view.getId()) {
case R.id.rg_home:
if (ischanged){//注意:这里一定要有这个判断,只有对应该id的按钮被点击了,ischanged状态发生改变,才会执行下面的内容
//这里写你的按钮变化状态的UI及相关逻辑
}
break;
case R.id.rg_wealth:
if (ischanged) {
//这里写你的按钮变化状态的UI及相关逻辑
}
break;
case R.id.rg_account:
if (ischanged) {
//这里写你的按钮变化状态的UI及相关逻辑
}
break;
default:
break;
}
}
这个在viewpager中使用
@OnPageChange(R.id.viewpager)
public void onPageSelected(int position) {
switch (position) {
case 0:
break;
case 1:
break;
}
}
注解 | 用处 |
---|---|
@OnEditorAction | 软键盘的功能键 |
@OnFocusChange | 焦点改变 |
@OnItemClick item | 被点击(注意这里有坑,如果item里面有Button等这些有点击的控件事件的,需要设置这些控件属性focusable为false) |
@OnItemLongClick item | 长按(返回真可以拦截onItemClick) |
@OnItemSelected | item被选择事件 |
@OnTextChanged | EditText里面的文本变化事件 |
@Optional | 选择性注入,如果当前对象不存在,就会抛出一个异常,为了压制这个异常,可以在变量或者方法上加入一下注解,让注入变成选择性的,如果目标View存在,则注入, 不存在,则什么事情都不做 |
Android Butterknife(黄油刀) 使用方法总结
ButterKnife使用方法详解
ButterKnife 的简单使用