ButterKnife使用及びLibrary穴埋め記

4932 ワード

この间、勉强を怠って、博文を书くことを坚持していません.***
さて、ButterKnifeのソースアドレスは:https://github.com/JakeWharton/butterknife.このライブラリは注記を使用してFieldとMethodのバインドを実現します.使用中に問題が発生した場合は、その次に公式ドキュメントを参照する必要があります.
メリットは次のとおりです.
  • Eliminate findViewById calls by using @BindView on fields.
  • Group multiple views in a list or array. Operate on all of them at once with actions, setters, or properties.
  • Eliminate anonymous inner-classes for listeners by annotating methods with @OnClick and others.
  • Eliminate resource lookups by using resource annotations on fields.

  • 簡単な使用コードは次のとおりです.
    class ExampleActivity extends Activity {
      @BindView(R.id.user) EditText username;
      @BindView(R.id.pass) EditText password;
    
      @BindString(R.string.login_error) String loginErrorMessage;
    
      @OnClick(R.id.submit) void submit() {
        // TODO call server...
      }
    
      @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.simple_activity);
        ButterKnife.bind(this);
        // TODO Use fields...
      }
    }
    

    Bind使用シーン
    Activity
    具体的には、上記のサンプルコードを参照してください.ButterKnife.bind(activity)
    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();
      }
    }
    

    注意、ButterKnifeを使用します.bind(fragment, view).ドキュメントによると、Fragmentの特殊性のため、onCreateViewでbindを行う場合は、onDestroyViewで解縛する必要があります.
    AdapterのViewHolder使用
    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 view;
      }
    
      static class ViewHolder {
        @BindView(R.id.title) TextView name;
        @BindView(R.id.job_title) TextView jobTitle;
    
        public ViewHolder(View view) {
          ButterKnife.bind(this, view);
        }
      }
    }
    

    もう1つの使用の詳細は面白いと思いますが、デフォルトでは@Bindとリスナーを使用する場合、ターゲットViewが存在しないと異常が放出されます.このような挙動を避けるために,@Nullable注記(Field)と@Optional注記(methods)を用いることができる.
    詳細については、次の文書を参照してください.http://jakewharton.github.io/butterknife/.
    Appモジュールコンパイル構成
    appモジュールのbuild.gradleでは、次の依存を追加します.
    dependencies {
      implementation 'com.jakewharton:butterknife:8.8.1'
      annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    }
    

    注意:If you are using Kotlin,replace annotationProcessor with kapt.
    Libraryモジュールコンパイル構成
    コードの複雑さが増すにつれて、マルチコンポーネントが現れ、ButterKnifeの使用にも迷惑をかけます.公式ドキュメントを参照して、手順は以下の通りです.一、libモジュールのbuildscriptに次のコードを追加します.
    buildscript {
      repositories {
        mavenCentral()
       }
      dependencies {
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
      }
    }
    

    二、libモジュールで使用する
    apply plugin: 'com.android.library'
    apply plugin: 'com.jakewharton.butterknife'
    

    三、RではなくR 2で参照
    class ExampleActivity extends Activity {
      @BindView(R2.id.user) EditText username;
      @BindView(R2.id.pass) EditText password;
    ...
    }
    

    穴埋め記
    複数のLibでR 2を使用する場合、Android Studioは常に最初に追加されたmodule(最下層のコンパイル依存モジュールでもあり、テストされていない)に自動的に追加されます.この場合はimportモジュール名.R 2を直接追加することで解決できます.バカな私はショートカットキーで自動的に参照を追加しなければなりません.自分の時間を無駄にしますよ.
    switch-case文の使用に注意してください.libraryではリソースidをcase値として使用できません.そうしないと、Validates using resource IDs in a switch statement in Android library module異常が発生します.解決策はif-elseで置き換え,コードにRを用いてリソースidを参照することである.
    @OnClick({R2.id.textView, R2.id.button1, R2.id.button2, R2.id.button3, R2.id.image})
        public void onViewClicked(View view) {
            int i = view.getId();
            if (i == R.id.textView) {
            } else if (i == R.id.button1) {
            } else if (i == R.id.button2) {
            } else if (i == R.id.button3) {
            } else if (i == R.id.image) {
            }
        }
    

    使用中には、1つのActivityの2つの動的Viewをbin d(this,view)とそれぞれ呼び出すコードが書かれていますが、1つのviewが実行時にバインドされるオブジェクトの例はnullです.この記事を参考にして、ViewHolderで解決することができます.https://segmentfault.com/q/1010000009989285.
    参考文章:Butter Knife——最もよく使うView注入複数のlibrary butterknifeを使用するピットValidates using resource IDs in a switch statement in Android library module butterknifeコンポーネント化開発libraryにおけるR類問題の一括解決策コンポーネント化開発butterknife libraryに使用するピット