選擇ButterKnife,告別findViewById

JYcoder發表於2018-03-31

安卓基礎開發庫,讓開發簡單點。
DevRing & Demo地址github.com/LJYcoder/De…

學習/參考地址:
http://www.jianshu.com/p/9ad21e548b69
http://www.cnblogs.com/zhaoyanjun/p/6016341.html

前言

ButterKnife是一個資源繫結框架,它使用註解來進行資源繫結、監聽事件繫結的操作,可以幫我們省去findViewById、setXXXListener等繁瑣的程式碼。使用方便,不影響效能(編譯時就生成相應檔案),提高開發效率。


介紹

下面從 配置、使用、外掛、混淆 這幾個部分來介紹。

1. 配置

在Module下的build.gradle中新增

//ButterKnife注入
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
複製程式碼

2. 使用

使用流程可以分成 設定資源繫結、設定監聽繫結、開啟繫結

2.1 設定資源繫結

2.1.1繫結檢視 @BindView( ) / @BindViews( )

  • 使用@BindView( )繫結單個檢視
@BindView(R.id.rv_collect)
RecyclerView mRvCollect;
複製程式碼
  • 使用@BindViews( )繫結一組檢視 bindviews設定屬性
@BindViews({ R2.id.tv_name, R2.id.tv_age,  R2.id.tv_introduce })  
List<TextView> buttonList ;  
複製程式碼

另外,ButterKnife提供了apply方法,可對一組檢視進行操作。
1)對一組檢視進行操作(不傳值)

ButterKnife.apply(@NonNull List< T> list, @NonNull Action< ? super T> action)
複製程式碼
@BindViews({ R2.id.tv_name, R2.id.tv_age,  R2.id.tv_introduce })  
List<TextView> listTv;  

//統一把文字顏色設為紅色
ButterKnife.Action<TextView> SET_COLOR =new ButterKnife.Action<TextView>() {
    @Override
    public void apply(@NonNull TextView textView, int index) {
        textView.setTextColor(Color.RED);
    }
};

ButterKnife.apply(listTv, SET_COLOR);
複製程式碼

2)對一組檢視進行操作(傳值)

ButterKnife.apply(@NonNull List<T> list, @NonNull Setter<? super T, V> setter, V value)
複製程式碼
@BindViews({ R2.id.tv_name, R2.id.tv_age,  R2.id.tv_introduce })  
List<TextView> listTv;  

List<String> listTitle= Arrays.asList(new String[]{"姓名","年齡","介紹"});
//按順序取出標題寫入TextView
ButterKnife.Setter<TextView, List<String>> SET_TEXT = new ButterKnife.Setter<TextView, List<String>>() {
    @Override
    public void set(@NonNull TextView textView, List<String> listTitle, int index) {
        textView.setText(listTitle.get(index));
    }
};

ButterKnife.apply(listTv, SET_TEXT, listTitle);

複製程式碼

3)對一組檢視的Property屬性進行操作

ButterKnife.apply(listTv, View.ALPHA, 0.3f);
複製程式碼

2.1.2 繫結字串 @BindString( ) / @BindArray( )

  • 使用BindString( )繫結單個字串資源
@BindString(R.string.tip)
String tip;
複製程式碼
  • 使用@BindArray( )繫結一組字串資源
@BindArray(R.array.tips)
String[] tips ;
複製程式碼

2.1.3 繫結顏色值 @BindColor( )

@BindColor(R.color.theme)
int themeColor;
複製程式碼

2.1.4 繫結圖片 @BindBitmap( )

@BindBitmap(R.mipmap.ic_launcher)
Bitmap appLogo ;
複製程式碼

2.1.5 注意

  1. 使用註解宣告的資源變數,不能用private或static修飾,否則會保錯。
  2. 當指定資源id對應的View找不到時,會丟擲異常,可以加多個@Nullable註解來宣告變數,以防止崩潰(建議使用Android註解庫“support-annotations”中的@Nullable)

