Android Study 之 初識ButterKnife(8.5.1)及簡單運用

<font color=FF0000> LZ-Says:給大家推薦一個網(wǎng)站,有興趣可以查閱外邓,想為大家貢獻一點自己的力量也可以投稿,老大審核通過會發(fā)表席镀,更好的幫助有需要的人歡迎大家踴躍投稿地址如下:
http://www.123si.org/android

突然間不知道說什么好豪诲,祝大家編碼無bug吧~

前言

話說服赎,Android開發(fā)的兄弟們都知道,每次初始化控件缺厉,設(shè)置相應(yīng)的事件,寫的那點過程多而且惡心辐脖。我們先一塊回顧下不堪的曾經(jīng)~

那些年嗜价。。奴拦。

那些年,我們是這樣初始化控件:

// 每次的習(xí)慣上來寫一個initView()方法
tvContent = (TextView) findViewById(R.id.btn_content);
// 遇到項目大的時候暂氯,這里面的東西,也曾占據(jù)半壁江山辣吃。神得。宵蕉。苦不堪言
// 當(dāng)然也曾封裝過方法缝左,避免各種findViewById,但是依舊如此。碌上。馏予。

那些年,我們是這樣設(shè)置事件:

tvContent.setOnClickListener(this);
// 當(dāng)然蛹尝,LZ的習(xí)慣依舊扔到initView中,讓他們盡情的浪蕩愕难,放縱~

<font color=FF0000 >But,騷年饵骨,身為一個Android開發(fā)妖混,你還能繼續(xù)忍受這種不堪的摧殘么制市?</font>

答案當(dāng)然不能!

那么误褪,接下來為大家?guī)硪粋€神器,助我們開發(fā)高效嘀略,快捷~

ButterKnife 閃亮登場

ButterKnife 初識

ButterKnife,又被戲稱為黃油刀讼育,至于為什么被戲稱為這個稠集,大家可以看下面附上的從官方截取的icon~

這里寫圖片描述

一塊桌布忧饭,一個盤子,一個Android小機器人形狀的黃油吼砂,一把刀渔肩。這些合起來被大家戲稱為黃油刀抹剩。(我說呢,糾結(jié)我半天蛉艾,都搞不懂黃油刀是個什么鬼拓瞪,這次曉得了)

icon下面簡單解釋就是為Android 視圖(View)提供綁定字段和方法。 也就是說,我們今后可以通過這把刀去替換之前瑣碎的初始化~

大家有興趣的也可以去官網(wǎng)上看看矢空,下面為大家附上官網(wǎng)地址以及GitHub地址捎帶的附帶個api地址。

官方地址:http://jakewharton.github.io/butterknife/

GitHub地址:https://github.com/JakeWharton/butterknife

API訪問地址:http://jakewharton.github.io/butterknife/javadoc/

話說酿箭,簡單了解之后,還是來點干貨吧~不然說不過去哈

首先我們要明白妇蛀,ButterKnife 是出自Android大神JakeWharton之手的一個開源庫,它的作用就是通過注解綁定視圖的方法纵诞,從而簡化代碼量(減少我們當(dāng)年findViewById以及設(shè)置事件時編寫的大量代碼)登刺。

而我們使用一個東西塘砸,必須要知道他的優(yōu)勢在哪兒?我用它能給我?guī)硎裁捶奖阒幣危磕敲唇酉聛眚燃#覀兛纯催@把“黃油刀”有著什么樣的優(yōu)勢,從而能簡化我們一些代碼珍策?

ButterKnife 優(yōu)勢

1. 強大的View綁定,Click事件處理功能以及資源內(nèi)容蹭劈,簡化代碼铺韧,提升開發(fā)效率割卖;

2. 方便的處理Adapter里的ViewHolder綁定問題罢维;

3. 運行時不會影響APP效率匀借,使用配置方便;

4. 代碼清晰是鬼,可讀性強。

