androidandroid-constraintlayoutandroid-viewbindingviewstub

ViewStub inflation of ConstraintLayout


I want to leverage ViewStub to optionally show a portion of UI. When the root of my inflated item is ConstraintLayout then it doesn't render. ConstraintLayout

But if that root is MaterialCardView then it displays as intended. MaterialCardView

<!-- my_fragment.xml -->

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/fragmentRootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ViewStub
        android:id="@+id/fragmentViewStub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inflatedId="@+id/fragmentViewStub"
        android:layout="@layout/item"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- item.xml -->

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/itemRootLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/itemLabel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/itemLabelText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
/* MyFragment.kt */

@AndroidEntryPoint
class MyFragment : Fragment(R.layout.my_fragment) {
    private val viewModel: MyViewModel by viewModels()

    private val viewBinding: MyFragmentBinding by viewLifecycleLazy {
        MyFragmentBinding.bind(requireView())
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewBinding.fragmentViewStub.inflate()
    }
}

I've tried matching the ViewStub's id/inflatedId attributes and programmatically setting dimensions/constraints but neither solved the issue.

What am I overlooking about making these pieces work together?


Solution

  • Forgot to update with my answer/oversight. This worked as expected in both cases all along.

    Nightmode was enabled and the behavior of MaterialCardView has automatic contrast between its card and content. Meanwhile, when ConstraintLayout inverts its theme the label appears to be missing but is indeed present, as white text on white background.