Butter Knife
参考:
Introduction:http://jakewharton.github.io/butterknife/
JakeWharton/butterknife:https://github.com/JakeWharton/butterknife
依赖注入框架AndroidAnnotations和ButterKnife真的方便了开发者?:https://www.zhihu.com/question/38742543?sort=created
最近才接触到 ButterKnife
,很好用,不过刚入门还是有一些困难,网上查找了不少资料,记录下 ButterKnife
最常用的方法,方便以后使用
下面代码的实现工程:ButterKnifeDemo
源代码编译工程:http://download.csdn.net/detail/u012005313/9824876
主要内容
- 基本原理
Android Studio
导入ButterKnife
Activity
中使用Fragment
和Adapter
中使用Android Studio
插件android-butterknife-zelezny
使用
基本原理
参考:【腾讯Bugly干货分享】深入理解 ButterKnife,让你的程序学会写代码
ButterKnife
是利用 Java
注解机制来实现辅助代码生成的框架,其在编译期生成代码,对运行时没有任何副作用(注:暂时不理解注解机制,没深入看过 ButterKnife
代码)
Android Studio
导入
ButterKnife
Android Studio
导入
ButterKnife
当前最新版本:8.5.1
新建工程 ButterKnifeDemo
:
打开 app->build.gradle
,直接添加:
dependencies {
...
compile 'com.jakewharton:butterknife:8.5.1'
compile 'com.jakewharton:butterknife-compiler:8.5.1'
}
或者
打开 File->Project Structure
,在 app->Dependencies
中打开 Library Dependency
窗口,输入 butterknife
进行查找
自此,导入完成
Activity
中使用
Activity
中使用
ButterKnife
的使用方式非常简单
Field and method binding for Android views which uses annotation processing to generate boilerplate code for you.
* Eliminate findViewById calls by using @BindView on fields.
* Group multiple views in a list or array. Operate on all of them at once with actions, setters, or properties.
* Eliminate anonymous inner-classes for listeners by annotating methods with @OnClick and others.
* Eliminate resource lookups by using resource annotations on fields.
接下来用具体的实例验证
在 Activity
中使用
在 MainActivity
中实现
- 文本视图(
TextView
) - 进度条(
ProgressBar
) - 按钮(
Button
) - 多选框(
CheckBox
) - 单选框(
RadioButton
) - 下拉框(
Spinner
) - 图像按钮(
ImageButton
)
利用 ButterKnife
进行组件绑定,同时进行值设置,属性设置,以及接口调用
strings.xml
:
<resources>
<string name="app_name">ButterKnifeDemo</string>
<string-array name="array">
<item>卡西</item>
<item>阿道夫</item>
<item>供电所</item>
</string-array>
<string-array name="array2">
<item>啊等发达</item>
<item>噶地方</item>
<item>擦地方</item>
</string-array>
<string-array name="array3">
<item>fadf</item>
<item>cadrfe</item>
<item>gadfa</item>
<item>cafd</item>
</string-array>
</resources>
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.uniview.butterknifedemo.MainActivity">
<TextView
android:id="@+id/am_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/ll_tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
<TextView
android:id="@+id/ll_tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
<TextView
android:id="@+id/ll_tv3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="TextView" />
</LinearLayout>
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/checkBox3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="CheckBox" />
<CheckBox
android:id="@+id/checkBox2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="CheckBox" />
<CheckBox
android:id="@+id/checkBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="CheckBox" />
</LinearLayout>
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<RadioButton
android:id="@+id/radioButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RadioButton" />
<RadioButton
android:id="@+id/radioButton4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RadioButton" />
<RadioButton
android:id="@+id/radioButton3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RadioButton" />
<RadioButton
android:id="@+id/radioButton2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="RadioButton" />
</RadioGroup>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Spinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="@+id/imageButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@android:drawable/arrow_down_float"
app:srcCompat="@color/colorPrimaryDark" />
</LinearLayout>
</LinearLayout>
MainActivity.java
:
package com.uniview.butterknifedemo;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import butterknife.BindArray;
import butterknife.BindString;
import butterknife.BindView;
import butterknife.BindViews;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnItemSelected;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@BindView(R.id.am_tv)
TextView textView;
@BindView(R.id.progressBar)
ProgressBar progressBar;
@BindViews({R.id.ll_tv1, R.id.ll_tv2, R.id.ll_tv3})
List<TextView> textViewList;
@BindView(R.id.button)
Button button;
@BindViews({R.id.checkBox, R.id.checkBox2, R.id.checkBox3})
List<CheckBox> checkBoxList;
@BindViews({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
List<RadioButton> radioButtonList;
@BindView(R.id.spinner)
Spinner spinner;
@BindView(R.id.imageButton)
ImageButton imageButton;
@BindString(R.string.app_name)
String appName;
@BindArray(R.array.array)
String[] arrays;
@BindArray(R.array.array2)
String[] arrays2;
@BindArray(R.array.array3)
String[] arrays3;
static final ButterKnife.Setter<TextView, String[]> initialText = new ButterKnife.Setter<TextView, String[]>() {
@Override
public void set(@NonNull TextView view, String[] value, int index) {
view.setText(value[index]);
}
};
static final ButterKnife.Setter<TextView, String[]> initialRadio = new ButterKnife.Setter<TextView, String[]>() {
@Override
public void set(@NonNull TextView view, String[] value, int index) {
view.setText(value[index]);
}
};
static final ButterKnife.Action<TextView> visible = new ButterKnife.Action<TextView>() {
@Override
public void apply(@NonNull TextView view, int index) {
view.setVisibility(View.VISIBLE);
}
};
static final ButterKnife.Action<TextView> invisible = new ButterKnife.Action<TextView>() {
@Override
public void apply(@NonNull TextView view, int index) {
view.setVisibility(View.INVISIBLE);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initView();
}
private void initView() {
textView.setText(appName);
// for (int i = 0; i < 3; i++) {
// textViewList.get(i).setText(arrays[i]);
// }
ButterKnife.apply(textViewList, initialText, arrays);
// ButterKnife.apply(textViewList, actionText);
ButterKnife.apply(checkBoxList, initialText, arrays2);
ButterKnife.apply(radioButtonList, initialRadio, arrays3);
ButterKnife.apply(textViewList, invisible);
ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(this,
android.R.array.organizationTypes, android.R.layout.simple_spinner_item);
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(spinnerAdapter);
}
@OnClick(R.id.am_tv)
void textViewClick() {
String text = textView.getText().toString();
if (text.equals("Hello World")) {
textView.setText("Hello zj");
} else {
textView.setText("Hello World");
}
}
@OnClick({R.id.ll_tv1, R.id.ll_tv2, R.id.ll_tv3})
void textMultipleClick() {
// for (int i = 0; i < 3; i++) {
// textViewList.get(i).setText(arrays2[i]);
// }
ButterKnife.apply(textViewList, initialText, arrays2);
}
@OnClick(R.id.button)
void btnClick(View view) {
int flag = progressBar.getVisibility();
Log.e(TAG, "btnClick: flag = " + flag);
if (flag == progressBar.VISIBLE) {
progressBar.setVisibility(progressBar.INVISIBLE);
ButterKnife.apply(textViewList, visible);
} else {
progressBar.setVisibility(progressBar.VISIBLE);
ButterKnife.apply(textViewList, invisible);
}
}
@OnClick({R.id.checkBox, R.id.checkBox2, R.id.checkBox3})
void onCheckboxClicked(View view) {
switch (view.getId()) {
case R.id.checkBox:
Toast.makeText(this, "you click checkbox + " + ((CheckBox) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.checkBox2:
Toast.makeText(this, "you click checkbox2 + " + ((CheckBox) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.checkBox3:
Toast.makeText(this, "you click checkbox3 + " + ((CheckBox) view).getText(), Toast.LENGTH_SHORT).show();
break;
}
}
@OnClick({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
void onRadioClicked(View view) {
switch (view.getId()) {
case R.id.radioButton:
Toast.makeText(this, "you click radiobutton + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.radioButton2:
Toast.makeText(this, "you click radiobutton2 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.radioButton3:
Toast.makeText(this, "you click radiobutton3 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.radioButton4:
Toast.makeText(this, "you click radiobutton4 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
}
}
@OnItemSelected(value = R.id.spinner, callback = OnItemSelected.Callback.ITEM_SELECTED)
void onItemSel(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(this, "position: " + position + " id: " + id, Toast.LENGTH_SHORT).show();
}
@OnClick(R.id.imageButton)
void onImageBtnClicked() {
Intent intent = new Intent(this, Main2Activity.class);
intent.putExtra("image", "image");
startActivity(intent);
}
}
首先需要在 onCreate()
中调用 ButterKnife
注意:需要在 ‘setContentView’ 之后
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
// TODO Use fields...
}
对于视图,可以单个绑定,也可以将多个视图同时进行绑定,生成 List
或者 Array
形式:
@BindView(R.id.am_tv)
TextView textView;
@BindView(R.id.progressBar)
ProgressBar progressBar;
@BindViews({R.id.ll_tv1, R.id.ll_tv2, R.id.ll_tv3})
List<TextView> textViewList;
@BindView(R.id.button)
Button button;
@BindViews({R.id.checkBox, R.id.checkBox2, R.id.checkBox3})
List<CheckBox> checkBoxList;
@BindViews({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
List<RadioButton> radioButtonList;
@BindView(R.id.spinner)
Spinner spinner;
@BindView(R.id.imageButton)
ImageButton imageButton;
Note:这样操作之后,就不需要再使用 findViewById
了
使用 ButterKnife
同时可以对资源进行绑定:
@BindString(R.string.app_name)
String appName;
@BindArray(R.array.array)
String[] arrays;
@BindArray(R.array.array2)
String[] arrays2;
@BindArray(R.array.array3)
String[] arrays3;
不仅可以进行字符串,字符串数组绑定,还可以进行颜色,图像等其他资源绑定
当多个视图同时绑定,生成 List
或者 Array
形式后,ButterKnife
还提供了同时赋值和属性设置的功能
赋值函数:
/** A setter that can apply a value to a list of views. */
public interface Setter<T extends View, V> {
/** Set the {@code value} on the {@code view} which is at {@code index} in the list. */
@UiThread
void set(@NonNull T view, V value, int index);
}
属性设置函数:
/** An action that can be applied to a list of views. */
public interface Action<T extends View> {
/** Apply the action on the {@code view} which is at {@code index} in the list. */
@UiThread
void apply(@NonNull T view, int index);
}
应用函数:
There are three convenience methods for working with view collections:
apply(List, Action) – Applies an action to each view.
apply(List, Setter, Object) – Applies a setter value to each view.
apply(List, Property, Object) – Applies a property value to each view.
对于视图而言,还可以对接口事件进行绑定
比如对于 TextView
来说,可以进行点击事件的绑定:
@OnClick(R.id.am_tv)
void textViewClick() {
...
}
函数名自定义,可以根据需求添加原本接口函数的参数:
@OnClick(R.id.button)
void btnClick(View view) {
...
}
如果接口事件中有多个函数,需要进行指定:
@OnItemSelected(value = R.id.spinner, callback = OnItemSelected.Callback.ITEM_SELECTED)
...
}
如果多个视图都要进行同一事件的操作,可以同时绑定:
@OnClick({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
void onRadioClicked(View view) {
switch (view.getId()) {
case R.id.radioButton:
Toast.makeText(this, "you click radiobutton + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.radioButton2:
Toast.makeText(this, "you click radiobutton2 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.radioButton3:
Toast.makeText(this, "you click radiobutton3 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
case R.id.radioButton4:
Toast.makeText(this, "you click radiobutton4 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
break;
}
}
Fragment
和 Adapter
中使用
Fragment
和 Adapter
中使用
ButterKnife
不仅可以用在 Activity
中,还可以使用在 Fragment
和 Adapter
中,接下来实现一个 ViewPager + TabLayout + Fragment + RecyclerView
的组合
Main3Activity.java
:
package com.uniview.butterknifedemo;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import butterknife.BindView;
import butterknife.ButterKnife;
public class Main3Activity extends AppCompatActivity {
@BindView(R.id.tab_layout)
TabLayout tabLayout;
@BindView(R.id.view_pager)
ViewPager viewPager;
private MyAdapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
ButterKnife.bind(this);
initView();
}
private void initView() {
myAdapter = new MyAdapter(this, getSupportFragmentManager());
viewPager.setAdapter(myAdapter);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.setupWithViewPager(viewPager);
}
}
activity_main3.xml
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.uniview.butterknifedemo.Main3Activity">
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MyAdapter.java
:
package com.uniview.butterknifedemo;
import android.content.Context;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
/**
* Created by Lenovo on 2017/4/23.
*/
public class MyAdapter extends FragmentPagerAdapter {
private final String Tabs[] = {"left", "middle", "right"};
private Context context;
public MyAdapter(Context context, FragmentManager fm) {
super(fm);
this.context = context;
}
@Override
public Fragment getItem(int position) {
return ViewPagerFragment.newInstance(position);
}
@Override
public int getCount() {
return Tabs.length;
}
@Override
public CharSequence getPageTitle(int position) {
// return super.getPageTitle(position);
return Tabs[position];
}
}
ViewPagerFragment.java
:
package com.uniview.butterknifedemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import butterknife.BindArray;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
/**
* Created by Lenovo on 2017/4/22.
*/
public class ViewPagerFragment extends Fragment {
private int status;
@BindView(R.id.text)
TextView textView;
@BindView(R.id.recycler_view)
RecyclerView recyclerView;
@BindArray(R.array.array)
String[] arrays;
@BindArray(R.array.array2)
String[] arrays2;
private Unbinder unbinder;
private DisplayAdapter displayAdapter;
private LinearLayoutManager linearLayoutManager;
public static ViewPagerFragment newInstance(int status) {
ViewPagerFragment viewPagerFragment = new ViewPagerFragment();
Bundle args = new Bundle();
args.putInt("status", status);
viewPagerFragment.setArguments(args);
return viewPagerFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
status = getArguments() != null ? getArguments().getInt("status") : 1;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// return super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.fragment_view, container, false);
unbinder = ButterKnife.bind(this, v);
textView.setText("statu: " + status);
linearLayoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(linearLayoutManager);
if (status == 0 || status == 2) {
displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays));
} else {
displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays2));
}
recyclerView.setAdapter(displayAdapter);
return v;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
fragment_view.xml
:
<?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">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/app_name"
android:textSize="24sp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
DisplayAdapter.java
:
package com.uniview.butterknifedemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by Lenovo on 2017/4/24.
*/
public class DisplayAdapter extends RecyclerView.Adapter<DisplayAdapter.MyViewHolder> {
private static final String TAG = DisplayAdapter.class.getSimpleName();
private Context context;
private List<String> arrays = new ArrayList<>();
public DisplayAdapter(Context context, List<String> arrs) {
this.context = context;
arrays.addAll(arrs);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// return null;
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_recycler_view, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(arrays.get(position));
}
@Override
public int getItemCount() {
return arrays.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.text)
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
layout_recycler_view.xml
:
<?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="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:text="@string/app_name"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#000000" />
</LinearLayout>
绑定 fragment
格式如下:
@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;
}
在绑定自身的同时还需要指明父视图。同时,由于 fragment
有一个不同的生命周期,需要在 onDestroyView
方法中解绑 ButterKnife
,具体用法如下:
@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();
}
当前代码操作如下:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// return super.onCreateView(inflater, container, savedInstanceState);
View v = inflater.inflate(R.layout.fragment_view, container, false);
unbinder = ButterKnife.bind(this, v);
textView.setText("statu: " + status);
linearLayoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(linearLayoutManager);
if (status == 0 || status == 2) {
displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays));
} else {
displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays2));
}
recyclerView.setAdapter(displayAdapter);
return v;
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
使用 RecyclerView
或者 ListView
时,经常会使用 ViewHolder
模型来优化,ButterKnife
也提供了在 ViewHolder
中进行视图绑定的方法:
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 {
@BindView(R.id.title) TextView name;
@BindView(R.id.job_title) TextView jobTitle;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
当前代码中 ViewHolder
操作如下:
static class MyViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.text)
TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
Android Studio
插件 android-butterknife-zelezny
使用
Android Studio
插件 android-butterknife-zelezny
使用
参考:
avast/android-butterknife-zelezny
Android Studio
上有关于 ButterKnife
的插件,推荐 android-butterknife-zelezny
,非常有用
安装方法不再介绍,下面提醒一下使用时需要注意的事情:
安装完成后,需要点击在 xml
文件上,鼠标右键点击 Generate...
,才会出现 ButterKnife
的选项