2.2 設定監聽繫結

定義一個方法,用相關注解進行監聽事件的繫結,

2.2.1 點選事件 @OnClick( )

@OnClick(R.id.btn1)  
public void show1(){  
    Toast.makeText(this, "onClick", Toast.LENGTH_SHORT).show();  
} 
複製程式碼

2.2.2 長按事件 @OnLongClick( )

@OnLongClick(R.id.btn2)  
public void show2(){  
    Toast.makeText(this, "onLongClick", Toast.LENGTH_SHORT).show();  
} 
複製程式碼

2.2.3 多個控制元件繫結一個事件

以onclick事件舉例。
方法可以定義適當的引數,它將會被自動轉化。

@OnClick( {R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4} )  
public void onViewClicked(View view) {  
    switch (view.getId()) {  
        case R.id.btn1:  
            Toast.makeText(this, "onclick1", Toast.LENGTH_SHORT).show();  
            break;  
        case R.id.btn2:  
            Toast.makeText(this, "onclick2", Toast.LENGTH_SHORT).show();  
            break;  
        case R.id.btn3:  
            Toast.makeText(this, "onclick3", Toast.LENGTH_SHORT).show();  
            break;  
        case R.id.btn4:  
            Toast.makeText(this, "onclick4", Toast.LENGTH_SHORT).show();   
            break;  
    }  
}  
複製程式碼

2.2.4 其他事件

除了點選事件和長按事件,ButterKnife還提供了很多點選事件,比如
@OnCheckedChanged(),
@OnEditorAction(),
@OnFocusChange(),
@OnItemClick(),
@OnItemLongClick(),
@OnItemSelected(),
@OnPageChange() 等

2.2.5 注意

  1. 使用註解宣告的監聽方法,不能用private或static修飾,否則會保錯。
  2. 當指定資源id對應的View找不到時,會丟擲異常,可以加多個@Optional註解來宣告方法,以防止崩潰

2.3 開啟繫結

設定完資源繫結和監聽事件繫結後,需要通過ButterKnife.bind()方法開啟繫結,呼叫該方法後,對應的資源和監聽事件就會開始進行注入繫結。

2.3.1 在Activity中開啟繫結

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  
    //在setContentView後呼叫
    ButterKnife.bind(this);  
}  
複製程式碼

2.3.2 在Fragment中開啟繫結

在Fragment中開啟繫結後,需要在檢視銷燬時進行解綁操作。

private Unbinder unbinder; 
 
@Override  
public View onCreateView(LayoutInflater inflater, ViewGroup container,  
                         Bundle savedInstanceState) {  
    View view = inflater.inflate(R.layout.fragment, container, false);  
    
    //返回Unbinder值用於解綁
    //這裡呼叫的方法與Activity呼叫的有區別  
    unbinder = ButterKnife.bind(this, view);  
    return view;  
}  

@Override  
public void onDestroyView() {  
    super.onDestroyView();  
    //解綁
    unbinder.unbind();  
}  
複製程式碼

2.3.3 在ViewHolder中開啟繫結

使用列表控制元件時,常常用到ViewHolder,可以通過以下方式進行繫結

//來自http://www.jianshu.com/p/9ad21e548b69

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);
        }
    }
}
複製程式碼

3. 外掛

zelezny外掛可以快速自動生成ButterKnife繫結相關的程式碼。
1.先通過Android Studio ---> Setting---> Plugins ---> Browse Responsitories ---> 搜尋zelezny並下載,下載後請重啟Android Studio。

下載外掛
2.右鍵R.layout.xxxx,點選Generate--->Generate ButterKnife Injections,選擇目標View,即可生成相應的程式碼。
外掛使用1
外掛使用2

4. 混淆

在proguard-rules.pro檔案中新增以下內容進行混淆配置

#butterknife開始
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * { @butterknife.* <fields>;}
-keepclasseswithmembernames class * { @butterknife.* <methods>;}
#butterknife結束
複製程式碼

相關文章