はじめに:
ButterKnifeビューは簡単にこれらのステップを省略することができButterKnifeで、Viewオブジェクトを見つけるために、findViewById多くのことを書くために使用、Androidシステムに注力するためのフレームワークに注入されます。神は、現在非常に広く使用されている偉大なJakeWhartonの傑作、です。最も重要な点は、ButterKnifeは注釈が運営に反映されていない使用しますが、コンパイル時に新しいクラスを作成しますので、基本的にButterKnifeパフォーマンスの損失なしを使用しています。プロジェクトで使用するのが特に便利で統合することは特に簡単です。
この記事の研究を通じて、プロジェクトにButterKnifeを使用する方法を学びます。この記事では、以下の点が含まれています。
- 序文
- ブリーフ
- ButterKnife利点
- 基本構成
- ButterKnife登録と結合
- ButterKnifeは経験や注意事項を使用します
- 結合ButterKnifeでの活動
- 結合断片ButterKnifeで
- アダプタで結合ButterKnife
- ButterKnifeの基本的な使用
- バインドビュー
- バインディングのリソース
- イベントバインディング
- バインディングモニター
- 使用findById
- プロパティのビューを複数設定します
- 注意事項
- その他のバインディングアノテーション
- その他のイベントの注意事項
- コードの難読化のButterKnife
- Butterknifeプラグ:zelezny
- プラグインのインストール
- プラグインの使用
ButterKnifeプロジェクト住所:https://github.com/JakeWharton/butterknife
▲のButterKnifeの利点:
1、結合および強力なビューをクリックしてイベントハンドラ関数、コードを簡素化し、開発効率を向上させます
2、ViewHolder結合問題で便利な処分アダプタ
3、APPは、コンフィギュレーションを使用して簡単に、操作の効率に影響を与えません。
4、読みやすいクリアコード、
基本構成の
設定は、Android StudioプロジェクトにButterKnifeを使用しています
- ステップ1:プロジェクトのbuild.gradleに次のコードを追加します。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1' //添加这一行
}
}
- ステップ2:アプリケーションbuild.gradleに次のコードを追加します。
apply plugin: 'com.jakewharton.butterknife'
- 依存関係を追加しました:
compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
特に簡単で環境を構築し、あなたはどのように使用できるかを見てみましょう
ButterKnife登録と結合
▲ButterKnifeレビューや注意事項:
結合活性クラスの1、:ButterKnife.bind(この);(setContentViewでなければならない);結合した後、結合し、親クラスを結合した後、サブクラスは、バインドする必要はありません。
図2に示すように、非アクティビティクラス(例えばフラグメント、ViewHold)結合に:ButterKnife.bind(これは、ビュー);これは、ここでは交換することができないgetActivity()。
図3は、アクティビティのアンバンドリングの操作を行うために必要で、操作がして()onDestroyViewにアンバンドリングフラグメントを行わなければなりません。
図4は、修正された方法のButterKnifeとコントロールを使用して、プライベートまたは静的と、それ以外の場合はエラーになり、変更することができません。エラー:@BindViewフィールドは、プライベートまたは(com.zyj.wifi.ButterknifeActivity.button1)静的であってはなりません。
5、setContentView()は、注釈によって達成することができません。(いくつかの他のコメントフレームワークすることができます)
6、活動を使用している場合は、ルートビューの任意のオブジェクトをバインドし、あなたはMVCデザインパターンのようなものを使用する場合は、コントローラーをバインドするために、中ButterKnife.bind(これ、活動)の活動を呼び出すことができます。
ButterKnife.bind(これは、ビュー)ビューのバインド可能なノードのフィールドを使用して7、。あなたや、子ビューで使用されている工法の自己定義されたビューはレイアウトを膨らませる場合は、すぐにこのメソッドを呼び出すことができます。また、カスタムXMLは、コールバックメソッドでそれを使用することができますonFinishInflateタイプを表示する膨らませます。
活動中▲結合ButterKnife:
onCreateで活動中のアクティビティをバインドするたびに、それが結合を完了し、個人BaseActivityを書くことが推奨されているので、サブクラスが継承することができます。活動をバインドするsetContentViewした後でなければなりません。結合のためButterKnife.bind(これ)を使用します。コードは以下の通りであります:
public class MainActivity extends AppCompatActivity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定初始化ButterKnife ButterKnife.bind(this); } }
断片中▲結合ButterKnifeで:
フラグメントのライフサイクルは、活動は異なっています。断片onCreateViewに結合すると、ビューはnullに設定onDestroyViewます。あなたはあなたをバインドするフラグメントバインドを呼び出すと、バターナイフはUnbinderのインスタンスを返します。それは、そのアンバインドメソッド適切なライフサイクルで(onDestroyView)コールバックは、フラグメントのアンバンドリングを搭載呼び出します。結合のためButterKnife.bind(これ、ビュー)を使用します。コードは以下の通りであります:
public class ButterknifeFragment extends Fragment{ private Unbinder unbinder; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment, container, false); //返回一个Unbinder值(进行解绑),注意这里的this不能使用getActivity() unbinder = ButterKnife.bind(this, view); return view; } /** * onDestroyView中进行解绑操作 */ @Override public void onDestroyView() { super.onDestroyView(); unbinder.unbind(); } }
▲アダプタでButterKnifeバインディング:
ViewHolderアダプタは、コンストラクタ、ビューに渡して新しいViewHolderを追加ViewHolderに使用されます。次のように結合ButterKnife.bind(これ、ビュー)を、使用します。
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.testlayout, parent, false); holder = new ViewHolder(view); view.setTag(holder); } holder.name.setText("Donkor"); holder.job.setText("Android"); // etc... return view; } static class ViewHolder { @BindView(R.id.title) TextView name; @BindView(R.id.job) TextView job; public ViewHolder(View view) { ButterKnife.bind(this, view); } } }
ButterKnifeの基本的な使用
▲バインドビュー:
- コントロールID注:@BindView()
@BindView( R2.id.button)
public Button button;
- レイアウト内のコントロールのノートID番号:@BindViews()
public class MainActivity extends AppCompatActivity { @BindViews({ R2.id.button1, R2.id.button2, R2.id.button3}) public List<Button> buttonList ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); buttonList.get( 0 ).setText( "hello 1 "); buttonList.get( 1 ).setText( "hello 2 "); buttonList.get( 2 ).setText( "hello 3 "); } }
▲バインディングのリソース:
- 結合文字列:@BindString()
public class MainActivity extends AppCompatActivity { @BindView(R2.id.button) //绑定button 控件 public Button button ; @BindString(R2.string.app_name) //绑定资源文件中string字符串 String str; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; button.setText( str ); } }
- アレイのアレイ内の結合列:@BindArray()
<resources>
<string name="app_name">城市</string>
<string-array name="city"> <item>北京市</item> <item>天津市</item> <item>哈尔滨市</item> <item>大连市</item> <item>香港市</item> </string-array> </resources> ------------------------------------------------------------------------------ public class MainActivity extends AppCompatActivity { @BindView(R2.id.button) //绑定button 控件 public Button button ; @BindString(R2.string.app_name) //绑定资源文件中string字符串 String str; @BindArray(R2.array.city) //绑定string里面array数组 String [] citys ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; button.setText(citys[0]); } }
- 結合ビットマップのリソース:@BindBitmap()
public class MainActivity extends AppCompatActivity { @BindView( R2.id.imageView ) //绑定ImageView 控件 public ImageView imageView ; @BindBitmap( R2.mipmap.bm)//绑定Bitmap 资源 public Bitmap bitmap ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; imageView.setImageBitmap(bitmap); } }
- 色の値を結合:@BindColor()
public class MainActivity extends AppCompatActivity { @BindView( R2.id.button) //绑定一个控件 public Button button; @BindColor( R2.color.colorAccent ) //具体色值在color文件中 int black ; //绑定一个颜色值 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; button.setTextColor( black ); } }
▲イベントバインディング:
-
クリックイベントをバインドします。
-
バインドされたコントロールのClickイベント:@OnClick()
-
バインドされたコントロールを押してイベント:@OnLongClick()
-
public class MainActivity extends AppCompatActivity { @OnClick(R2.id.button1 ) //给 button1 设置一个点击事件 public void showToast(){ Toast.makeText(this, "is a click", Toast.LENGTH_SHORT).show(); } @OnLongClick( R2.id.button1 ) //给 button1 设置一个长按事件 public boolean showToast2(){ Toast.makeText(this, "is a long click", Toast.LENGTH_SHORT).show(); return true ; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; } }
- Idは、複数の結合事象を指定します。
public class MainActivity extends AppCompatActivity { //Tip:当涉及绑定多个id事件时,我们可以使用Android studio的Butterknife //插件zelezny快速自动生成的,之后在下面会有介绍安装插件与使用 @OnClick({R.id.ll_product_name, R.id.ll_product_lilv, R.id.ll_product_qixian, R.id.ll_product_repayment_methods}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.ll_product_name: System.out.print("我是点击事件1"); break; case R.id.ll_product_lilv: System.out.print("我是点击事件2"); break; case R.id.ll_product_qixian: System.out.print("我是点击事件3"); break; case R.id.ll_product_repayment_methods: System.out.print("我是点击事件4"); break; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; } }
上記の例で分かるように、あなたは、単一のシーケンシャル書き込みすることができR2の文言を使用する必要があれば、クリックイベントは、道とR2以上のものではありません、以下のように、正しい言葉遣いは次のようになります。
public class MainActivity extends AppCompatActivity { @OnClick(R2.id.ll_product_name) public void onViewClicked1(View view) { System.out.print("我是点击事件1"); } @OnClick(R2.id.ll_product_lilv) public void onViewClicked2(View view) { System.out.print("我是点击事件2"); } @OnClick(R2.id.ll_product_qixian) public void onViewClicked3(View view) { System.out.print("我是点击事件3"); } @OnClick(R2.id.ll_product_repayment_methods) public void onViewClicked4(View view) { System.out.print("我是点击事件4"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; } }
- バインドを使用してカスタムビューイベント
ID、直接コメントのOnClickを指定しないでください。コードを見て、クリックイベントを達成するための同様の方法のように感じます。これは、実際にOnClickListenerインターフェースを実現していませんでした。コードは以下の通りであります:
public class MyButton extends Button { @OnClick public void onClick() {} }
▲聞くバインディング:
- リスナーは自動的に処理するように構成することができます
@OnClick(R.id.submit)
public void submit(View view) { // TODO submit data to server... }
- リスナーメソッドのすべてのパラメータはオプションです
@OnClick(R.id.submit)
public void submit() { // TODO submit data to server... }
- カスタム特定のタイプ、それは自動的に変換されます
@OnClick(R.id.submit)
public void sayHi(Button button) {//看括号内参数的变化就明白了 button.setText("Hello!"); }
- パブリックイベント処理のための単一の結合で複数のIDを指定します。ここでは、例えばイベントをクリックします。その他のイベントリスナーも可能です。
@OnClick(R.id.submitCode,R.id.submitFile,R.id.submitTest)
public void sayHi(Button button) {//多个控件对应公共事件 button.setText("Success!"); }
- カスタムビューは、IDを指定していない、自分のリスナーにバインドすることができます。
public class FancyButton extends Button { @OnClick public void onClick() { // TODO do something! } }
- リスナーマルチメソッドのアノテーション
コールバック・リスナーの複数に対応する注釈の方法は、それらのいずれかに結合するために使用することができます。各コメントには、バインディングのデフォルトのコールバックを持っています。交換を指定するには、コールバックパラメータを使用します。例えばスピナーするには。
もともとコード:
Spinner s=new Spinner(this);
//原始方法:Spinner 条目选择监听事件 正常写法
s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { } @Override public void onNothingSelected(AdapterView<?> parent) { } });
コメントバターナイフの方法により、
public class MainActivity extends AppCompatActivity { /*利用注解对Spinner item 作选择监听事件处理方式*/ @OnItemSelected(R.id.my_spiner)//默认callback为ITEM_SELECTED void onItemSelected(int position) { Toast.makeText(this, "position: " + position, Toast.LENGTH_SHORT).show(); } /* * 注解onNothingSelected,需要在注解参数添加一个callback, * 注意的是Spinner中只要有数据,默认都会选中第0个数据,所以想进入到onNothingSelected()方法,就需要把Adapter中的数据都清空 */ @OnItemSelected(value = R.id.my_spiner, callback = OnItemSelected.Callback.NOTHING_SELECTED) void onNothingSelected() { Toast.makeText(this, "Nothing", Toast.LENGTH_SHORT).show(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind( this ) ; Spinner s=new Spinner(this); } }
- @OnCheckedChangedリスニングを使用します
元のメソッドは次のようになりますsetOnCheckedChangeListener()。栗を使用してください
<?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="match_parent" android:orientation="vertical"> <RadioGroup android:id="@+id/rg_main" android:layout_width="fill_parent" android:layout_height="48dp" android:layout_alignParentBottom="true" android:background="@color/white" android:orientation="horizontal"> <RadioButton android:id="@+id/rg_home" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="false" android:text="@string/nav_one" /> <RadioButton android:id="@+id/rg_wealth" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="false" android:text="@string/nav_two" /> <RadioButton android:id="@+id/rg_account" android:layout_width="match_parent" android:layout_height="match_parent" android:focusable="false" android:text="@string/nav_four" /> </RadioGroup> </LinearLayout> ------------------------------------------------------------------------- @OnCheckedChanged({R.id.rg_home,R.id.rg_wealth,R.id.rg_account}) public void OnCheckedChangeListener(CompoundButton view, boolean ischanged ){ switch (view.getId()) { case R.id.rg_home: if (ischanged){//注意:这里一定要有这个判断,只有对应该id的按钮被点击了,ischanged状态发生改变,才会执行下面的内容 //这里写你的按钮变化状态的UI及相关逻辑 } break; case R.id.rg_wealth: if (ischanged) { //这里写你的按钮变化状态的UI及相关逻辑 } break; case R.id.rg_account: if (ischanged) { //这里写你的按钮变化状态的UI及相关逻辑 } break; default: break; } }
▲findByIdを使用します。
バターナイフはまだ依然として、活性、またはダイアログ・ビュー初期化ビューから、findById()メソッドが含まれ、それは自動的に型を変換することができます。
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 iv = ButterKnife.findById(view, R.id.iv);
▲セット特性の複数のビュー:
- 適用されます()
役割は:あなたはすぐにすべてのビューのリストを操作することができます。
- アクションとセッターのインターフェイス
役割:アクションセッターとシンプルなインターフェイスは、動作を指定することができます。
public class MainActivity extends AppCompatActivity { @BindViews({R2.id.first_name, R2.id.middle_name, R2.id.last_name}) List<EditText> nameViews; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定activity ButterKnife.bind(this); //设置多个view的属性 //方式1:传递值 ButterKnife.apply(nameViews, DISABLE); //方式2:指定值 ButterKnife.apply(nameViews, ENABLED, false); ////方式3 设置View的Property ButterKnife.apply(nameViews, View.ALPHA, 0.0f);//一个Android属性也可以用于应用的方法。 } /* * Action接口设置属性 */ static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() { @Override public void apply(View view, int index) { view.setEnabled(false);//目的是使多个view都具备此属性 } }; /* * Setter接口设置属性 */ 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);//目的是使多个view都具备此属性,可变boolean值是可以传递的 } }; }
▲注意:
- 異なるバージョンによるButterKinfe注釈ラベルが異なります。
ラベルの前に8.0.0 8.0.0バインド後BindViewとなったが、ビューをバインドするとき8.7.0の後、代わりに通常のR.id.XXXのR2.id.XXXを使用しています。
githubの特定の変更を表示し、ログを提出する:
https://github.com/JakeWharton/butterknife/blob/master/CHANGELOG.md#version-800-2016-04-25
- デフォルトでは、@バインドとリスナー結合が必要です。あなたがターゲットビューが見つからない場合は、例外がスローされます。
この動作を抑制し、オプションの結合を作成するには、@Nullableフィールドに注釈を追加、または@optional方法にメモを追加することができます。
任意の名前の@Nullableノートには、メンバ変数のために使用することができます。我々はアンドロイド「サポート-注釈」@Nullableアノテーション・ライブラリを使用することをお勧めします。
@Nullable
@BindView(R.id.might_not_be_there)
TextView mightNotBeThere;
@Optional
@OnClick(R.id.maybe_missing)
public void onMaybeMissingClicked() { // TODO ... }
▲多くのバインディングアノテーション:
@BindView - >ビューを結合; idが可変図であります
@BindViews - >ビューの複数の結合; IDリストが可変の図です。
@BindArray - >配列の内部に文字列配列を結合; @BindArray(R.array.city)文字列[]市内。
@BindBitmap - >バインディンググラフィックアセットのビットマップ; @BindBitmap(R.mipmap.wifi)ビットマップビットマップ。
@BindBool - >バインドブール値
@BindColor - >绑定色; @BindColor(R.color.colorAccent)ブラックINT。
@BindDimen - >绑定DIMEN; @BindDimen(R.dimen.borth_width)int型mBorderWidth。
@BindDrawable - >绑定描画領域; @BindDrawable(R.drawable.test_pic)描画領域mTestPic。
@BindFloat - >バインディングフロート
@BindInt - > int型のバインド
@BindString - >文字列変数として文字列IDを結合; @BindString(R.string.app_name)文字列MEG。
▲多くのイベントの注意事項:
@OnClick - >クリックイベント
@OnCheckedChanged - >確認し、チェックを外します
@OnEditorAction - >ソフトキーボードのファンクションキー
@OnFocusChange - >変更フォーカス
@OnItemClickアイテム - >クリックは、(ピットボタンをクリックしているがアイテムは、これらのイベントを制御する場合、我々はfalseにフォーカス可能なコントロールのプロパティを設定する必要があることに注意してください)
@OnItemLongClickアイテム - >ロングプレス(本当にonItemClickを傍受することができます返します)
@OnItemSelected - >項目が選択されたイベント
@OnLongClick - >ロングプレスイベント
@OnPageChange - >ページの変更イベント
@OnTextChanged - >テキストの変更イベントの内部のEditText
@OnTouch - >タッチイベント
@optional - 現在のオブジェクトが存在しない場合>選択的注入、それは、注入が選択的になるように、ターゲットがビューが存在する場合に例外を抑制するために、あなたは、どのような変数やメソッドの上にメモを追加することができ、例外がスローされます注入は、何もしない、存在しません。
//Test @Optional
@Optional
@OnCheckedChanged(R.id.cb_test)
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked){ if(isChecked){ tvTest.setText("被选中..."); }else{ tvTest.setText("被取消..."); } }
コードの難読化のButterKnife
混乱のファイルで、次のコードを追加します。
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; }
Butterknifeプラグ:zelezny
- プラグインがインストールさ:
ツールバーファイルは、設定を見つける...またはオープンショートカットはCtrl + Alt + Sポイントを使用しています。zeleznyダウンロードを検索し、プラグインをインストールし、Androidのメーカーを再起動します
- プラグインの使用:
インストールが完了するプラグインです後は、ASは、再起動後、新しいレイアウトと、次のコードクラスのテストを書くことができます再起動を促すメッセージが表示されます。テストプロセス中に注意を払う必要があり、カーソルsetContentView(R.layout.acty_login)を移動カーソルR.layout.acty_loginを置き、そこを右生成する必要があります。ここでは、プラグインがもたらすの利点を示すために、より直感的なGIFのレンダリングを、引用されました。IDをバインドするために、より必要性のために、手動で時刻を破ってコーディングする必要性を保存します。
著者:lisx_
リンクします。https://www.jianshu.com/p/3678aafdabc7
出典:ジェーン・ブック
著者によって予約ジェーンブックの著作権は、いかなる形で再現され、承認を得るために、作者に連絡して、ソースを明記してください。