findViewById代替案:Android Jetpack MVVMのBindingAdapter

16835 ワード

本論文の目的はBindingAdapterの使用方法を述べ,クリックイベントを例に挙げることである.
それを紹介する前に、レイアウトファイルのシステム属性android:onClick=""について説明します.使用したことがあるかどうか分かりませんが、二重引用符の真ん中にトリガーするイベント名があります.findViewByIdで対応するコントロールを取得してからclickイベントを傍受する必要はありません.もしあなたが使ったことがあれば省略してください.もしなかったら、どうやって使うか見てみましょう.
たとえば、レイアウトファイルでandroid:onClick=「clickEvent」を設定します.
<ImageView    
        android:layout_width="wrap_content"    
        android:layout_height="wrap_content"    
        android:onClick="clickEvent"   
        android:src="@drawable/tes" />

activityでclickEvent関数を新規作成します.
public void clickEvent(View v) {   
    Toast.makeText(this, "test", Toast.LENGTH_LONG).show();
}

このようにImageViewのクリックイベントを直接傍受することができるのは便利ではないでしょうか.なぜこれを紹介するのかというと、本稿BindingAdapterも同様の方法で実現しなければならないからです.ただ、システムの定義された属性ではなく、自分で属性を定義します.
まずattrsについてお話しします.xml、res/valuesディレクトリの下にあるファイルですが、なぜですか?bindingadapterと密接につながっているからです.
  • カスタム属性カスタマイズには、2つの部分があります.1つ目は、属性名、すなわち名前、2つ目は、属性値、すなわち属性フォーマットformatです.次のコードを見てください:
  • 
    <resources>
        <attr name="backColor" format="color">
            <enum name="redColor" value="1" />
        <declare-styleable name="MyView">
            <attr name="backColor"/>
        declare-styleable>
    resources>
    

    attrで始まるのは、特定の属性を表します.
    declare-styleableで表されるグループ.たとえば、ビューのプロパティをカスタマイズしたいのですが、このビューがMyViewであると仮定すると、MyViewの下に定義されているすべてのプロパティはMyViewグループに属し、それを継承するものはすべて使用できます.もちろん、システムコントロールにカスタムプロパティを追加することもできます.
    システム属性とカスタム属性には違いがあり、属性名の前に「android:」がシステム属性です.カスタム属性名は何も言うことはありませんが、できるだけシステム定義の属性名と同じではありません.
    システム定義のプロパティと同様にformatを設定しない場合は、システムをそのまま使用します.設定すると、システム属性の再定義になりますが、変更できないシステム属性フォーマットもあります.
    プロパティのformatについて簡単に説明します.
    referenceはcolor色booleanブールinteger整数dimension float浮動小数点型string文字型fractionパーセントenum列挙型flagを参照
    カスタム属性ができましたが、実際には難しくありません.では、次に、BindingAdapterと接続を確立する方法を見てみましょう.実はとても簡単で、やはり1つの例で説明します
  • まず、カスタムプロパティ、私たちはシステムの制御ViewにonClickCommandプロパティをカスタマイズして、Viewというグループに属している限り、このプロパティを使用することができます.
  • <resources>
           <declare-styleable name="View">
               <attr name="onClickCommand" format="reference" />    
           declare-styleable>
     resources>
    

    この属性nameは、BindingAdapterの鍵です.
  • 次にBindingAdapter
  • 一般的なフォーマットは次のとおりです.
    @BindingAdapter(value={"属性名1","属性名2"})public static void関数名(パラメータ){//関数内容}
    具体的な例は以下の通りである:新しいファイルはViewAdapterである.JAva、クラスに次のコードを追加
    @BindingAdapter(value = {"onClickCommand"}, requireAll = false)
    public static void click(View view, final ClickCallBack bindingCommand) {    
        view.setOnClickListener(new View.OnClickListener() {        
            @Override        
            public void onClick(View view) {           
            if (bindingCommand != null) {                
               bindingCommand.clickEvent();               
               Toast.makeText(view.getContext(), "it works", Toast.LENGTH_LONG).show();           
            } else {                
                Toast.makeText(view.getContext(), "binding command is null", Toast.LENGTH_LONG).show();           
            }        
        }    
     });
    }
    

    BindingAdapterのvalueはattrsとxmlのカスタムプロパティは一貫しています.そうしないと、バインドは成功しません.
    バインドされた関数は必ずstaticのもので、関数名には具体的な要求はありません.関数の最初のパラメータはバインド対象で、私たちがバインドしたのはViewです.それはViewです.
    次のパラメータは各プロパティです.レイアウトファイルでは必ず順番に行わなければなりません.そうしないと、エラーが発生する可能性があります.
    このプロパティをレイアウトファイルに適用する必要があります
    <ImageView
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:src="@drawable/tes"   
            binding:onClickCommand="@{viewmodel.mBindingCommand}" 
    />
    

    これまでコードレベルは問題ありませんでしたが、bindingが必要なのでまだ使えません.
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, getLayoutResId()); 
    

    ここでActivityMainBindingはシステムによって自動的に生成され、レイアウトファイルとプロパティのバインドが実現されます.つまり、クリックイベントが実現されます.
    最後に、イベントバインディングを実装するだけでなく、イベントのビジネス処理が必要であるため、ViewModelでコールバックできます.
    ViewModelでは、次のようにBindingAdapterの復帰を具体的に実現する必要があります.
    public ClickCallBack mBindingCommand = new ClickCallBack() {    
        @Override    
        public void clickEvent() {        
        Log.e("tag", "click");    
        }
    };
    

    このコールバックは、レイアウトファイルにバインドするだけで有効になります.
    コールバックオブジェクトが空であることがわかりました.設定が必要ですから.
    binding.setVariable(BR.viewmodel, mViewModel);
    

    これこそ完全なBindingAdapterプロセスです.
    注目すべきはbindingです.setVariable(BR.viewmodel, mViewModel);ViewModelを作成した後でなければなりません.そうしないと、コールバックパラメータをバインドして空になります.ViewModelは空に作成されていないので、自動生成されたコードを見ることができ、自動生成されたコードもデバッグできます.
    ImageViewをGlideでロードする画像を統一したい場合は、この方法で実現できます.
    @BindingAdapter({"imageUrl"})
        public static void loadImage(ImageView view, String u) {
            RequestOptions options = new RequestOptions()
                    .centerCrop()
                    .placeholder(R.mipmap.ic_launcher_round)
                    .error(R.mipmap.ic_launcher)
                    .priority(Priority.HIGH)
                    .diskCacheStrategy(DiskCacheStrategy.NONE);
            Glide.with(view.getContext()).applyDefaultRequestOptions(options).load(u).transition(new DrawableTransitionOptions().crossFade(1000)).into(view);
        }
    

    コード量が少なく、効率が高くなります.