天天看點

Android開發第三方庫 -- ButterKnife使用詳解

寫在前面:該文檔使用7.0版本,8.0版本方法名有所改動,建議看官方文檔,整體業務邏輯和原理沒什麼變動;

在Android程式設計過程中,我們會寫大量的布局和點選事件,像初始view、設定view監聽這樣簡單而重複的操作讓人覺得麻煩類,是以可以采用注解的方式去實作,而ButterKnife則是注解中相對簡單易懂的很不錯的開源架構,而網上的文檔和例子都過時了,7.0之後的版本改動很大,之前的注解都不能用了,是以借鑒官方文檔總結了一下,接下來就介紹一下如何使用。基本參照官方文檔,加上自己的心得。

ButterKnife 優勢:

1.強大的View綁定和Click事件處理功能,簡化代碼,提升開發效率

2.友善的處理Adapter裡的ViewHolder綁定問題

3.運作時不會影響APP效率,使用配置友善

4.代碼清晰,可讀性強

使用心得:

1.Activity  ------  ButterKnife.bind(this);必須在setContentView();之後,且父類bind綁定後,子類不需要再bind

2.Fragment  ------  ButterKnife.bind(this, mRootView);

3.屬性布局不能用private or static 修飾,否則會報錯

4.setContentView()不能通過注解實作。(其他的有些注解架構可以)

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

使用步驟:

一.導入ButterKnife jar包:

1)如果你是Eclipse,可以去官網下載下傳jar包

2)如果你是AndroidStudio可以直接 File->Project Structure->Dependencies->Library dependency 搜尋butterknife即可,第一個就是

3)當然也可以用maven和gradle配置

MAVEN  
        <dependency>  
          <groupId>com.jakewharton</groupId>  
          <artifactId>butterknife</artifactId>  
          <version>(insert latest version)</version>  
        </dependency>  
      
    GRADLE  
    compile 'com.jakewharton:butterknife:(insert latest version)'  
      
    Be sure to suppress this lint warning in your build.gradle.(關閉)  
    lintOptions {  
      disable 'InvalidPackage'  
    }  
           

注意如果在Library 項目中使用要按如下步驟(github中有具體描述)否則無法找到view:

Android開發第三方庫 -- ButterKnife使用詳解

注:官網和github也有對應的引用步驟。

二.常見使用方法:

1)由于每次都要在Activity中的onCreate綁定Activity,是以個人建議寫一個BaseActivity完成綁定,子類繼承即可

     注:ButterKnife.bind(this);綁定Activity 必須在setContentView之後:

     實作如下(FragmentActivity 實作一樣):

public abstract class BaseActivity extends Activity {  
        public abstract int getContentViewId();  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(getContentViewId());  
            ButterKnife.bind(this);  
            initAllMembersView(savedInstanceState);  
        }  
      
        protected abstract void initAllMembersView(Bundle savedInstanceState);  
      
        @Override  
        protected void onDestroy() {  
            super.onDestroy();  
            ButterKnife.unbind(this);//解除綁定,官方文檔隻對fragment做了解綁  
        }  
    }  
           

2)綁定fragment

public abstract class BaseFragment extends Fragment {  
        public abstract int getContentViewId();  
        protected Context context;  
        protected View mRootView;  
      
        @Nullable  
        @Override  
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {  
            mRootView =inflater.inflate(getContentViewId(),container,false);  
            ButterKnife.bind(this,mRootView);//綁定framgent  
            this.context = getActivity();  
            initAllMembersView(savedInstanceState);  
            return mRootView;  
        }  
      
        protected abstract void initAllMembersView(Bundle savedInstanceState);  
      
        @Override  
        public void onDestroyView() {  
            super.onDestroyView();  
            ButterKnife.unbind(this);//解綁  
        }  
    }  
           

3)綁定view

@Bind(R.id.hello_world)  
    TextView mHelloWorldTextView;  
    @Bind(R.id.app_name)  
    TextView mAppNameTextView;//view  
           

4)綁定資源

@BindString(R.string.app_name)  
    String appName;//sting  
    @BindColor(R.color.red)  
    int textColor;//顔色  
    @BindDrawable(R.mipmap.ic_launcher)  
    Drawable drawable;//drawble  
    @Bind(R.id.imageview)  
    ImageView mImageView;  
    @Bind(R.id.checkbox)  
    CheckBox mCheckBox;  
    @BindDrawable(R.drawable.selector_image)  
    Drawable selector;  
           

5)Adapter ViewHolder 綁定

public class TestAdapter extends BaseAdapter {  
        private List<String> list;  
        private Context context;  
      
        public TestAdapter(Context context, List<String> list) {  
            this.list = list;  
            this.context = context;  
        }  
      
        @Override  
        public int getCount() {  
            return list==null ? 0 : list.size();  
        }  
      
        @Override  
        public Object getItem(int position) {  
            return list.get(position);  
        }  
      
