カスタムビューでデータバインディングを使用しようとしています(可能な使用法はGeorge Mountが示した here です)。
<merge>
タグなしで複合ビューを構築することは想像できません。ただし、この状況ではデータバインディングが失敗します。
MyCompoundView
クラス:
public class MyCompoundView extends RelativeLayout {
MyCompoundViewBinding binding;
public MyCompoundView (Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
binding = MyCompoundViewBinding.inflate(inflater, this, true);
}
my_compound_view.xml
:by app:isGone="@{!data.isViewVisible}"
複合ビュー全体の可視性を制御したい
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
>
<data>
<variable name="data" type="com.example.MyViewModel"/>
</data>
<merge
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:isGone="@{!data.isViewVisible}">
<ImageView
Android:id="@+id/image_image"
Android:layout_width="60dp"
Android:layout_height="60dp"
app:imageUrl="@{data.imagePhotoUrl}"/>
<!-- tons of other views-->
</merge>
</layout>
コンパイラエラー:
Error:(13) No resource identifier found for attribute 'isGone' in package 'com.example'
Error:(17, 21) No resource type specified (at 'isGone' with value '@{!data.isViewVisible}').
すべての@BindingAdapter
メソッドが必要です。今私はFrameLayout
からビューを継承し、<RelativeLayout>
の代わりに<merge>
を使用します-そしてそれは動作します。しかし、私は追加のネストされたレイアウトを持っています。
質問:merge
attrsは無視されます。それを回避する方法はありますか?
Android Studio 1.5.1安定
Gradleプラグインcom.Android.tools.build:gradle:1.5.0
インフレーション後はマージオブジェクトがないため、マージタグで値を割り当てるものはありません。マージで機能するバインディングタグは考えられません。
タグをルート要素に割り当て、BindingAdapterを使用して必要な操作を実行できます。
<layout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
>
<data>
<variable name="data" type="com.example.MyViewModel"/>
</data>
<merge
Android:layout_width="wrap_content"
Android:layout_height="wrap_content">
<ImageView
app:isGone="@{!data.isViewVisible}"
Android:id="@+id/image_image"
Android:layout_width="60dp"
Android:layout_height="60dp"
app:imageUrl="@{data.imagePhotoUrl}"/>
<!-- tons of other views-->
</merge>
</layout>
Bindingクラス自体で何かを実行したい場合は、DataBindingUtilを使用してビューからオブジェクトを検索できます。
@BindingAdapter("isGone")
public static void setGone(View view, boolean isGone) {
ViewDataBinding binding = DataBindingUtil.findBinding(view);
//... do what you want with the binding.
}
実際には<merge>
タグ内<include>
とデータバインディングを行います。
例:
incl_button.xml
<layout>
<merge xmlns:Android="http://schemas.Android.com/apk/res/Android">
<Button Android:id="btn"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Click"
/>
</merge>
</layout>
fragment_example.xml
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<include
layout="@layout/incl_button"
Android:id="@+id/layout_btn" />
</LinearLayout>
</layout>
ExampleFragment.kt
binding.layoutBtn.btn.setOnClickListener{
//...
}