android注入之ButterKnife的使用

pszh發表於2016-04-22

注入的話相信大家應該都是很熟悉的,他不僅把程式碼的結構簡潔化,還能減少很大一部分的findviewByid的程式碼量 ,但是平時看到的注入都是封裝在一個大的框架中的,比如xUtils,這裡我們來介紹下一個獨立的小框架 .jar包的下載地址 (這裡說的是5.0的包)

1.配置Eclipse

在使用ButterKnife需要先配置一下Eclipse。

專案右鍵-Properties-Java Complier-Annotation Processing 確保設定和下圖一致


接著展開Annotation Processing選擇Factory Path,選中Enable project specific settings。然後點選 Add JARs…,選中ButterKnife的jar包


然後點選ok儲存設定,Eclipse將問你是否重新構建新專案,點選Yes。

確保你專案的根目錄裡有一個.apt_generated的資料夾,資料夾中包含YOURACTIVITY$$ViewInjector.java這樣的檔案。


2 使用註解

2.1 在Activity中使用註解

1
2
3
4
5
6
7
8
9
10
11
12
class ExampleActivity extends Activity {
  @InjectView(R.id.title) TextView title;
  @InjectView(R.id.subtitle) TextView subtitle;
  @InjectView(R.id.footer) TextView footer;
 
  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_activity);
    ButterKnife.inject(this);
    // TODO Use "injected" views...
  }
}

2.2 Fragment中使用註解

1
2
3
4
5
6
7
8
9
10
11
public class FancyFragment extends Fragment {
  @InjectView(R.id.button1) Button button1;
  @InjectView(R.id.button2) Button button2;
 
  @Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.inject(this, view);
    // TODO Use "injected" views...
    return view;
  }
}

2.3 Adapter中使用註解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 convertView;
  }
 
  static class ViewHolder {
    @InjectView(R.id.title) TextView name;
    @InjectView(R.id.job_title) TextView jobTitle;
 
    public ViewHolder(View view) {
      ButterKnife.inject(this, view);
    }
  }
}

2.4事件注入

點選事件注入

1
2
3
4
@OnClick(R.id.submit)
public void sayHi(Button button) {
  button.setText("Hello!");
}

多個控制元件具有相同的事件

1
2
3
4
5
6
7
8
@OnClick({ R.id.door1, R.id.door2, R.id.door3 })
public void pickDoor(DoorView door) {
  if (door.hasPrizeBehind()) {
    Toast.makeText(this"You win!", LENGTH_SHORT).show();
  else {
    Toast.makeText(this"Try again", LENGTH_SHORT).show();
  }
}

2.5重置注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class FancyFragment extends Fragment {
  @InjectView(R.id.button1) Button button1;
  @InjectView(R.id.button2) Button button2;
 
  @Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.inject(this, view);
    // TODO Use "injected" views...
    return view;
  }
 
  @Override void onDestroyView() {
    super.onDestroyView();
    ButterKnife.reset(this);
  }
}

2.6 可選注入

預設情況下@InjectView@OnClick注入是必選的,如果view未找到將出現異常。為了避免出現異常,新增一個@Optional註解。

2.7其它

ButterKnife還包含了兩個findById方法。

1
2
3
4
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);

3 混淆

為避免混淆的時程式碼被移除,所以要在proguard-project.txt中新增如下程式碼避免混淆

1
2
3
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector { *; }
-keepnames class * { @butterknife.InjectView *;}

擴充套件閱讀

Butterknife

Butterknife中文 

版本7.0.0中,現在註解已經不叫@InjectView了,而叫@Bind,感覺更貼合語義。同時註冊的方式也從

ButterKnife.inject(this);

變成了

ButterKnife.bind(this);

關於7.0.0的ButterKnife的各種用法和功能,可以參考ButterKnife的github上的主頁:

http://jakewharton.github.io/butterknife/


注,在windows下,某些eclipse版本無法選擇 Compiler/Annotation Processing"。下面是兩個版本的比較。

adt-bundle-windows-x86_64-20140702 (較新的版本,不可以)
adt-bundle-windows-x86_64-20131030 (2013年的版本,可以)

原因是谷歌在bundled版本中移除了Annotation Processing 選項,目的是為了鎖定到他們自己新出的註解系統中: /extras/android/support/annotations/android-support-annotations.jar

github上的解決辦法是安裝如下圖所示的東西:

當然換成android studio應該更好解決

可以讓你在新增Butterkinfe註解時偷偷懶,直接點選幾下滑鼠既可以完成註解的增加,同時還是圖形化的操作,可以說,大大的減輕了開發負擔。尤其是當你的layout中有很多很多的view需要通過findviewbyid來獲得引用時。實際上如果不用這個外掛而通過手打加ButtefKnife註解的方式,要是view很多啟示也挺麻煩的,不是嗎?

 

首先看看如何在Android Studio上安裝該外掛,直接看圖:


安裝好後需要restart你的Android Studio。

在使用此外掛前,需要已經匯入了butterknife的jar(或者在build.gradle中已經加入:compile'com.jakewharton:butterknife:7.0.0'

 

隨後,在你需要匯入註解的Activity或者Fragment或者ViewHolder的layout資原始碼上,右擊,選擇 Generate 然後Generate ButterKnife Injections,這時候生成類似於下列的選擇框:


Element為view的型別,ID為layout中資源的id名字,Variable Name即為你在程式碼中引用出來的變數名,點選Confirm後即可。(具體的操作還可以檢視http://blog.csdn.net/cxc19890214/article/details/47430547

 

下面是Android ButterKnife Zelezny的github上的一個動態使用流程圖:



相關文章