2016-01-14 11 views
27

Android data binding guideでは、アクティビティまたはフラグメント内の値のバインディングについて説明していますが、カスタムビューでデータバインディングを実行する方法はありますか? my_custom_view.xmlカスタムビューでのアンドロイドデータバインディング

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <com.mypath.MyCustomView 
     android:id="@+id/my_view" 
     android:layout_width="match_parent" 
     android:layout_height="40dp"/> 

</LinearLayout> 

::私のような何かをしたいと思います

<layout> 

<data> 
    <variable 
     name="myViewModel" 
     type="com.mypath.MyViewModelObject" /> 
</data> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@{myViewModel.myText}" /> 

</LinearLayout> 

</layout> 

カスタムを設定することによってこれを行うことが可能に見えるが、これはすぐに面倒になる、カスタムビューの属性バインドする値がたくさんある場合。

私がやろうとしていることを達成する良い方法はありますか?カスタムビューで

+0

あなたは、カスタマービューを膨張させた後、あなたのMyCustomViewクラス内のデータを結合しようとしましたか? –

+0

私はこれを達成するためにいくつかのことを試みましたが、バインディング関数はアクティビティやフラグメントに含まれる情報を必要とするようです。 これらの例では、カスタムビュー内でこれを達成する方法のサンプルが提供されていませんでした。これを達成するための簡単なコードスニペットは非常に高く評価されます。 – Dave

+0

FYI:xmlレイアウトファイルには、慣例によりアンダースコア表記が付けられていると思います。 –

答えて

31

、しかし、あなたは通常どおりのレイアウトを膨らませると、設定したい属性のセッターを提供:

<layout xmlns...> 
    <data> 
     <variable 
      name="myViewModel" 
      type="com.mypath.MyViewModelObject" /> 
    </data> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <com.mypath.MyCustomView 
      android:id="@+id/my_view" 
      app:myViewModel="@{myViewModel}" 
      android:layout_width="match_parent" 
      android:layout_height="40dp"/> 

    </LinearLayout> 
</layout> 

private MyCustomViewBinding mBinding; 
public MyCustomView(...) { 
    ... 
    LayoutInflater inflater = (LayoutInflater) 
     context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    mBinding = MyCustomViewBinding.inflate(inflater); 
} 

public void setMyViewModel(MyViewModelObject obj) { 
    mBinding.setMyViewModel(obj); 
} 

は、次にレイアウトで、あなたはそれを使用します上記では、名前がsetMyViewModelのセッターが存在するため、app:myViewModelの自動バインディング属性が作成されています。

+0

ありがとう! 私が抱えていた苦労の一部は、Android Studioからキャッシュを無効にする必要があり、中間ファイルを取り除き新しいバインディングファイルを生成するためにプロジェクトを数回再構築しました。すべての赤で何がうまくいかないのかを知ることは困難でした。 – Dave

+1

タイプ「MyCustomViewBinding」はどこで作成されますか? –

+0

MyCustomViewBindingは、データバインディングフレームワークの一部としてアノテーションプロセッサを介して生成されます。 xmlファイル(DaveはMyCustomView.xmlを使用しましたが、実際にはmy_custom_view.xmlを意味しました。大文字と小文字はリソースファイルですべて小文字にする必要があるため)では、MyCustomViewBindingのデフォルトのBindingクラス名(Bindingの接尾辞はキャラルケース)。また、Bindingクラス名をカスタマイズすることもできます。http://developer.android.com/tools/data-binding/guide.html#custom_binding_class_names –

4

まず、このカスタムビューがアクティビティなどの別のレイアウトの<include>になっている場合は、これを行わないでください。予期しない値のタグに関する例外が表示されます。データバインディングはすでにバインディングを実行していたため、設定されています。

onFinishInflateを使用してバインドを実行しようとしましたか? (Kotlin例)

override fun onFinishInflate() { 
    super.onFinishInflate() 
    this.dataBinding = MyCustomBinding.bind(this) 
} 

あなたのビューで結合を使用する場合、少なくともそれもできれば両方をサポートするのは非常に複雑になり、プログラム的に作成することができないことに注意してください。

1

Following the solution presented by georgeアンドロイドスタジオのグラフィカルエディタはカスタムビューをレンダリングできませんでした。その理由は、何のビューは実際には次のコードで膨張されていないこと、である:

public MyCustomView(...) { 
    ... 
    LayoutInflater inflater = (LayoutInflater) 
     context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    mBinding = MyCustomViewBinding.inflate(inflater); 
} 

私はしかし、グラフィカルエディタがそれを好きではなかった、バインディングがインフレを扱うこととします。

私の具体的な使用例では、ビューモデル全体ではなく、単一のフィールドをバインドしたかったのです。私は思いついた(kotlin incoming):

class LikeButton @JvmOverloads constructor(
     context: Context, 
     attrs: AttributeSet? = null, 
     defStyleAttr: Int = 0 
) : ConstraintLayout(context, attrs, defStyleAttr) { 

    val layout: ConstraintLayout = LayoutInflater.from(context).inflate(R.layout.like_button, this, true) as ConstraintLayout 

    var numberOfLikes: Int = 0 
     set(value) { 
      field = value 
      layout.number_of_likes_tv.text = numberOfLikes.toString() 
     } 
} 

同様のボタンは画像とテキストビューで構成されています。テキストビューには、データバインディングを使用して設定する好き嫌いの数が保持されます。データを自動的に結合は関連付けを行い、次のXML内の属性としてnumberOfLikes用セッターを使用することにより

<views.LikeButton 
    android:id="@+id/like_btn" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:numberOfLikes="@{story.numberOfLikes}" /> 

深い読み:あなたは何をしているかに基づいてhttps://medium.com/google-developers/android-data-binding-custom-setters-55a25a7aea47

0

、私がしようとしましたMyCustomBinding.bind(this)を実行しても、もう機能しなくなりました。バインディングはすでに行われていますが、代わりにそれを見つけることができます。

private MyCustomBinding binding; 

@Override 
protected void onAttachedToWindow() { 
    super.onAttachedToWindow(); 

    binding = DataBindingUtil.getBinding(this); //got the binding! 
    MyViewModelObject model = MyViewModelObject.get("myText"); 

    binding.setVariable(BR.myViewModel, model); 
} 
関連する問題