了解完ButterKnife優(yōu)勢后囤耳,懷著好奇心,我們看看他都支持哪兒些方面,換句話說就是萄窜,我們開發(fā)過程中,在什么情況下可以通過使用ButterKnife去減少我們曾經(jīng)的代碼量穗泵?

ButterKnife 使用場景

  • View(視圖)綁定:例如初始化控件;
  • 資源綁定:例如color,string等尺棋;
  • 非Activity綁定:這里值得是當(dāng)時用 fragment 的時候成福;
  • View List 綁定: Adapter 中 ViewHolder,具體使用會在下方講解蕴潦;
  • Listener 綁定:這個就好理解了,也就是平時控件所需監(jiān)聽事件。

ButterKnife 語法

1. activity fragment 綁定與 fragment解綁

想要使用ButterKnife蜜猾,簡單配置之后秀菱,我們還需要在Activity中onCreate()綁定,如下:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 必須在setContentView()之后綁定
        ButterKnife.bind(this); 
    }

而如果使用fragment蹭睡,官方給出的綁定以及解綁如下:

public class FancyFragment extends Fragment {
  @BindView(R.id.button1) Button button1;
  @BindView(R.id.button2) Button button2;
  private Unbinder unbinder;

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    // 綁定
    unbinder = ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }

  @Override public void onDestroyView() {
    super.onDestroyView();
    // 解綁
    unbinder.unbind();
  }
}

綁定之后衍菱,我們一起來看看,常用的幾種監(jiān)聽通過使用ButterKnife之后肩豁,我們又該如何編寫相關(guān)事件呢?別急,往下看~

2.單擊事件

首先我們先看看人家表層提供我們代碼中搬葬,我們可以得到哪兒些對我們有用的信息

這里寫圖片描述

首先明確码倦,targetType(目標(biāo)類型)為View歧沪,setter為setOnClickListener(單擊事件監(jiān)聽)迈着,type為ButterKnife封裝的單擊事件(butterknife.internal.DebouncingOnClickListener)影钉,而method中則是name為doClick以及parameters為View類型的倆個參數(shù);而下面的interface接口中需要我們傳遞一個id。

簡單了解后,我們衍生出三種寫法迫吐,如下:

    // 寫法1
    @OnClick(控件ID)
    void 方法名() {
        //業(yè)務(wù)邏輯操作
    }
    
    // 寫法2
    @OnClick(控件ID)
    void 方法名(控件類型) {
        //業(yè)務(wù)邏輯操作
    }
    
    // 寫法3
    @OnClick(控件ID)
    void 方法名(View view) {
        //業(yè)務(wù)邏輯操作
    }

你可以按照上面指定一個個的寫,也可以綁定多個惊奇,如官網(wǎng)提供下面寫法:

這里寫圖片描述
這里寫圖片描述

3.長按事件

同樣依舊看人家怎么寫的房维,看看我們能了解到什么

這里寫圖片描述

和單擊事件對比脖阵,長按時間則多出了一個returnType(返回值),且默認為false啄踊。So,寫法如下~

    // 方法1
    boolean 方法名(){
        // 業(yè)務(wù)邏輯操作
        return false;
    }
    
    // 方法2
    boolean 方法名(控件類型){
        // 業(yè)務(wù)邏輯操作
        return false;
    }

    // 方法3
    boolean 方法名(View view){
        // 業(yè)務(wù)邏輯操作
        return false;
    }

4.Checked改變事件

老規(guī)矩:

這里寫圖片描述

改變,一般來說,會提供我們一個標(biāo)識喂柒,去方便我們根據(jù)不同的狀態(tài)去處理不同的邏輯,so...

    // 寫法1
    @OnCheckedChanged(控件ID)
    void radioButtonCheckChange(boolean isl) {
        // 業(yè)務(wù)邏輯
    }
    
    // 寫法2
    @OnCheckedChanged(控件ID)
    void radioButtonCheckChange(控件類型,boolean isl) {
        // 業(yè)務(wù)邏輯
    }

