I have three views in a constraint layout A (textview), B(textview) and C (imageview). B have dynamic text and hence I want it to grow as much as possible but without touching C. It can have multiple lines but I don't want to fix its width and shouldn't make C off screen. How can I use constraint layout for such layout. This is what I want to achieve https://i.stack.imgur.com/EIbnz.png If the text is more, make it multiline. This is what I get https://i.stack.imgur.com/VG7Z5.png
.The last image view is pushed out of screen if text is long.
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#drawable/button_background_rounded_gray"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="30dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/docIcon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:textAllCaps="true"
android:gravity="center"
android:text="PDF"
android:textColor="#color/tcWhite"
android:background="#drawable/button_background_rounded_red"
android:layout_marginStart="10dp"
android:textSize="7sp"
android:layout_width="20dp"
android:layout_height="20dp"/>
<androidx.appcompat.widget.AppCompatTextView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:textSize="12sp"
android:id="#+id/docName"
tools:text="Accommodation Voucher - Circus at Disneyland Paris - Demo - 11 Oct.pdf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintStart_toEndOf="#+id/docIcon"
android:layout_gravity="center_vertical"/>
<androidx.appcompat.widget.AppCompatImageView
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/docStatus"
app:srcCompat="#drawable/ic_picture_as_pdf_red_24dp"
android:layout_marginEnd="10dp"
android:layout_width="20dp"
android:layout_height="20dp"
app:layout_constraintStart_toEndOf="#+id/docName"/>
You don't show how the overall width for ConstraintLayout that you posted is determined. For this answer, I use match_parent but another constraint will work as well.
I key to allowing the text to expand to the constraints but still honor the constraints is to set app:layout_constrainedWidth="true" on the TextView. I have also placed the three views into a horizontal chain. See the ConstraintLayout Developer Guide.
WRAP_CONTENT : enforcing constraints (Added in 1.1)If a dimension is set to WRAP_CONTENT, in versions before 1.1 they will be treated as a literal dimension -- meaning, constraints will not limit the resulting dimension. While in general this is enough (and faster), in some situations, you might want to use WRAP_CONTENT, yet keep enforcing constraints to limit the resulting dimension. In that case, you can add one of the corresponding attribute:
app:layout_constrainedWidth=”true|false”
app:layout_constrainedHeight=”true|false”
activity_main.xml
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/docIcon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:background="#drawable/ic_launcher_background"
android:gravity="center"
android:text="PDF"
android:textColor="#android:color/white"
android:textSize="7sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/docName"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:textAllCaps="true" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/docName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="This is a very long name. This is a very long name. This is a very long name. "
android:textSize="12sp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/docStatus"
app:layout_constraintStart_toEndOf="#+id/docIcon"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/docStatus"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/docName"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_launcher_foreground" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is a simpler demonstration.
activity_main.xml
<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="400dp"
android:layout_height="wrap_content"
android:background="#android:color/darker_gray">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Type here..."
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="#+id/imageView"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#+id/button"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#mipmap/ic_launcher" />
</androidx.constraintlayout.widget.ConstraintLayout>
Add those two properties to the second AppCompactTextView
app:layout_constraintRight_toRightOf="#id/docStatus"
app:layout_constraintHorizontal_bias="1"
And make the width of that textView to 0dp.
Related
I got a RelativeLayout like this:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
Inside this Layout, there are some TextView and other stuff, through which the height of the Layout is defined, because it is set to wrap_content like you can see above.
Now I want to have have two Views in the RelativeLayout who share the space(in respect to width) but fill the whole Layout. The purpose behind this is, that I want to have two onClickListener. In other words: I want to kind of split the layout in two Views next to another (horizontally).
I tried to put a LinearLayout inside the RelativeLayout like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<TextView
android:id="#+id/togoTrueTrigger"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:id="#+id/togoFalseTrigger"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
It takes the whole with of the RelativeLayout and one TextView takes the left 50% and the other one the right 50%. That is exactly what I want. BUT I also want them to take the whole Height.
What I can't do: Set the Height of the LinearLayout to match_parent. This is not possible, because the whole thing is inside another layout and this would adjust the Height in relation to this layout.
EDIT: This is my new approach
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="15dp">
<TextView
android:id="#+id/togoTrue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pickup"
android:textAppearance="#style/itemConfiguration"
app:layout_constraintLeft_toLeftOf="parent"/>
<com.bhargavms.podslider.PodSlider
android:id="#+id/togoSwitch"
android:layout_width="75dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
app:numberOfPods="2"
app:selectedPodColor="#color/colorAccent"
app:mainSliderColor="#color/colorPrimary"
app:podColor="#ffffff"
android:layout_centerInParent="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="#+id/togoFalse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vor Ort"
android:textAppearance="#style/itemConfiguration"
app:layout_constraintRight_toRightOf="parent"/>
<View
android:id="#+id/togoTrueTrigger"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<View
android:id="#+id/togoFalseTrigger"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.5"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>
Unfortunately this still doesn't work.
EDIT:
Here is a sketch of what I want. The first picture is the layout and the second shows the same layout with a blue and a red view. These Views are the ones I try to create.
So there are three views inside of the main layout and two views with 50% width obove of them. I believe this is Your answer:
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/togoTrue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pickup"
android:textAppearance="#style/itemConfiguration"
app:layout_constraintLeft_toLeftOf="parent" />
<com.bhargavms.podslider.PodSlider
android:id="#+id/togoSwitch"
android:layout_width="75dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:mainSliderColor="#color/colorPrimary"
app:numberOfPods="2"
app:podColor="#ffffff"
app:selectedPodColor="#color/colorAccent" />
<TextView
android:id="#+id/togoFalse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vor Ort"
android:textAppearance="#style/itemConfiguration"
app:layout_constraintRight_toRightOf="parent" />
<View
android:id="#+id/togoTrueTrigger"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#44ffff00"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent=".5" />
<View
android:id="#+id/togoFalseTrigger"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#4400ff00"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent=".5" />
</android.support.constraint.ConstraintLayout>
Try taking a look at ConstraintLayout.
Though initially a bit intimidating it does everything all the other layouts can do and much more (including what you just asked by using "match_constraint").
It's part of the Support Library as well, so it's usable in older projects.
If I understood you correctly, you want these two Views for the purpose of setting an OnClickListener on them. This is how I would go about it:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/togoTrue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pickup"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/togoSwitch"
app:layout_constraintTop_toTopOf="parent" />
<com.bhargavms.podslider.PodSlider
android:id="#+id/togoSwitch"
android:layout_width="75dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
app:numberOfPods="2"
app:selectedPodColor="#color/colorAccent"
app:mainSliderColor="#color/colorPrimary"
app:podColor="#ffffff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#id/togoTrue"
app:layout_constraintRight_toLeftOf="#id/togoFalse"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/togoFalse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Vor Ort"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#id/togoSwitch"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/togoTrueTrigger"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#id/togoFalseTrigger"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/togoFalseTrigger"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#id/togoTrueTrigger"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Trying to make a really simple layout for a settings page using ConstraintLayout.
Simple text views to the left one below the other and a switch to the right to the center.
The layout I have works fine for newer devices, but as soon I switch to a Nexus 4 or older, the switch goes below/disappears from the view.
Here is my layout code,
<android.support.constraint.ConstraintLayout
android:id="#+id/locationLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="parent">
<TextView
android:id="#+id/locationTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="#string/location_title"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="#id/guidelineLocationLayout"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textSize="16sp"/>
<TextView
android:id="#+id/locationDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/location_description"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationTitle"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="#id/locationTitle"
app:layout_constraintRight_toLeftOf="#id/guidelineLocationLayout"
android:textSize="12sp"
/>
<Switch
android:id="#+id/locationPermissionSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#id/guidelineLocationLayout"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="parent"/>
<View
android:id="#+id/viewLocationLayout"
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="#d6d6d6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationDescription"/>
<android.support.constraint.Guideline
android:id="#+id/guidelineLocationLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="48dp" />
</android.support.constraint.ConstraintLayout>
And here are how the constraints look like for the Pixel 2XL,
Here is how they look on a smaller device,
I have used 0dp width for the long description and defined left and right constraints, anything else I could do?
You can use barriers instead of guidelines because a Barrier references multiple widgets as input, and creates a virtual guideline based on the most extreme widget on the specified side.
According to the Documentation
Similar to a guideline, a barrier is an invisible line that you can
constrain views to. Except a barrier does not define its own position;
instead, the barrier position moves based on the position of views
contained within it. This is useful when you want to constrain a view
to the a set of views rather than to one specific view.
Hope this helps you. I've used barrier instead of guideline.
<?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/locationLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="parent">
<TextView
android:id="#+id/locationTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Save location to the song"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/locationDescription"
android:layout_width="261dp"
android:layout_height="32dp"
android:text="Your location is only requested when a new song is identified. Location details are never sent to the server"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationTitle" />
<android.support.constraint.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="locationDescription,locationTitle" />
<Switch
android:id="#+id/locationPermissionSwitch"
android:layout_width="41dp"
android:layout_height="26dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/barrier"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="#+id/viewLocationLayout"
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="#d6d6d6"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/locationDescription" />
</android.support.constraint.ConstraintLayout>
You need to change the constraints of the switch like this
<Switch
android:id="#+id/locationPermissionSwitch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#id/guidelineLocationLayout"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
You are constraining the bottom of the switch to the top of the parent and top of the switch to the bottom of the parent. You have to change it to layout_constraintTop_toTopOf and layout_constraintBottom_toBottomOf
I'm very new (Day 1) to Android programming so I might be missing something very obvious.
In this, why is "Weight" TextView and it's EditText component not exactly above each other? Same goes for the NumberPicker and "Reps" TextView. From what I understand, as width is same for both components and margin is same too, they should be exactly above each other.
XML for reference:-
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#android:color/background_light"
tools:context="host.abhi.rmcalc.MainActivity">
<TextView
android:id="#+id/noRepsHeading"
android:layout_width="110dp"
android:layout_height="45dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:gravity="center"
android:text="Reps"
android:textColor="#color/colorPrimaryDark"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="#+id/noReps"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/enteredWeightHeading"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/enteredWeight"
android:layout_width="110dp"
android:layout_height="107dp"
android:layout_marginBottom="80dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:defaultFocusHighlightEnabled="true"
android:ems="10"
android:filterTouchesWhenObscured="false"
android:fontFamily="#font/archivo_black"
android:gravity="center"
android:hint="00"
android:inputType="textPersonName|numberDecimal"
android:textSize="50sp"
app:layout_constraintBottom_toTopOf="#+id/oneRepMax"
app:layout_constraintEnd_toStartOf="#+id/noReps"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/enteredWeightHeading"
tools:focusableInTouchMode="true" />
<TextView
android:id="#+id/oneRepMax"
android:layout_width="391dp"
android:layout_height="0dp"
android:layout_marginBottom="150dp"
android:layout_marginTop="8dp"
android:background="#android:color/darker_gray"
android:fontFamily="#font/archivo_black"
android:gravity="center"
android:textColor="?attr/colorPrimaryDark"
android:textSize="100sp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/oneRepMaxHeading" />
<NumberPicker
android:id="#+id/noReps"
android:layout_width="110dp"
android:layout_height="109dp"
android:layout_marginBottom="78dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
app:layout_constraintBottom_toTopOf="#+id/oneRepMax"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/enteredWeight"
app:layout_constraintTop_toBottomOf="#+id/noRepsHeading" />
<TextView
android:id="#+id/enteredWeightHeading"
android:layout_width="110dp"
android:layout_height="45dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:gravity="center"
android:text="Weight"
android:textColor="#color/colorPrimaryDark"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="#+id/enteredWeight"
app:layout_constraintEnd_toStartOf="#+id/noRepsHeading"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/oneRepMaxHeading"
android:layout_width="283dp"
android:layout_height="53dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="180dp"
android:gravity="center"
android:text="1RM Estimated"
android:textColor="#color/colorPrimaryDark"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
This is the culprit right here
<TextView
android:id="#+id/enteredWeightHeading"
android:layout_width="110dp"
android:layout_height="45dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:gravity="center"
android:text="Weight"
android:textColor="#color/colorPrimaryDark"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="#+id/enteredWeight"
app:layout_constraintEnd_toStartOf="#+id/noRepsHeading"
app:layout_constraintHorizontal_chainStyle="spread_inside" <!--PROBLEM HERE-->
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
The simplest explanation is that there are 3 chainStyles
Packed - The elements in the chain are place as close to each other as possible, with any remaining space pushed towards the margins.
Spread_inside - The first 2 elements are placed starting and ending at the margins and any remaining space or widgets are distributed evenly between the first 2 elements.
Spread (Default) - All the widgets and any remaining space is distributed evenly in the view.
To fix the problem just change the chainStyle to spread
<TextView
android:id="#+id/enteredWeightHeading"
android:layout_width="110dp"
android:layout_height="45dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:gravity="center"
android:text="Weight"
android:textColor="#color/colorPrimaryDark"
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="#+id/enteredWeight"
app:layout_constraintEnd_toStartOf="#+id/noRepsHeading"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Hope this helps!
Edit
From the documentaion
Spread: The views are evenly distributed (after margins are accounted for). This is the default.
Spread inside: The first and last view are affixed to the constraints on each end of the chain and the rest are evenly distributed.
Weighted: When the chain is set to either spread or spread inside, you can fill the remaining space by setting one or more views to "match constraints" (0dp). By default, the space is evenly distributed between each view that's set to "match constraints," but you can assign a weight of importance to each view using the layout_constraintHorizontal_weight and layout_constraintVertical_weight attributes. If you're familiar with layout_weight in a linear layout, this works the same way. So the view with the highest weight value gets the most amount of space; views that have the same weight get the same amount of space.
Packed: The views are packed together (after margins are accounted for). You can then adjust the whole chain's bias (left/right or up/down) by changing the chain's head view bias.
I'm having 3 view in a row: title, version and imageview (working as button):
title should be wrap_content but respecting the following rules
version should be wrap_content, to right of the title and to left of imageview
imageview has fixed size and is at right top corner of the parent
The problem is if title is too large, the version is moved to right and rule "version is to the left of imageview" is not respected:
So i need to limit title width and make version visible and not moved to the right.
Here is XML:
<?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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:background="#b3b2b2">
<!-- -->
<TextView
android:id="#+id/LibraryWithVersionItem.title"
android:layout_width="0dp"
android:textStyle="bold"
android:textSize="#dimen/fontSize18"
android:textColor="#color/mySecondaryDarkColor"
android:layout_height="wrap_content"
android:ellipsize="middle"
tools:text="ExampleLibrary 01234567890123456789012345"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
/>
<Spinner
android:id="#+id/LibraryWithVersionItem.versions"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:textSize="#dimen/fontSize16"
android:textColor="#color/mySecondaryDarkColor"
tools:listitem="#layout/library_version"
android:layout_marginTop="#dimen/margin8"
android:layout_marginLeft="#dimen/margin8"
android:layout_marginRight="#dimen/margin8"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="#+id/LibraryWithVersionItem.title"
app:layout_constraintRight_toLeftOf="#+id/LibraryWithVersionItem.info"
app:layout_constraintHorizontal_bias="0.0"/>
<TextView
android:id="#+id/LibraryWithVersionItem.sentence"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#id/LibraryWithVersionItem.title"
tools:text="Some library description in one sentence\nbut two lines"
android:layout_marginTop="#dimen/margin8"
android:layout_marginLeft="#dimen/margin8"
app:layout_constraintRight_toLeftOf="#+id/LibraryWithVersionItem.install"
android:layout_marginRight="8dp"
app:layout_constraintHorizontal_bias="0.0"/>
<TextView
android:id="#+id/LibraryWithVersionItem.isInstalled"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/LibraryManager.installed"
android:textColor="#1a7c1a"
android:layout_marginTop="#dimen/margin8"
android:layout_marginBottom="#dimen/margin8"
android:layout_marginLeft="#dimen/margin8"
android:layout_marginRight="#dimen/margin8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#id/LibraryWithVersionItem.sentence"
app:layout_constraintRight_toLeftOf="#+id/LibraryWithVersionItem.install"
app:layout_constraintHorizontal_bias="0.0"/>
<!-- information button -->
<ImageView
android:id="#+id/LibraryWithVersionItem.info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="#dimen/margin8"
android:paddingLeft="#dimen/margin8"
android:paddingRight="#dimen/margin8"
android:paddingBottom="#dimen/margin8"
android:scaleType="center"
android:src="#drawable/ic_info_outline_white_24dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<!-- install button -->
<ImageView
android:id="#+id/LibraryWithVersionItem.install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/margin8"
android:paddingRight="#dimen/margin8"
android:paddingTop="#dimen/margin8"
android:paddingBottom="#dimen/margin8"
android:scaleType="center"
android:src="#drawable/ic_get_app_white_24dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/LibraryWithVersionItem.info"/>
</android.support.constraint.ConstraintLayout>
PS 1. layout_width="0dp" + app:layout_constraintWidth_default="wrap" seems to be exactly what i need ("wrap_content but not breaking the constraints") but it does not work (still larger than required):
<TextView
android:id="#+id/LibraryWithVersionItem.title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:ellipsize="middle"
android:textColor="#color/mySecondaryDarkColor"
android:textSize="#dimen/fontSize18"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
tools:text="ExampleLibrary 01234567890123456789012345"
PS 2. Setting min constraint width for the version (app:layout_constraintWidth_min="60dp") does not help too - it's invisible as it's moved too right.
Title and version should be in the chain and app:layout_constraintWidth_default="wrap" used:
<?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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:background="#b3b2b2">
<!-- information button -->
<ImageView
android:id="#+id/LibraryWithVersionItem.info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="#dimen/margin8"
android:paddingLeft="#dimen/margin8"
android:paddingRight="#dimen/margin8"
android:paddingBottom="#dimen/margin8"
android:scaleType="center"
android:src="#drawable/ic_info_outline_white_24dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<!-- -->
<TextView
android:id="#+id/LibraryWithVersionItem.title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ellipsize="middle"
android:textColor="#color/mySecondaryDarkColor"
android:textSize="#dimen/fontSize18"
android:textStyle="bold"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
tools:text="ExampleLibrary 01234567890123456789012345"
app:layout_constraintRight_toLeftOf="#+id/LibraryWithVersionItem.versions"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
android:paddingBottom="1dp"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0.0"/>
<Spinner
android:id="#+id/LibraryWithVersionItem.versions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/fontSize16"
android:textColor="#color/mySecondaryDarkColor"
tools:listitem="#layout/library_version"
app:layout_constraintRight_toLeftOf="#id/LibraryWithVersionItem.info"
app:layout_constraintLeft_toRightOf="#+id/LibraryWithVersionItem.title"
android:layout_marginRight="0dp"
app:layout_constraintBottom_toBottomOf="#+id/LibraryWithVersionItem.title"
android:layout_marginBottom="0dp"/>
<TextView
android:id="#+id/LibraryWithVersionItem.sentence"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/LibraryWithVersionItem.title"
tools:text="Some library description in one sentence\nbut two lines"
android:layout_marginTop="5dp"
android:layout_marginLeft="#dimen/margin8"
app:layout_constraintRight_toLeftOf="#+id/LibraryWithVersionItem.install"
android:layout_marginRight="8dp"
app:layout_constraintHorizontal_bias="0.0"
android:layout_marginStart="#dimen/margin8"
android:layout_marginEnd="8dp"/>
<TextView
android:id="#+id/LibraryWithVersionItem.isInstalled"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="#string/LibraryManager.installed"
android:textColor="#1a7c1a"
android:layout_marginTop="#dimen/margin8"
android:layout_marginLeft="#dimen/margin8"
android:layout_marginRight="#dimen/margin8"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/LibraryWithVersionItem.sentence"
app:layout_constraintRight_toLeftOf="#+id/LibraryWithVersionItem.install"
app:layout_constraintHorizontal_bias="0.0"
android:layout_marginStart="#dimen/margin8"
android:layout_marginEnd="#dimen/margin8"/>
<!-- install button -->
<ImageView
android:id="#+id/LibraryWithVersionItem.install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/margin8"
android:paddingRight="#dimen/margin8"
android:paddingTop="#dimen/margin8"
android:paddingBottom="#dimen/margin8"
android:scaleType="center"
android:src="#drawable/ic_get_app_white_24dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/LibraryWithVersionItem.info"/>
</android.support.constraint.ConstraintLayout>
I've tried to align version to title baseline but if the title is 2 or more lines it's aligned to the first line and it's not desired. So i had to align version to title bottom and hardcode title -3 bottom padding.
However, it looks as desired in Android Studio:
but on hardware device it looks different:
When analyzing in Layout Inspector i can see title width is calculated wrong:
Probably it's side effect of using it in RecyclerView but anyway...
You want to set android:layout_width="0dp".
Using wrap_content, the view will grow infinitely with the content. By using 0dp and setting its constraints, the view will have the maximum size as default, and the content will grow inside it reaches the limit.
Using android:layout_width="wrap_content"
Using android:layout_width="0dp"
From here-on, do your magic. You can set the TextView's android:maxLines="1" and android:ellipsize="end", adding three dots when reaching the maximum size.
Final layout xml
<?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:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/item_a_receber_historico"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="John Dreadpool Lennon Of House Stark Man This Name Is Huge!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/item_a_receber_valor"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/item_a_receber_valor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:text="R$420,00"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
i achieve this by setting layout_width to wrap_content and maxWidth to a value
In ConstraintLayout you can add one or mre guidelines horizontally or vertically which help to divide the screen in sections.
I ussually add the guidelines using the *_pct atribute which set the position as a percentage of the screen width/height.
I have a TextView and a Button organized horizontally, in sequence, in a ConstraintLayout:
I need the first element (TextView) to take only the necessary space when the text is short enough, but to expand as necessary when more text needs to be displayed while still leaving enough space for the second element (Button) to be completely rendered inside the view, with its end aligned to the end of the parent.
This is what the XML currently looks like:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">
<TextView
android:id="#+id/element1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Short enough text"/>
<Button
android:id="#+id/element2"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:drawableLeft="#drawable/element2ButtonDrawable"
android:drawablePadding="0dp"
android:drawableStart="#drawable/element2ButtonDrawable"
android:text="Action"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="#id/element1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.0"/>
</android.support.constraint.ConstraintLayout>
This is how the tree renders when switching from "Short enough text" to "A longer text that will cause most of the bottom to get pushed outside of the parent view bounds":
Is it possible to achieve what I'm trying to do by using the ConstraintLayout?
(at time of writing, latest version is 1.0.2)
Thanks!
You should use packed horizontal chain with your TextView having width that matches constraints and horizontal bias equals 0.0
Here's solution:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:text="Short enough text"
app:layout_constraintWidth_default="wrap"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0.0" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:drawablePadding="0dp"
android:drawableStart="#drawable/element2buttondrawable"
android:text="Action"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="#+id/textView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
Here's how this layout looks on the device with different text and orientations:
You can read more about using chains in following posts:
Building interfaces with ConstraintLayout
Build a Responsive UI with ConstraintLayout
Try something like this:
<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:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">
<TextView
android:id="#+id/element1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/element2"
app:layout_constraintTop_toTopOf="parent"
tools:text="A longer text that will cause most of the bottom to get pushed outside of the parent view bounds" />
<Button
android:id="#+id/element2"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:text="Action"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>