Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConstraintLayout Barrier in dynamic feature module fails

I have a ConstraintLayout within an XML layout, it contains 3 views and a Barrier, they are button2, textView2, barrier2, and button3. As expected, button3 is successfully placed under both button2 and textView2, constrained by using barrier2. However it seems fail to refer to the constraining views (button2 and textView2) when used in the dynamic feature module, so that button3 sticks to top.

These screenshots show it is successful is base module, but not working in dynamic feature module:

Screenshots

The XML layouts both in base and dynamic feature are like this:

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView 2"
        app:layout_constraintStart_toEndOf="@id/button2"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Barrier
        android:id="@+id/barrier2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="bottom"
        app:constraint_referenced_ids="button2,textView2" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 3"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/barrier2" />
</androidx.constraintlayout.widget.ConstraintLayout>

However, it is success if I set the constraint with code instead of XML:

  barrier2.referencedIds = intArrayOf(R.id.button2, R.id.textView2)

How to correctly refer to button2 and textView2 within the XML layout?

like image 656
fikr4n Avatar asked Dec 05 '18 05:12

fikr4n


Video Answer


1 Answers

Inspecting the (decompiled) source code, I found a (hacky?) solution: by using fully qualified resource ID (package:type/entry). It seems this is not "an official way" since the linter give an error, but it works.

Suppose the app package is com.example.app and the dynamic feature module name is dynfeat, prepend the ID with <package>.<module>:id/ like this:

app:constraint_referenced_ids="com.example.app.dynfeat:id/button2,com.example.app.dynfeat:id/textView2"

I am actually not satisfied with this solution, because code like is hard to maintain, for example, when renaming the dynamic feature module name. So that, the other solution is by subclassing the Barrier class and handle it in the constructor.

like image 136
fikr4n Avatar answered Sep 22 '22 03:09

fikr4n