日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Butterknife全方位解析

發布時間:2023/12/19 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Butterknife全方位解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

Butterknife是供職于Square公司的JakeWharton大神開發的開源庫,使用這個庫,在AS中搭配Android ButterKnife Zelezny插件,可以大大提高開發的效率,從此擺脫繁瑣的findViewById(int id),也不用自己手動@bind(int id) , 直接用插件生成即可。本篇博客將對Butterknife進行深入解析。

項目地址:?JakeWharton/butterknife

ButterKnife有以下優點:

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

2、方便的處理Adapter里的ViewHolder綁定問題

3、運行時不會影響APP效率,使用配置方便

4、代碼清晰,可讀性強

如何導入ButterKnife

在項目的build.grade文件中進行如下配置:

  • buildscript?{?
  • ????repositories?{?
  • ????????jcenter()?
  • ????????mavenCentral()?
  • ????????maven?{?
  • ????????????url?"https://plugins.gradle.org/m2/"?
  • ????????}?
  • ????}?
  • ????dependencies?{?
  • ????????classpath?'com.android.tools.build:gradle:2.2.0'?
  • ????????//這里配置?apt?供butterknife使用?
  • ????????classpath?'com.neenbedankt.gradle.plugins:android-apt:1.8'?
  • ?
  • ????}?
  • }??
  • 例如:

  • buildscript?{?
  • ????repositories?{?
  • ????????jcenter()?
  • ????????mavenCentral()?
  • ????????maven?{?
  • ????????????url?"https://plugins.gradle.org/m2/"?
  • ????????}?
  • ?
  • ????}?
  • ?
  • ????dependencies?{?
  • ????????classpath?'com.android.tools.build:gradle:2.2.2'?
  • ????????classpath?'com.neenbedankt.gradle.plugins:android-apt:1.8'?
  • ????}?
  • }?
  • ?
  • allprojects?{?
  • ????repositories?{?
  • ????????jcenter()?
  • ????}?
  • }?
  • ?
  • task?clean(type:?Delete)?{?
  • ????delete?rootProject.buildDir?
  • }??
  • 在app的build.grade文件中進行如下配置:

  • apply?plugin:?'com.android.application'?
  • apply?plugin:?'com.neenbedankt.android-apt'?
  • ?
  • android{...}?
  • ?
  • dependencies?{?
  • ????//視圖綁定?butterknife?
  • ????compile?'com.jakewharton:butterknife:8.4.0'?
  • ????apt?'com.jakewharton:butterknife-compiler:8.4.0'?
  • }??
  • 例如:

  • apply?plugin:?'com.android.application'?
  • apply?plugin:?'android-apt'?
  • ?
  • android?{?
  • ????compileSdkVersion?24?
  • ????buildToolsVersion?"24.0.3"?
  • ?
  • ????defaultConfig?{?
  • ?
  • ????????minSdkVersion?14?
  • ????????targetSdkVersion?24?
  • ????????versionCode?1?
  • ????????versionName?"1.0"?
  • ????}?
  • ????buildTypes?{?
  • ????????release?{?
  • ????????????minifyEnabled?false?
  • ????????????proguardFiles?getDefaultProguardFile('proguard-android.txt'),?'proguard-rules.pro'?
  • ????????}?
  • ????}?
  • }?
  • ?
  • dependencies?{?
  • ????compile?fileTree(dir:?'libs',?include:?['*.jar'])?
  • ?
  • ????compile?'com.jakewharton:butterknife:8.4.0'?
  • ????apt?'com.jakewharton:butterknife-compiler:8.4.0'?
  • }??
  • 如何使用ButterKnife

    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) 控件id 注解: @BindView()

  • package?com.myl.test;?
  • ?
  • import?android.support.v7.app.AppCompatActivity;?
  • import?android.os.Bundle;?
  • import?android.widget.Button;?
  • ?
  • import?butterknife.BindView;?
  • import?butterknife.ButterKnife;?
  • ?
  • public?class?ButterknifeActivity?extends?AppCompatActivity?{?
  • ?
  • ????@BindView(?R.id.button1?)?
  • ????public?Button?button1?;?
  • ?
  • ????//?注意:button?的修飾類型不能是:private?或者?static?。?否則會報錯:錯誤:?@BindView?fields?must?not?be?private?or?static.?(com.myl.test.ButterknifeActivity.button1)?
  • ?
  • ????@Override?
  • ????protected?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ????????setContentView(R.layout.activity_butterknife);?
  • ????????//綁定activity?
  • ????????ButterKnife.bind(?this?)?;?
  • ?
  • ????????button1.setText(?"I?am?a?button?");?
  • ????}?
  • }??
  • 4) 多個控件id 注解: @BindViews()

  • package?com.myl.test;?
  • ?
  • import?android.support.v7.app.AppCompatActivity;?
  • import?android.os.Bundle;?
  • import?android.widget.Button;?
  • import?java.util.List;?
  • import?butterknife.BindViews;?
  • import?butterknife.ButterKnife;?
  • ?
  • public?class?Main2Activity?extends?AppCompatActivity?{?
  • ?
  • ????@BindViews({?R.id.button1??,?R.id.button2?,??R.id.button3?})?
  • ????public?List<Button>?buttonList?;?
  • ?
  • ????@Override?
  • ????protected?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ????????setContentView(R.layout.activity_main2);?
  • ?
  • ????????ButterKnife.bind(this);?
  • ?
  • ????????buttonList.get(?0?).setText(?"hello?1?");?
  • ????????buttonList.get(?1?).setText(?"hello?2?");?
  • ????????buttonList.get(?2?).setText(?"hello?3?");?
  • ????}?
  • }??
  • 5) @BindString() :綁定string 字符串

  • package?com.myl.test;?
  • ?
  • import?android.os.Bundle;?
  • import?android.support.v7.app.AppCompatActivity;?
  • import?android.widget.Button;?
  • ?
  • import?butterknife.BindString;?
  • import?butterknife.BindView;?
  • import?butterknife.ButterKnife;?
  • ?
  • public?class?ButterknifeActivity?extends?AppCompatActivity?{?
  • ?
  • ????@BindView(?R.id.button1?)?//綁定button?控件?
  • ????public?Button?button1?;?
  • ?
  • ????@BindString(?R.string.app_name?)??//綁定string?字符串?
  • ????String?meg;?
  • ?
  • ????@Override?
  • ????protected?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ????????setContentView(R.layout.activity_butterknife);?
  • ?
  • ????????//綁定activity?
  • ????????ButterKnife.bind(?this?)?;?
  • ?
  • ????????button1.setText(?meg?);?
  • ????}?
  • }??
  • 6) @BindArray() : 綁定string里面array數組

  • <resources>?
  • ????<string?name="app_name">校園助手</string>?
  • ?
  • ????<string-array?name="city">?
  • ????????<item>東莞市</item>?
  • ????????<item>廣州市</item>?
  • ????????<item>珠海市</item>?
  • ????????<item>肇慶市</item>?
  • ????????<item>深圳市</item>?
  • ????</string-array>?
  • ?
  • </resources>?
  • -----------------------------------------------------------------?
  • package?com.myl.test;?
  • ?
  • import?android.os.Bundle;?
  • import?android.support.v7.app.AppCompatActivity;?
  • import?android.widget.Button;?
  • ?
  • import?butterknife.BindArray;?
  • import?butterknife.BindView;?
  • import?butterknife.ButterKnife;?
  • ?
  • public?class?ButterknifeActivity?extends?AppCompatActivity?{?
  • ?
  • ????@BindView(?R.id.button1?)?//綁定button?控件?
  • ????public?Button?button1?;?
  • ?
  • ????@BindArray(R.array.city?)??//綁定string里面array數組?
  • ????String?[]?citys?;?
  • ?
  • ????@Override?
  • ????protected?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ????????setContentView(R.layout.activity_butterknife);?
  • ?
  • ????????//綁定activity?
  • ????????ButterKnife.bind(?this?)?;?
  • ?
  • ????????button1.setText(?citys[0]?);?
  • ????}?
  • }??
  • 7) @BindBitmap( ) : 綁定Bitmap 資源

  • package?com.myl.test;?
  • ?
  • import?android.graphics.Bitmap;?
  • import?android.os.Bundle;?
  • import?android.support.v7.app.AppCompatActivity;?
  • import?android.widget.ImageView;?
  • ?
  • import?butterknife.BindBitmap;?
  • import?butterknife.BindView;?
  • import?butterknife.ButterKnife;?
  • ?
  • public?class?ButterknifeActivity?extends?AppCompatActivity?{?
  • ?
  • ????@BindView(?R.id.imageView?)?//綁定ImageView?控件?
  • ????public?ImageView?imageView?;?
  • ?
  • ????@BindBitmap(?R.mipmap.wifi?)??//綁定Bitmap?資源?
  • ????public?Bitmap?wifi_bitmap?;?
  • ?
  • ????@Override?
  • ????protected?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ????????setContentView(R.layout.activity_butterknife);?
  • ?
  • ????????//綁定activity?
  • ????????ButterKnife.bind(?this?)?;?
  • ?
  • ????????imageView.setImageBitmap(?wifi_bitmap?);?
  • ????}?
  • }??
  • 8) @BindColor( ) : 綁定一個顏色值

  • package?com.myl.test;?
  • ?
  • import?android.os.Bundle;?
  • import?android.support.v7.app.AppCompatActivity;?
  • import?android.widget.Button;?
  • ?
  • import?butterknife.BindColor;?
  • import?butterknife.BindView;?
  • import?butterknife.ButterKnife;?
  • ?
  • public?class?ButterknifeActivity?extends?AppCompatActivity?{?
  • ?
  • ????@BindView(?R.id.button1?)??//綁定一個控件?
  • ????public?Button?button1?;?
  • ?
  • ????@BindColor(?R.color.colorAccent?)?int?black?;??//綁定一個顏色值?
  • ?
  • ????@Override?
  • ????protected?void?onCreate(Bundle?savedInstanceState)?{?
  • ????????super.onCreate(savedInstanceState);?
  • ????????setContentView(R.layout.activity_butterknife);?
  • ?
  • ????????//綁定activity?
  • ????????ButterKnife.bind(?this?)?;?
  • ?
  • ????????button1.setTextColor(??black?);?
  • ?
  • ????}?
  • }??
  • 9) 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);???
  • ????????}???
  • ????}???
  • }????
  • 10) 點擊事件的綁定:不用聲明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.submit)???
  • public?void?sayHi(Button?button)?{???
  • ??button.setText("Hello!");???
  • }???
  • 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)?{???
  • ?
  • }??
  • 代碼混淆

  • -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,然后就出現如圖的選擇框。

    ButterKnife實現原理

    對ButterKnife有過了解人 , 注入字段的方式是使用注解@BindView(R.id.tv_account_name),但首先我們需要在Activity聲明注入ButterKnife.bind(Activity activity) 。我們知道,注解分為好幾類, 有在源碼生效的注解,有在類文件生成時生效的注解,有在運行時生效的注解。分別為RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME ,其中以RetentionPolicy.RUNTIME最為消耗性能。而ButterKnife使用的則是編譯器時期注入,在使用的時候,需要配置classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’ , 這個配置說明,在編譯的時候,進行注解處理。要對注解進行處理,則需要繼承AbstractProcessor , 在boolean process(Set

    ButterKnife實現方式

    知曉了注解可以在編譯的時候進行處理,那么,我們就可以得到注解的字段屬性與所在類 , 進而生成注入文件,生成一個注入類的內部類,再進行字段處理 , 編譯之后就會合并到注入類中,達到植入新代碼段的目的。例如:我們注入@VInjector(R.id.tv_show) TextView tvShow;我們就可以得到tvShow這個變量與R.id.tv_show這個id的值,然后進行模式化處理injectObject.tvShow = injectObject.findViewById(R.id.tv_show); ,再將代碼以內部類的心事加入到組件所在的類中 , 完成一次DI(注入) 。

    a) 首先創建一個視圖注解

    b) 創建一個注解處理器,用來得到注解的屬性與所屬類

    c) 解析注解,分離組合Class與屬性

    d) 組合Class與屬性,生成新的Java File

    APT生成的Java File , 以及模式代碼

    使用Javac , 編譯時期生成注入類的子類

    項目UML圖

    簡要說明:

    主要類:

    VInjectProcessor —-> 注解處理器 , 需要配置注解處理器

  • resources?
  • ????????-?META-INF?
  • ??????????????-?services?
  • ????????????????????-?javax.annotation.processing.Processor??
  • Processor內容:

  • com.myl.viewinject.apt.VInjectProcessor???#?指定處理器全類名??
  • VInjectHandler —-> 注解處理類 , 主要進行注入類與注解字段進行解析與封裝,將同類的字段使用map集合進行映射。exp: Map

    自定義ButterKnife具體實現

    因微信字數限制,請點擊左下角原文鏈接查看!~







    本文作者:佚名 來源:51CTO

    總結

    以上是生活随笔為你收集整理的Butterknife全方位解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。