[Android]ButterKnife-無盡之刃-繫結檢視控制元件和事件的快速開發工具
阿新 • • 發佈:2019-01-02
簡單介紹
Butter knife是大神JakeWharton的一款Android利器,多數開發者都應該瞭解和使用過,這把黃油刀最大的吸引人的地方就是簡化了android程式編寫中的view,findviewById(id)和setOnxxxListener事件的寫法,它使用了一種很簡潔的註解寫法,例如
你會發現沒有了findviewById這種超累的程式碼片段了,哈哈,這就值得讓我們為這把黃油刀點贊!
簡單使用
1.先下載butterknife的jar包,本文示例程式碼用的是版本7.0.1,可能與舊版本有些方法名不一樣。如果用的是as:直接用gradle:
compile 'com.jakewharton:butterknife:7.0.1'
@bind方式就是簡化了findviewbyid的程式碼,但在使用之前,一定要在Acivity中初始化Butterknife.bind(activity)。
先上本地demo的activity_main.xml,你可以直接跳過這段,沒有具體的內容,主要是看這麼引用這些控制元件的id.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".ExampleActivity"> <LinearLayout android:id="@+id/layout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/app_title_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="123" android:gravity="center" android:textSize="20sp" /> <Button android:id="@+id/bind_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/bind_me" /> <TextView android:id="@+id/text_content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/cool_text" android:textSize="20sp" android:visibility="invisible" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/layout1" android:background="#ADE8BA" android:orientation="vertical"> <fragment android:id="@+id/example_fragment" android:name="org.jan.butterknife.demo.ExampleFragment" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </RelativeLayout>
ExampleActivity,先看看我們怎麼使用butter knife獲取控制元件引用,以及快速註冊點選事件的。
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.Bind;
import butterknife.BindString;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnLongClick;
import static android.widget.Toast.LENGTH_SHORT;
/**
* butterknife的簡單使示例程式碼
*/
public class ExampleActivity extends AppCompatActivity {
/**
* 2:7.0+版本的butterKnife將使用bind註解
* 注:因為註解用到了反射機制,所以這裡的所有用到butterKnife的註解的變數都是非private的
*/
@Bind(R.id.bind_btn)
Button button;
@Bind(R.id.text_content)
TextView mCoolText;
@Bind(R.id.app_title_text)
TextView mTitleText;
//繫結預定義的字串資源,還有其他的一些方法如:@BindBool, @BindColor, @BindDimen, @BindDrawable, @BindInt
@BindString(R.string.butterknife_demo)
String title;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.將繫結該Activity
ButterKnife.bind(this);
//3.已經不再需要一個個findviewbyid了,可以直接呼叫,非常省心
userFieldToDo();
}
private void userFieldToDo() {
button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
mTitleText.setText(title);
mCoolText.setText("bind textview");
}
/**
* [email protected]可以根據view's id來註冊一個點選事件
* 方法引數是可選的,可以傳一個view,或者widget,
* 這裡是無參的,你可以寫成onClickBindButton(View view)或onClickBindButton(Button btn)
*/
@OnClick(R.id.bind_btn)
void onClickBindButton() {
mCoolText.setVisibility(View.VISIBLE);
Toast.makeText(this, "I bind it!", LENGTH_SHORT).show();
}
/**
* 繫結長按事件,這裡要有返回一個boolean值,預設為false
* @return
*/
@OnLongClick(R.id.bind_btn)
boolean onLongClickBindButton(){
Toast.makeText(this, "Let me go!", LENGTH_SHORT).show();
return true;
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
}
其實就是兩個步驟:1.初始化butterknife
2.bind所需要的widget
3.在fragment中的話可以選擇解除繫結。
這樣寫到底有沒有用呢?看看效果吧,別搞了半天還是奔潰的。
果然是可行的,好東西果斷要分享啊!
2.可能有人會有疑問,在Activity中這樣做是可行的,但如果換在Fragment中或者listview的Adapter中,是否也可以用butterknife來簡化程式碼呢,答案是肯定可以的。
**
* 在fragment中的butterknifey運用
*/
public class ExampleFragment extends Fragment {
// @Bind(R.id.fragment_title)
TextView mTitleText;
@Bind(R.id.example_listview)
ListView mListview;
public ExampleFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_example, container, false);
//1.bind方法很是很靈活的
ButterKnife.bind(this, view);
//2.如果遇到必須要利用findviewbyid的方式來引用某個view的話,你可以使用下面這種方式
mTitleText = ButterKnife.findById(view,R.id.fragment_title);
mTitleText.setGravity(Gravity.CENTER_HORIZONTAL);
mTitleText.setText("Example Fragment");
SimpleAdapter adapter = new SimpleAdapter(getContext());
mListview.setAdapter(adapter);
return view;
}
//給listview註冊了一個onItemClick事件,這裡的會傳入一個position
@OnItemClick(R.id.example_listview)
void onItemClick(int position){
String item = mListview.getAdapter().getItem(position).toString();
Toast.makeText(getContext(),"i clicked "+item,Toast.LENGTH_SHORT).show();
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
//2.解除繫結
ButterKnife.unbind(this);
}
}
fragment_example.xml 這是fragment的佈局檔案,就是展示一個簡單的listview.
<FrameLayout 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"
tools:context="org.jan.butterknife.demo.ExampleFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/fragment_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ListView
android:id="@+id/example_listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#FFFFFF"
android:dividerHeight="1dp" />
</LinearLayout>
</FrameLayout>
Listview使用的SimpleAdapter.java
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.BindDrawable;
import butterknife.ButterKnife;
public class SimpleAdapter extends BaseAdapter {
private static final String[] CONTENTS =
"誰也 跟不上 我的 節奏 德瑪西亞 啦啦 啦啦啦".split(" ");
private final LayoutInflater inflater;
public SimpleAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
@Override public int getCount() {
return CONTENTS.length;
}
@Override public String getItem(int position) {
return CONTENTS[position];
}
@Override public long getItemId(int position) {
return position;
}
@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.simple_list_item, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
}
String s = getItem(position);
holder.word.setText(s);
holder.imageView.setBackground(holder.defaultImage);
return view;
}
/**
* 看ViewHolder的變數就知道我們又省去在getview方法裡不停的findviewbyid了
*/
static class ViewHolder {
@Bind(R.id.hehe_image)
ImageView imageView;
@Bind(R.id.hehe_text)
TextView word;
@BindDrawable(R.drawable.main_icon_service)
Drawable defaultImage;
ViewHolder(View view) {
//這裡黃油刀在建構函式中久把fragment中的檢視綁定了
ButterKnife.bind(this, view);
}
}
}
simple_list_item.xml 這是list_item的佈局。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/hehe_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/hehe_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test"
android:textSize="16sp" />
</LinearLayout>
還有一些事件的寫法我這裡就不一一舉例了。詳細的使用我們可以看--->DOC<-----
最後,謝謝閱讀。