        @Override  
        public long getItemId(int position) {  
            return position;  
        }  
      
        @Override  
        public View getView(int position, View convertView, ViewGroup parent) {  
            ViewHolder holder;  
            if (convertView == null) {  
                convertView = LayoutInflater.from(context).inflate(R.layout.layout_list_item, null);  
                holder = new ViewHolder(convertView);  
                convertView.setTag(holder);  
            } else {  
                holder = (ViewHolder) convertView.getTag();  
            }  
            holder.textview.setText("item=====" + position);  
            return convertView;  
        }  
      
        static class ViewHolder {  
            @Bind(R.id.hello_world)  
            TextView textview;  
      
            public ViewHolder(View view) {  
                ButterKnife.bind(this, view);  
            }  
        }  
    }  
           

6)點選事件的綁定:不用聲明view,不用setOnClickLisener()就可以綁定點選事件

a.直接綁定一個方法

@OnClick(R.id.submit)  
    public void submit(View view) {  
      // TODO submit data to server...  
    }  
           

b.所有監聽方法的參數是可選的

@OnClick(R.id.submit)  
    public void submit() {  
      // TODO submit data to server...  
    }  
           

c.定義一個特定類型,它将自動被轉換

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

d.多個view統一處理同一個點選事件,很友善,避免抽方法重複調用的麻煩

例子一:

@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();  
      }  
    }  
           

例子二:

@OnClick({ R.id.tv_text1, R.id.tv_text2, R.id.tv_text3, R.id.tv_text4 })  
    public void sayHi(Button button) {            //控件根據你所綁定的控件而定
        switch (button.getId()) {  
        case R.id.tv_text1:  
            button.setText("你按到我了啦1!");  
            Toast.makeText(this, "你按到我了啦1!", Toast.LENGTH_SHORT).show();  
            break;  
        case R.id.tv_text2:  
            button.setText("你按到我了啦2!");  
            Toast.makeText(this, "你按到我了啦2!", Toast.LENGTH_SHORT).show();  
            break;  
        case R.id.tv_text3:  
            button.setText("你按到我了啦3!");  
            Toast.makeText(this, "你按到我了啦3!", Toast.LENGTH_SHORT).show();  
            break;  
        case R.id.tv_text4:  
            button.setText("你按到我了啦4!");  
            Toast.makeText(this, "你按到我了啦4!", Toast.LENGTH_SHORT).show();  
            break;  
        default:  
            break;  
        }  
    }
           

 e.自定義view可以綁定自己的監聽,不指定id

public class FancyButton extends Button {  
      @OnClick  
      public void onClick() {  
        // TODO do something!  
      }  
    }  
           

f.給EditText加addTextChangedListener(即添加多回調方法的監聽的使用方法),利用指定回調,實作想回調的方法即可,哪個注解不會用點進去看下源碼上的注釋就會用了

@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)  
    void beforeTextChanged(CharSequence s, int start, int count, int after) {  
      
    }  
    @OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)  
    void onTextChanged(CharSequence s, int start, int before, int count) {  
      
    }  
    @OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)  
    void afterTextChanged(Editable s) {  
      
    }  
           

7)對一組View進行統一操作

a.裝入一個list

@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })  
    List<EditText> nameViews;  
           

b.設定統一處理

static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {  
      @Override public void apply(View view, int index) {  
        view.setEnabled(false);  
      }  
    };  
    static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {  
      @Override public void set(View view, Boolean value, int index) {  
        view.setEnabled(value);  
      }  
    };  
           

c.統一操作處理,例如設定是否可點,屬性等

[java] view plain copy

  1. ButterKnife.apply(nameViews, DISABLE);  
  2. ButterKnife.apply(nameViews, ENABLED, false);  

8)可選綁定:預設情況下,“綁定”和“監聽”綁定都是必需的。如果不能找到目标視圖,則将抛出異常。是以做空處理 [java] view plain copy

  1. @Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;  
  2. @Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {  
  3.   // TODO ...  
  4. }  

三、代碼混淆

-keep class butterknife.** { *; }  
    -dontwarn butterknife.internal.**  
    -keep class **$$ViewBinder { *; }  
      
    -keepclasseswithmembernames class * {  
        @butterknife.* <fields>;  
    }  
      
    -keepclasseswithmembernames class * {  
        @butterknife.* <methods>;  
    }  
           

四、Zelezny插件的使用

在AndroidStudio->File->Settings->Plugins->搜尋Zelezny下載下傳添加就行 ,可以快速生成對應元件的執行個體對象,不用手動寫。使用時,在要導入注解的Activity 或 Fragment 或 ViewHolder的layout資源代碼上,右鍵——>Generate——Generate ButterKnife Injections,然後就出現如圖的選擇框。(此動态圖來自官網)

Android開發第三方庫 -- ButterKnife使用詳解

轉載 http://blog.csdn.net/itjianghuxiaoxiong/article/details/50177549

繼續閱讀