5.監(jiān)聽軟鍵盤右下角按鈕事件

老規(guī)矩:

這里寫圖片描述

so...經(jīng)過上面幾個大家可以知道覆劈,我們只需要對parameters以及是否是returnType重點關(guān)注即可。

    // 寫法1
    @OnEditorAction(控件ID)
    boolean 方法名() {
        // 業(yè)務(wù)邏輯操作
        return false;
    }

    // 寫法2
    // code:狀態(tài)碼
    @OnEditorAction(控件ID)
    boolean EditTextAction(int code) {
        // 業(yè)務(wù)邏輯操作
        return false;
    }

    // 寫法3
    // KeyEvent
    @OnEditorAction(控件ID)
    boolean EditTextAction(KeyEvent keyEvent) {
        // 業(yè)務(wù)邏輯操作
        return false;
    }

    // 寫法4
    @OnEditorAction(控件ID)
    boolean EditTextAction(int code, KeyEvent keyEvent) {
        // 業(yè)務(wù)邏輯操作
        return false;
    }

    // 寫法5
    @OnEditorAction(控件ID)
    boolean EditTextAction(TextView textView,int code, KeyEvent keyEvent) {
        // 業(yè)務(wù)邏輯操作
        return false;
    }

6. EditText內(nèi)容改變監(jiān)聽事件

由于源碼中內(nèi)容較長纵穿,不方便截圖拷淘,故截取部分代碼做解析昧互,如下:

@Target(METHOD)
@Retention(CLASS)
@ListenerClass(
    targetType = "android.widget.TextView",
    setter = "addTextChangedListener",
    remover = "removeTextChangedListener",
    type = "android.text.TextWatcher",   --->   這里同樣對之前的TextWatcher做了相關(guān)處理 ggg
    callbacks = OnTextChanged.Callback.class   --->   自定義枚舉,通過枚舉類型標(biāo)識當(dāng)前操作 666
)
public @interface OnTextChanged {
  /** View IDs to which the method will be bound. */
  @IdRes int[] value() default { View.NO_ID };   --->   需要傳入ID

  /** Listener callback to which the method will be bound. */
  Callback callback() default Callback.TEXT_CHANGED;  --->  未改變狀態(tài)

  /** {@link TextWatcher} callback methods. */
  enum Callback {  --->  枚舉中分為三種類似 未改變 改變前 改變后
    /** {@link TextWatcher#onTextChanged(CharSequence, int, int, int)} */
    @ListenerMethod(
        name = "onTextChanged",  --->  當(dāng)前標(biāo)識為 未改變
        parameters = {
            "java.lang.CharSequence",  --->  用戶輸入字符
            "int", --->  改變前個數(shù)
            "int", --->  測試時咨跌,返回0陋葡,沒整明白代表什么意思
            "int"  --->  根據(jù)打印結(jié)果,猜測這個應(yīng)該是每次增加內(nèi)容個數(shù)
        }
    )
    TEXT_CHANGED,

    /** {@link TextWatcher#beforeTextChanged(CharSequence, int, int, int)} */
    @ListenerMethod(
        name = "beforeTextChanged",  --->  當(dāng)前標(biāo)識為 改變前
        parameters = {
            "java.lang.CharSequence",  --->  用戶輸入字符
            "int", --->  改變前個數(shù)
            "int",
            "int"
        }
    )
    BEFORE_TEXT_CHANGED,

