ViewBinding-インクルードされたレイアウトのバインディングを取得する方法は?


11

ViewBindingを使用していると、文書化されていないケースがほとんどありません。

最初に、含まれている汎用ビューレイアウトパーツのバインディングを取得するには、メインバインディングでメインレイアウトのアイテムのみを表示しますか?

2番目:含まれているマージタイプレイアウトパーツのバインディングを取得する方法、ここでもメインバインディングはメインレイアウトのアイテムのみを表示しますか?

回答:


15

の場合には:

  1. (マージノードではなく)一般的なレイアウトでインクルードします。インクルードパーツにIDを割り当てる必要があります。これにより、バインディングでインクルードサブパーツにアクセスできるようになります。
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />

このようにあなたの活動コードで:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    setContentView(exampleBinding.root)
    //we will be able to access included layouts view like this
    val includedView: View = exampleBinding.yourId.idOfIncludedView
//[...]
}
  1. 外部レイアウトのマージブロックに含めます。マージブロックはビューではないため、IDを追加できません。そのような永遠のマージレイアウト(merge_layout.xm)があるとしましょう:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="@layout/activity_example">

    <TextView
        android:id="@+id/some_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World" />
</merge>

このようなマージレイアウトを適切にバインドするには、以下を行う必要があります。

あなたの活動コードで:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout
private lateinit var mergeBinding: MergeLayoutBinding  //merge_layout.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    //we need to bind the root layout with our binder for external layout
    mergeBinding = MergeLayoutBinding.bind(exampleBinding.root)
    setContentView(exampleBinding.root)
    //we will be able to access included in merge layout views like this
    val mergedView: View = mergeBinding.someView
//[...]
}

1
これはバグのようです。それはうまくいくはずです
ミゲル

7

最初の質問は、ViewBindingを使用してインクルードレイアウトを操作することです。これは非常に簡単に解決できます。

main_fragment.xmlファイルのサンプルを次に示します

<?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">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view_main"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

</LinearLayout>

そしてMainFragment.javaはこのようにすることができます

public class MeaningFragment extends Fragment {

    private MainFragmentBinding binding;
    private ToolbarBinding toolbarBinding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

        binding = MainFragmentBinding.inflate(inflater, container, false);
        toolbarBinding = binding.toolbar;

        return binding.getRoot();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        toolbarBinding = null;
        binding = null;
    }
}

これで、2つのバインディングができました。それらの1つはデフォルトであり、次は含まれているレイアウトからのものです。


1
非常に単純な答えで、新しい構文を使用します。すべてが、で同様の構文を持つ非フラグメントアクティビティで機能しますonCreate()。ありがとう。(ちょうどを使用するのに少し問題がありますDrawerLayout
Fat Monk

0

他の簡単な方法は、データバインディングライブラリを使用することです。次に、XMLレイアウトをタグでラップして、ライブラリを使用している場合、レイアウト内のビューをデータオブジェクトにバインドするために必要なクラスを自動的に生成します。正直なところ、それが進むべき道だと思います。こちらのガイドに従ってください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.