0

Please help me find a way to combine two ConstraintLayouts so that the ImageViews are displayed correctly.

I have an activity that used to work fine for quite a few years. But after updating to androidx and updating to androidx.constraintlayout:constraintlayout:2.1.2 from 1.1.3, all ImageViews in one of the ConstraintLayouts has lost its position. Strangely, I can't get this activity back to the way it used to be displayed by changing back to the 1.1.3-version... The only thing that works is to go back to an older backuped version. Doing this however, does not seem to be a good solution since it probably won't be compatible with future updates.

The structure of this Activity-view is described in the picture below. One ConstraintLayout is putting one child ConstraintLayout and one child LinearLayout together using two FrameLayouts. These two FrameLayouts are positioned using a HorizontalGuideline in percent, that splits the view in two. The LinearLayout displays correctly. But the ImageViews in the child ConstraintsLayout either:

  1. For MatchParent: The ImageViews forgets all about their relative position to each other, gets detached to each other and spread out over the screen and even outside of the cellphone screen.

  2. For WrapContent: The ImageViews forgets all about their relative position to each other, gets position in the center of the cellphone screen. The center looks like a miniature window of the child ConstraintLayout with its ImageViews squezed together and on top of each other.

The ImageViews in the child ConstraintLayout are displayed with the help of one vertical and one horizontal guidelines, these are set in percent. What have I missed here?

(I assume there might be a work-around using a different layout instead of the child ConstraintLayout, but that would probably mess-up already developed animations... Hence, I would like to avoid that.)

[Views in design mode and on the cellphone screen][1]

[Structure][2]

Code parent ConstraintLayout

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/Constraintlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline14"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.85" />

    <FrameLayout
        android:id="@+id/containergame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/guideline14"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@+id/containergamecontrol"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/guideline14" />

</androidx.constraintlayout.widget.ConstraintLayout>

Code child ConstraintLayout (failing on device, but looks ok in design view in Android Studio)

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5" />

    <ImageView
        android:id="@+id/tile2"
        style="@style/TileButton_3by3"
        android:src="@drawable/borderpiece_upper"
        android:visibility="visible"
        app:layout_constraintLeft_toRightOf="@+id/guideline5"
        app:layout_constraintRight_toLeftOf="@+id/guideline5"
        app:layout_constraintTop_toBottomOf="@id/guideline6"
        app:layout_constraintBottom_toTopOf="@id/tile5"
        tools:ignore="ContentDescription" />


    <ImageView
        android:id="@+id/tile1"
        style="@style/TileButton_3by3"
        android:src="@drawable/cornerpiece_left_upper"
        android:visibility="visible"
        app:layout_constraintRight_toLeftOf="@+id/tile2"
        app:layout_constraintTop_toBottomOf="@+id/guideline6"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/tile3"
        style="@style/TileButton_3by3"
        android:src="@drawable/cornerpiece_right_upper"
        android:visibility="visible"
        app:layout_constraintLeft_toRightOf="@+id/tile2"
        app:layout_constraintTop_toBottomOf="@+id/guideline6"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/tile5"
        style="@style/TileButton_3by3"
        android:src="@drawable/centerpiece"
        android:visibility="visible"
        app:layout_constraintLeft_toRightOf="@+id/guideline5"
        app:layout_constraintRight_toLeftOf="@+id/guideline5"
        app:layout_constraintTop_toBottomOf="@+id/tile2"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/tile4"
        style="@style/TileButton_3by3"
        android:src="@drawable/borderpiece_left"
        android:visibility="visible"
        app:layout_constraintRight_toLeftOf="@+id/tile5"
        app:layout_constraintTop_toBottomOf="@+id/tile1"
        tools:ignore="ContentDescription" />


    <ImageView
        android:id="@+id/tile6"
        style="@style/TileButton_3by3"
        android:src="@drawable/borderpiece_right"
        android:visibility="visible"
        app:layout_constraintLeft_toRightOf="@+id/tile5"
        app:layout_constraintTop_toBottomOf="@+id/tile3"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/tile8"
        style="@style/TileButton_3by3"
        android:src="@drawable/borderpiece_bottom"
        android:visibility="visible"
        app:layout_constraintLeft_toRightOf="@+id/guideline5"
        app:layout_constraintRight_toLeftOf="@+id/guideline5"
        app:layout_constraintTop_toBottomOf="@+id/tile5"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/tile7"
        style="@style/TileButton_3by3"
        android:src="@drawable/cornerpiece_left_bottom"
        android:visibility="visible"
        app:layout_constraintRight_toLeftOf="@+id/tile8"
        app:layout_constraintTop_toBottomOf="@+id/tile4"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/tile9"
        style="@style/TileButton_3by3"
        android:src="@drawable/cornerpiece_right_bottom"
        android:visibility="visible"
        app:layout_constraintLeft_toRightOf="@+id/tile8"
        app:layout_constraintTop_toBottomOf="@+id/tile6"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand12"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand11"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand10"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand9"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand8"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand7"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand6"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand5"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand4"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand3"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />


    <ImageView
        android:id="@+id/operand2"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <ImageView
        android:id="@+id/operand1"
        style="@style/Operand_3by3"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.6"
        app:srcCompat="@drawable/operand_level_list"
        tools:ignore="ContentDescription" />

    <TextView
        android:id="@+id/number2"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile2"
        app:layout_constraintEnd_toEndOf="@+id/tile2"
        app:layout_constraintStart_toStartOf="@+id/tile2"
        app:layout_constraintTop_toTopOf="@+id/tile2" />

    <TextView
        android:id="@+id/number1"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile1"
        app:layout_constraintEnd_toEndOf="@+id/tile1"
        app:layout_constraintStart_toStartOf="@+id/tile1"
        app:layout_constraintTop_toTopOf="@+id/tile1" />

    <TextView
        android:id="@+id/number3"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile3"
        app:layout_constraintEnd_toEndOf="@+id/tile3"
        app:layout_constraintStart_toStartOf="@+id/tile3"
        app:layout_constraintTop_toTopOf="@+id/tile3" />

    <TextView
        android:id="@+id/number5"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile5"
        app:layout_constraintEnd_toEndOf="@+id/tile5"
        app:layout_constraintStart_toStartOf="@+id/tile5"
        app:layout_constraintTop_toTopOf="@+id/tile5" />

    <TextView
        android:id="@+id/number4"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile4"
        app:layout_constraintEnd_toEndOf="@+id/tile4"
        app:layout_constraintStart_toStartOf="@+id/tile4"
        app:layout_constraintTop_toTopOf="@+id/tile4" />

    <TextView
        android:id="@+id/number6"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile6"
        app:layout_constraintEnd_toEndOf="@+id/tile6"
        app:layout_constraintStart_toStartOf="@+id/tile6"
        app:layout_constraintTop_toTopOf="@+id/tile6" />

    <TextView
        android:id="@+id/number8"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile8"
        app:layout_constraintEnd_toEndOf="@+id/tile8"
        app:layout_constraintStart_toStartOf="@+id/tile8"
        app:layout_constraintTop_toTopOf="@+id/tile8" />

    <TextView
        android:id="@+id/number7"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile7"
        app:layout_constraintEnd_toEndOf="@+id/tile7"
        app:layout_constraintStart_toStartOf="@+id/tile7"
        app:layout_constraintTop_toTopOf="@+id/tile7" />

    <TextView
        android:id="@+id/number9"
        style="@style/Number_3by3"
        app:layout_constraintBottom_toBottomOf="@+id/tile9"
        app:layout_constraintEnd_toEndOf="@+id/tile9"
        app:layout_constraintStart_toStartOf="@+id/tile9"
        app:layout_constraintTop_toTopOf="@+id/tile9" />

    <TextView
        android:id="@+id/operands"
        style="@style/Operands_as_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@+id/guideline6"
        app:layout_constraintHorizontal_bias="0.50"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/operand1"
        app:layout_constraintVertical_bias="1.0" />

