1. 程式人生 > >ButterKnife框架使用詳解

ButterKnife框架使用詳解


一、     什麼是ButterKnife

ButterKnife是一個支援View注入的框架。以前總是要寫很多findViewById來找到View物件,有了ButterKnife可以很輕鬆的省去這些步驟。

是大神JakeWharton的力作,目前使用很廣。最重要的一點,使用ButterKnife對效能基本沒有損失,因為ButterKnife用到的註解並不是在執行時反射的,而是在編譯的時候生成新的class。(xUtils的注入都是執行時反射,對效能影響很大。)

ButterKnife目前的最新版本是7.0.1。

Butter Knife 的特性

    支援 Activity 中的 View 注入

    支援 View 中的 View 注入

    支援 View 事件回撥函式注入

目前支援如下事件回撥函式:

    View: @OnLongClick and @OnFocusChanged.

    TextView: @OnEditorAction.

    AdapterView: @OnItemClick and @OnItemLongClick.

    CompoundButton: @OnCheckedChanged.

二、     使用ButterKnife繫結View

在gradle中新增依賴

compile 'com.jakewharton:butterknife:7.0.1'

2.1       在Activity中注入(從7.0.0開始稱繫結更合適)

package com.qianfeng.butterknifedemo;
  
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
  
import butterknife.Bind;
import butterknife.ButterKnife;
  
public class MainActivity extends AppCompatActivity{
    //給指定的TextView繫結id
    @Bind(R.id.tv)
    TextView tv;
    //給指定的Button繫結id
    @Bind(R.id.btn)
    Button btn;
  
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
         ButterKnife.bind(this);
  
        tv.setText("哈哈");
        btn.setText("呵呵呵");
    }
}

注意:需要繫結的控制元件不能是private和static的

2.2       在Fragment中繫結

package com.qianfeng.butterknifedemo;
  
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
  
import butterknife.Bind;
import butterknife.ButterKnife;
  
  /**
 * A simple {@link Fragment} subclass.
 */
  public class BlankFragment extends Fragment{
    @Bind(R.id.f_tv)
    TextView f_tv;
  
    @Bind(R.id.f_btn)
    Button f_btn;
  
    public BlankFragment(){
        // Required empty public constructor
    }
  
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState){
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }
  
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState){
//繫結
        ButterKnife.bind(this, view);
        f_tv.setText("最新的資料");
        f_btn.setText("最新的資料");
    }
}

2.3       在ViewHolder中繫結

    static class ViewHolder {
        @InjectView(R.id.person_name)
        TextView name;
        @InjectView(R.id.person_age)
        TextView age;
        @InjectView(R.id.person_location)
        TextView location;
        @InjectView(R.id.person_work)
        TextView work;
        public ViewHolder(View view) {
            //繫結
            ButterKnife.inject(this, view);
        }
    }

注意:我們在ViewHolder中添加了一個有View引數的構造方法,以後再也不需要在getView方法中findViewById了

三、     使用ButterKnife繫結事件回撥方法

@OnClick({R.id.btn})
  public void ok(){ //方法形參列表中可以有View也可以沒有
    Toast.makeText(this, "點選了Activity中的按鈕", Toast.LENGTH_SHORT).show();
  }

也可以多個View控制元件的點選事件繫結在一個方法中。

除了點選事件@OnClick,還有ListView的點選@OnItemClick, CheckBox的@OnCheckedChanged等等.

四、     把多個View放在一起組成View List

@Bind({R.id.btn,R.id.tv})  //把多個View放入List集合中
List<View> views;

五、     ButterKnife的Apply方法

apply方法可以對指定的list集合中的View進行批量操作

共有三個過載方法:

其中Action和Setter是ButterKnife的內部介面。

例如:對views集合中所有 的view都會分別指向applay中的方法。

ButterKnife.apply(views, new ButterKnife.Action<View>(){
    @Override
    public void apply(View view, int index){
        TextView tv1 = (TextView) view;
        tv1.setText("aabbbaa");
    }
});
ButterKnife.apply(views, new ButterKnife.Setter<View, String>(){
  
    @Override
    public void set(View view, String value, int index){
  
    }
}, "aaaaa");

六、     ButterKnife一些其他常用方法

1、         解除繫結

@Override
  protected void onDestroy(){
    super.onDestroy();
    //解綁。  即把上面繫結的view全部置為null
    ButterKnife.unbind(this);
  
  }

2、         選擇性繫結。

預設情況下繫結View和事件的時候,控制元件的id是必須存在的,否則會丟擲異常。  選擇性繫結可以做到如果id存在就繫結,否則不繫結,不丟擲任何異常。  想達到這樣的想過只需要在@bind 或@onClick前新增@null即可

@Nullable @Bind(R.id.f_tv)
TextView tv;

@OnItemSelected(R.id.list_view)

void onItemSelected(int position) {

  // TODO ...

}

@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)

void onNothingSelected() {

  // TODO ...

}

4、         findById方法。以前我們呼叫findViewById需要進行強制型別轉換。使用它可以免除強制型別轉換,可以自動完成型別轉換。

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);

六、     在Android studio中使用外掛自動生成ButterKnife需要的程式碼

使用外掛:AndroidButterKnife Zelezny