    /** {@link TextWatcher#afterTextChanged(android.text.Editable)} */
    @ListenerMethod(
        name = "afterTextChanged",  --->  當(dāng)前標(biāo)識為 改變后
        parameters = "android.text.Editable"  --->  用戶輸入字符
    )
    AFTER_TEXT_CHANGED, --->  我們關(guān)注的重點在此窒朋,每次只需要監(jiān)聽這個彩匕,去做相關(guān)處理即可
  }

從上得知座掘,關(guān)于EditText內(nèi)容改變事件蛾坯,我們關(guān)注點只在乎改變后的內(nèi)容格式(個數(shù))是否符合項目需求俐东,而其他可以暫時忽略萌焰,從而衍生下面寫法:

    // 內(nèi)容改變后監(jiān)聽
    // Editable editable:用戶輸入字符
    @OnTextChanged(value = 控件ID, callback = 監(jiān)聽類型留潦,改變后取值為:OnTextChanged.Callback.AFTER_TEXT_CHANGED)
    void editTextChangeAfter(Editable editable) {
        // 業(yè)務(wù)邏輯
    }

    // 內(nèi)容改變前監(jiān)聽
    @OnTextChanged(value = 控件ID, callback = 監(jiān)聽類型,改變前取值為:OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
    void editTextChangeBefore(CharSequence s, int start) {
        // 業(yè)務(wù)邏輯
    }

    // 內(nèi)容未發(fā)生改變監(jiān)聽
    @OnTextChanged(value = 控件ID, callback = 監(jiān)聽類型毡熏,取值為:OnTextChanged.Callback.TEXT_CHANGED)
    void editTextChange(CharSequence s, int start) {
        // 業(yè)務(wù)邏輯
    }

7. 焦點監(jiān)聽事件

老規(guī)矩:

這里寫圖片描述

由此可見,如下:

    @OnFocusChange(控件ID)
    void editTextFocus(boolean isl){
        // 業(yè)務(wù)邏輯
    }

8. 觸摸監(jiān)聽事件

老規(guī)矩:

這里寫圖片描述
這里寫圖片描述

寫法如下:

    @OnTouch(控件ID)
    boolean imageView(MotionEvent event){
        // 業(yè)務(wù)邏輯
        return false;
    }

9. item項單擊監(jiān)聽事件

老規(guī)矩:

這里寫圖片描述
這里寫圖片描述

so...

    @OnItemClick(控件ID)
    void listItemClick(int position){
        // 業(yè)務(wù)邏輯
    }

10. item項長按監(jiān)聽事件

老規(guī)矩:

這里寫圖片描述

so...

    @OnItemLongClick(R.id.listView)
    boolean listItemLongClick(int position) {
        Toast.makeText(this, "OnItemLongClick---點擊了第" + position + "個", Toast.LENGTH_SHORT).show();
        return true;
    }

ButterKnife 使用注意

1.Activity ButterKnife.bind(this) 必須在 setContentView() 之后,且父類 bind 綁定后构捡,子類不需要再 bind粗合;

2.Fragment 中使用需要傳入view:Fragment ButterKnife.bind(this, mRootView);

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

4.setContentView()不能通過注解實現(xiàn)。(其他的有些注解框架可以)

通過上面簡單介紹党巾,相信大家對這把刀已經(jīng)有了一個初步的理解,那么如何在Android Studio中通過使用這把刀從而改善我們的代碼呢芽隆?我們接著往下瞧。

Android Studio使用ButterKnife前期準備操作

想要在Android Studio中使用ButterKnife刀脏,首先需要下載安裝ButterKnife插件,之后經(jīng)過簡單配置之后方可使用~

第一步:Android Studio集成ButterKnife插件

1.點擊 File ---> Settings... ---> 選擇 Plugins(也可以使用<font color=#FF0000>快捷鍵 Ctrl+Alt+S)

這里寫圖片描述

2.輸入ButterKnife限书,選擇“Android ButterKnife Zelezny”秦躯,點擊安裝(LZ這里已經(jīng)安裝好了),稍后Android Studio會提示重啟AS普办,確認即可亮隙。

這里寫圖片描述
這里寫圖片描述

3.經(jīng)過以上簡單倆步,我們的Android Studio又get了新技能促王,那就是:<font color=#FF0000>支持ButterKnife插件犀盟!

第二步:配置ButterKnife

1.使用前,我們需要對ButterKnife進行簡單配置( 為我們的項目引入<font color=#FF0000>'com.jakewharton:butterknife-compiler:8.5.1'蝇狼,'com.jakewharton:butterknife:8.5.1' )</font>阅畴,引入過程如下所示:

這里寫圖片描述
這里寫圖片描述

這里寫圖片描述

2.引入完成之后,我們先來小試牛刀~得瑟得瑟

在MainActivity中的onCreate **右鍵layout迅耘,選擇Generate... 贱枣,Generate ButterKnife Injections,選擇要使用注解的控件颤专,點擊Confirm **

這里寫圖片描述

一鍵可視化操作纽哥,方便快捷~

進過上面的配置后,我們可以在項目中盡情的使用ButterKnife各種秀了~

刀法一部曲栖秕,玩轉(zhuǎn)常用事件監(jiān)聽

1.在MainActivity布局中新增幾個常用控件春塌,通過右鍵layout,選擇Generate... 簇捍,Generate ButterKnife Injections只壳,選擇要使用注解的控件,點擊Confirm 暑塑,從而生成我們接下來演示根本(后面會有所更改)吼句,如下圖所示~

這里寫圖片描述
這里寫圖片描述

接下來為大家演示相關(guān)事件使用,一點點玩轉(zhuǎn)黃油刀

1. 單擊事件(以TextView為例)

代碼如下:

    @OnClick(R.id.text)
    void textClick() {
        Toast.makeText(MainActivity.this, "TextView的單擊事件觸發(fā)梯投。命辖。。(無參-默認)", Toast.LENGTH_SHORT).show();
    }

    @OnClick(R.id.text)
    void textClick(TextView textView){
        Toast.makeText(MainActivity.this, "TextView的單擊事件觸發(fā)分蓖。。尔许。(TextView)", Toast.LENGTH_SHORT).show();
    }

    @OnClick(R.id.text)
    void textClick(View view){
        Toast.makeText(MainActivity.this, "TextView的單擊事件觸發(fā)么鹤。。味廊。(View)", Toast.LENGTH_SHORT).show();
    }

運行結(jié)果展示:

這里寫圖片描述

2. 長按事件(以Button為例)

代碼如下:

    @OnLongClick(R.id.button)
    boolean buttonLongClick(){
        Toast.makeText(MainActivity.this, "Button的長按事件觸發(fā)蒸甜。棠耕。。(無參-默認)", Toast.LENGTH_SHORT).show();
        return false;
    }

//    @OnLongClick(R.id.button)
//    boolean buttonLongClick(Button button){
//        Toast.makeText(MainActivity.this, "Button的長按事件觸發(fā)柠新。窍荧。。(TextView)", Toast.LENGTH_SHORT).show();
//        return false;
//    }

//    @OnLongClick(R.id.button)
//    boolean buttonLongClick(View view){
//        Toast.makeText(MainActivity.this, "Button的長按事件觸發(fā)恨憎。蕊退。。(View)", Toast.LENGTH_SHORT).show();
//        return false;
//    }

運行結(jié)果如下:

這里寫圖片描述

這里大家可能會問了憔恳,LZ你干嘛要把下面的注釋掉了呢瓤荔,是不是不能用呢?
確實钥组,一開始沒有注釋输硝,運行時候出現(xiàn)異常,提示如下:

Multiple listener methods with return value specified for ID:2131165193

LZ理解為程梦,這個監(jiān)聽只會為ID(2131165193)返回相應(yīng)監(jiān)聽点把,也就是一一對應(yīng)!so... <font color=#FF0000>一山不容二虎屿附,除非一公一母啊~

3. Checked改變事件(以CheckBox為例)

代碼如下:

    @OnCheckedChanged(R.id.checkBox)
    void radioButtonCheckChange(boolean isl) {
        Toast.makeText(MainActivity.this, "CheckBox郎逃。。拿撩。(無參)" + isl, Toast.LENGTH_SHORT).show();
    }

    @OnCheckedChanged(R.id.checkBox)
    void radioButtonCheckChange(CheckBox checkBox,boolean isl) {
        Toast.makeText(MainActivity.this, "CheckBox衣厘。。压恒。(CheckBox)" + isl, Toast.LENGTH_SHORT).show();
    }

運行結(jié)果如下:

這里寫圖片描述

4. 監(jiān)聽軟鍵盤右下角按鈕事件

代碼如下:

//    @OnEditorAction(R.id.tv_editor_action)
//    boolean EditTextAction() {
//        Toast.makeText(MainActivity.this, " 點擊---通往天堂 無參", Toast.LENGTH_SHORT).show();
//        return false;
//    }

//    @OnEditorAction(R.id.tv_editor_action)
//    boolean EditTextAction(int code) {
//        Toast.makeText(MainActivity.this, " 點擊---通往天堂 code:"+code, Toast.LENGTH_SHORT).show();
//        return false;
//    }

//    @OnEditorAction(R.id.tv_editor_action)
//    boolean EditTextAction(KeyEvent keyEvent) {
//        Toast.makeText(MainActivity.this, "點擊---通往天堂 KeyEvent:"+keyEvent, Toast.LENGTH_SHORT).show();
//        return false;
//    }

//    @OnEditorAction(R.id.tv_editor_action)
//    boolean EditTextAction(int code, KeyEvent keyEvent) {
//        Toast.makeText(MainActivity.this, "點擊---通往天堂 code:"+code+" KeyEvent:"+keyEvent, Toast.LENGTH_SHORT).show();
//        return false;
//    }

    @OnEditorAction(R.id.tv_editor_action)
    boolean EditTextAction(TextView textView,int code, KeyEvent keyEvent) {
        Toast.makeText(MainActivity.this, textView.getText().toString()+" 點擊---通往天堂 code:"+code+" KeyEvent:"+keyEvent, Toast.LENGTH_SHORT).show();
        return false;
    }

運行效果下:

這里寫圖片描述

5. EditText內(nèi)容改變監(jiān)聽事件

代碼如下:

    @OnTextChanged(value = R.id.editText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
    void editTextChangeAfter(Editable editable) {
        Toast.makeText(MainActivity.this, "改變后內(nèi)容為:"+editable.toString(), Toast.LENGTH_SHORT).show();
        System.out.println("改變后---內(nèi)容為:"+editable.toString());
    }

    @OnTextChanged(value = R.id.editText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
    void editTextChangeBefore(CharSequence s, int start, int before, int count) {
        Toast.makeText(MainActivity.this, "編輯內(nèi)容為:"+s+"影暴,開始前個數(shù):"+start, Toast.LENGTH_SHORT).show();
        System.out.println("改變前---內(nèi)容為:"+s+",開始前個數(shù):"+start+"探赫,:"+before+"型宙,"+count);
    }

    @OnTextChanged(value = R.id.editText, callback = OnTextChanged.Callback.TEXT_CHANGED)
    void editTextChange(CharSequence s, int start, int before, int count) {
        Toast.makeText(MainActivity.this, "編輯內(nèi)容為:"+s+",開始前個數(shù):"+start, Toast.LENGTH_SHORT).show();
        System.out.println("未編輯---內(nèi)容為:"+s+"伦吠,開始前個數(shù):"+start+"妆兑,"+before+","+count);
    }

運行結(jié)果如下:

這里寫圖片描述

6.焦點監(jiān)聽事件

代碼如下:

    @OnFocusChange(R.id.editTextFocus)
    void editTextFocus(boolean isl) {
        if (isl) {
            Toast.makeText(MainActivity.this, "獲取焦點" + isl, Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, "失去焦點" + isl, Toast.LENGTH_SHORT).show();
        }
    }

運行結(jié)果如下:

這里寫圖片描述

7. 觸摸監(jiān)聽事件

代碼如下:

    @OnTouch(R.id.imageView)
    boolean imageView(MotionEvent event){
        System.out.println(event);
        return false;
    }

運行結(jié)果如下:

04-10 11:47:04.504 32627-32627/cn.hlq.butterknifestudy I/System.out: MotionEvent { action=<font color=#FF0000>ACTION_DOWN</font>, actionButton=0, id[0]=0, x[0]=189.8265, y[0]=148.42676, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=6743683, downTime=6743683, deviceId=1, source=0x1002 }

8. item單擊以及長按監(jiān)聽事件

代碼如下:

    @OnItemClick(R.id.listView)
    void listItemClick(int position){
        Toast.makeText(this,"OnItemClick---點擊了第"+position+"個",Toast.LENGTH_SHORT).show();
    }

    @OnItemLongClick(R.id.listView)
    boolean listItemLongClick(int position) {
        Toast.makeText(this, "OnItemLongClick---點擊了第" + position + "個", Toast.LENGTH_SHORT).show();
        return true;
    }

運行結(jié)果如下:

這里寫圖片描述

想必大家通過以上已經(jīng)掌握這套刀法基本使用了毛仪,那么上面曾說過搁嗓,還可以對Adapter進行改造,從而節(jié)省開發(fā)過程中一些編碼箱靴,那就一塊瞅瞅唄~

刀法二部曲腺逛,巧用Adapter

創(chuàng)建一個item_layout作為接下來演示用~

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:orientation="horizontal">

    <TextView
        android:id="@+id/item_username"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"/>

    <TextView
        android:id="@+id/item_userPwd"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_weight="1"/>

</LinearLayout>

很簡單,沒什么東西衡怀,接下來看adapter~

package cn.hlq.butterknifestudy.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import cn.hlq.butterknifestudy.R;
import cn.hlq.butterknifestudy.model.Student;

/**
 * Created by HLQ on 2017/4/11 0011.
 */

public class ListViewAdapter extends BaseAdapter {

    private Context context;
    private List<Student> stuList = new ArrayList<Student>();

    public ListViewAdapter(Context context, List<Student> stuList) {
        this.context = context;
        this.stuList = stuList;
    }

    @Override
    public int getCount() {
        return stuList != null ? stuList.size() : 0;
    }

    @Override
    public Object getItem(int position) {
        return stuList != null ? stuList.get(position) : null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (viewHolder == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item_listview_show, null);
            viewHolder = new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        Student stu = stuList.get(position);
        viewHolder.itemUsername.setText(stu.getUserName());
        viewHolder.itemUserPwd.setText(stu.getUserPwd());
        return convertView;
    }

    static class ViewHolder {
        @BindView(R.id.item_username)
        TextView itemUsername;
        @BindView(R.id.item_userPwd)
        TextView itemUserPwd;

        ViewHolder(View view) {
            ButterKnife.bind(this, view);
        }
    }
}

運行結(jié)果為:

這里寫圖片描述

在此告訴大家一個小秘密棍矛,你可以直接右鍵layout安疗,在生成注解時,選擇自動創(chuàng)建ViewHolder够委,如下圖:

這里寫圖片描述

是不是相當(dāng)方便荐类?

在此,順便捎帶腳的介紹下茁帽,如何使用這把刀玩玩資源內(nèi)容呢玉罐?

    // 初始化指定默認值
    @BindString(R.string.app_test)
    String titleContent; 

    lvTitle.setText(titleContent);

運行結(jié)果如下:

這里寫圖片描述

除以上,刀法中還包含對以下支持脐雪,大家有興趣自己了解即可厌小,沒什么難度了

這里寫圖片描述
這里寫圖片描述

而且官方上也提供了一些基本的使用,如下:

這里寫圖片描述
這里寫圖片描述

刀法三部曲BaseActivity封裝战秋,進一步簡化代碼

通常我們會封裝一個BaseActivity璧亚,里面寫好常用內(nèi)容,之后activity繼承此BaseActivity脂信。同樣我們也可以在此進行初始化癣蟋,避免我們多次初始化,看下面一波代碼~

package com.heliquan.butterknife.base;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * created by heliquan at 2017年4月14日
 */
public abstract class BaseActivity extends Activity {

    private Unbinder unbinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 必須重寫setContentView()的三個方法狰闪,不然會出現(xiàn)子類繼承無效疯搅,具體原因沒有深入了解
        setContentView(getContentViewId());
        unbinder = ButterKnife.bind(this);
    }

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        super.setContentView(layoutResID);
        unbinder = ButterKnife.bind(this);
    }

    @Override
    public void setContentView(View view) {
        super.setContentView(view);
        unbinder = ButterKnife.bind(this);
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        super.setContentView(view, params);
        unbinder = ButterKnife.bind(this);
    }

    /**
     * 獲取內(nèi)容id
     */
    protected abstract int getContentViewId();

    /**
     * 初始化View
     */
    protected abstract void initView();

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbinder.unbind();
    }

    /**
     * 根據(jù)id返回資源內(nèi)容
     *
     * @param context
     * @param strId
     * @return
     */
    protected String getStrResource(Activity activity, int strId) {
        return activity.getResources().getString(strId);
    }

    /**
     * 監(jiān)聽返回按鈕,點擊返回finish當(dāng)前頁面
     *
     * @param keyCode
     * @param event
     * @return
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

結(jié)束語

看到這里埋泵,想必大家已經(jīng)基本對這套刀法有所了解以及能夠基本運用了幔欧,感謝大家觀看,如有不到之處丽声,歡迎交流~

代碼查看以及下載地址

1.GitHub查看地址: https://github.com/HLQ-Struggle/ButterKnifeStudy礁蔗;

2.CSDN下載地址:http://download.csdn.net/detail/u012400885/9810345

參考資源地址

  1. 官方地址:http://jakewharton.github.io/butterknife/ 雁社;
  2. GitHub地址:https://github.com/JakeWharton/butterknife浴井;
  3. http://www.2cto.com/kf/201604/503479.html
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霉撵,一起剝皮案震驚了整個濱河市磺浙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌徒坡,老刑警劉巖撕氧,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異喇完,居然都是意外死亡呵曹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門何暮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奄喂,“玉大人需忿,你說我怎么就攤上這事叠纹。” “怎么了蛆挫?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵坏逢,是天一觀的道長域帐。 經(jīng)常有香客問我,道長是整,這世上最難降的妖魔是什么肖揣? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮浮入,結(jié)果婚禮上龙优,老公的妹妹穿的比我還像新娘。我一直安慰自己事秀,他們只是感情好彤断,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著易迹,像睡著了一般宰衙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上睹欲,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天供炼,我揣著相機與錄音,去河邊找鬼窘疮。 笑死袋哼,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的考余。 我是一名探鬼主播先嬉,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼楚堤!你這毒婦竟也來了疫蔓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤身冬,失蹤者是張志新(化名)和其女友劉穎衅胀,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酥筝,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡滚躯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掸掏。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡茁影,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丧凤,到底是詐尸還是另有隱情募闲,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布愿待,位于F島的核電站浩螺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仍侥。R本人自食惡果不足惜要出,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望农渊。 院中可真熱鬧患蹂,春花似錦、人聲如沸腿时。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽批糟。三九已至格了,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徽鼎,已是汗流浹背盛末。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留否淤,地道東北人悄但。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像石抡,于是被迫代替她去往敵國和親檐嚣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容