</androidx.constraintlayout.widget.ConstraintLayout>


  [1]: https://i.stack.imgur.com/zCwvG.png
  [2]: https://i.stack.imgur.com/BnVdW.png
  • It would be helpful to show the layout XML and maybe two images showing the good and the bad representations. It is hard to know what is going on without that information. However, from your question, it looks like you are using 'match_parent' for a dimension of a child of a _ConstraintLayot_ - don't do that. Change the dimensions to '0dp' with the constraints set to the parent. – Cheticamp Jan 04 '22 at 13:57
  • Please include your XML code. – Pierre Janineh Jan 04 '22 at 14:14
  • I've added the code and also tried to add views of the result - you will find them as links at the bottom of the page. – Creative_P Jan 05 '22 at 14:34
  • It looks like some of your constraints aren't right. For instance, for tile2, you specify `app:layout_constraintLeft_toRightOf="@+id/guideline5"` and `app:layout_constraintRight_toLeftOf="@+id/guideline5"` which will result in a zero width. Check all your constraints for problems like this. Issues like this will cascade throughout your layout. Not sure why design view doesn't show a problem. – Cheticamp Jan 05 '22 at 14:54
  • Noop, it should not give a zero width since the constraints only positions views. As a test I altered the child ConstraintLayout using horizontal and vertical chains and style packed. I also deleted the vertical guideline. Nothing changed - looks the same as before in Design mode in Android Studio and on the device. This leads me to believe that there is nothing wrong with the child ConstraintLayout and possibly not in the XML-code. The child is showing a fragment and the parent an activity. Could something in the java-code make the activity misunderstand how to properly show the fragment? – Creative_P Jan 06 '22 at 23:16

1 Answers1

0

Solved it!

Remember, we had ImageViews that were wrongly positioned after an update to AndroidX. This also made the view of the fragment lose it's shape. To see a picture of this weird behavior please look at this:

In turned out that the problem was an incautious java-programing on my part. I wanted the ImageViews to be connected to the program logic in the rest of my java-code. To achieve this I altered the Ids on the ImageViews themselves, so that the id's carried some information connected to the other code. I did this in the onCreateView method in my fragment like this:

int id = <A unique integer carrying some information>

iv.setId(id)

Erasing these two lines of code above leaving the id:s unchanged, makes the app work flawless again.

Hmmm, how could this be? Well, I guess that the id's of the ImageViews are read earlier by the layout engine in AndroidX and before the change of the id's in the onCreateView method in my java-code takes place. So when I change the id:s to something else (afterwards), I accidentally destroy the link between the awareness of the views and the views themselves, leaving the layout engine confused.

Lesson learned: Never change the id's of the ImageViews unless you know exactly when the id:s are read and how they are used by the layout engine.

glennsl
  • 28,186
  • 12
  • 57
  • 75