jakub
jakub

Reputation: 196

Strange constrainlayout behavior

i would like to ask you, if you have similar problem with constraint layout. fragment is not correctly formatted when fragment element contains id tag.

incorrectly formatted layout

i have activity with only one fragment defined in xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
    android:id="@+id/initial__initial_fragment"
    android:name="com.touch4it.taxi.screens.initial.InitialFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout="@layout/initial__fragment__layout" />

fragment constraint one constrain layout:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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/initial__fragment__layout__holder_CL"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <EditText
    android:id="@+id/initial__fragment__layout__phone_number_ET"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="phone"
    android:text="Name"
    android:singleLine="true"
    app:layout_constraintLeft_toLeftOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginStart="16dp"
    app:layout_constraintTop_toBottomOf="@+id/initial__fragment__layout__user_name_ET"
    android:layout_marginTop="48dp"
    app:layout_constraintRight_toRightOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginEnd="16dp" />

    <EditText
    android:id="@+id/initial__fragment__layout__user_name_ET"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10"
    android:inputType="textPersonName"
    android:text="Name"
    android:singleLine="true"
    app:layout_constraintLeft_toLeftOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginStart="16dp"
    app:layout_constraintTop_toBottomOf="@+id/initial__fragment__layout__log_in_label_TV"
    android:layout_marginTop="64dp"
    app:layout_constraintRight_toRightOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginEnd="16dp" />

    <Button
    android:id="@+id/initial__fragment__layout__login_B"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:text="Button"
    app:layout_constraintLeft_toLeftOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginStart="16dp"
    app:layout_constraintRight_toRightOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginEnd="16dp"
    app:layout_constraintBottom_toBottomOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginBottom="16dp" />

    <TextView
    android:id="@+id/initial__fragment__layout__log_in_label_TV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TextView"
    app:layout_constraintLeft_toLeftOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginStart="16dp"
    app:layout_constraintTop_toTopOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginTop="48dp"
    app:layout_constraintRight_toRightOf="@+id/initial__fragment__layout__holder_CL"
    android:layout_marginEnd="16dp" />

</android.support.constraint.ConstraintLayout>

when fragment layout is used in activity directly, everything is ok.

Upvotes: 2

Views: 445

Answers (1)

Nicolas Roard
Nicolas Roard

Reputation: 8449

This is caused by the fact that when getting the layout in a fragment, the id of the element will not be the one you used when defining the layout. For example, in your code you have:

app:layout_constraintLeft_toLeftOf="@+id/initial__fragment__layout__holder_CL"

and the parent element correctly contains the id:

<android.support.constraint.ConstraintLayout
...
    android:id="@+id/initial__fragment__layout__holder_CL"
...

The problem is that your fragment tag itself has a different id, initial__initial_fragment:

<fragment
    android:id="@+id/initial__initial_fragment"
...

So when the fragment loads the layout, the layout elements, which are referencing the id initial__fragment__layout__holder_CL, won't find it, and the views are thus not being able to be constrained.

There are two things you could do to fix this issue.

The first option is to use the same id in both places:

<fragment
    android:id="@+id/initial__fragment__layout__holder_CL"
...

The second option (definitely preferrable) is to update to a newer version of ConstraintLayout (starting from alpha 5 -- but note that alpha 6 is available and fixes some issues in alpha 5). Alpha 5 introduced a new notation for this exact case -- instead of having to specify a parent id, you could instead use:

app:layout_constraintLeft_toLeftOf="parent"

Note too that with Android Studio 2.2 beta 1, the layout editor will automatically replace references to parent by the string "parent" instead of using an id. So the simplest thing to fix your layout would be to update to AS 2.2 beta 1, change your gradle file to point to constraintlayout alpha 6, open your layout and save it.

Upvotes: 2

Related Questions