Last view is getting cropped in constraint layout - android

I want to build a listview whose every item can have different height as per text content length.
Below is the layout of my listview item. When I tried to set lengthy content on title, the bottom textview is getting cropped, however I wanted parent constraint layout to be expanded as per the text.
Layout
<?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="match_parent"
android:layout_height="wrap_content"
android:background="#color/background"
android:minHeight="90dp"
android:padding="16dp">
<ImageView
android:id="#+id/iv_notification_thumbnail"
android:layout_width="36dp"
android:layout_height="36dp"
android:src="#drawable/ic_avatar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
<TextView
android:id="#+id/tv_notification_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp"
android:fontFamily="#font/roboto"
android:text="If the cont"
android:textColor="#color/white"
android:textSize="14sp"
app:layout_constraintEnd_toStartOf="#id/tv_notification_time"
app:layout_constraintStart_toEndOf="#id/iv_notification_thumbnail"
app:layout_constraintTop_toTopOf="#id/iv_notification_thumbnail" />
<TextView
android:id="#+id/tv_notification_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/roboto"
android:text="#string/value_place_holder"
android:textColor="#color/text_desc"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#id/tv_notification_title" />
<TextView
android:id="#+id/tv_notification_desc"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="4dp"
android:fontFamily="#font/roboto_medium"
android:text="#string/submit_to_oms"
android:textColor="#color/text_desc"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#id/tv_notification_title"
app:layout_constraintStart_toStartOf="#id/tv_notification_title"
app:layout_constraintTop_toBottomOf="#id/tv_notification_title"
tools:ignore="SmallSp" />
<ImageButton
android:id="#+id/ib_unread_dot"
android:layout_width="8dp"
android:layout_height="8dp"
android:background="#drawable/shape_circle_orange"
android:clickable="false"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>

0dp makes the view follow the defined constraints as priority, and when there is no left space in the Item, it still follows the constraints, making the bottom of the view at the bottom of the parent and the top on the bottom of the title. There is no space between these two constraints when the title is too big.
Instead of 0dp, change the layout_height to wrap_content and it should wrap it's content:
<TextView
android:id="#+id/tv_notification_desc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:fontFamily="#font/roboto_medium"
android:text="#string/submit_to_oms"
android:textColor="#color/text_desc"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="#id/tv_notification_title"
app:layout_constraintStart_toStartOf="#id/tv_notification_title"
app:layout_constraintTop_toBottomOf="#id/tv_notification_title"
tools:ignore="SmallSp" />

Related

how can I align textview in Constrainlayout

I am developing news app but I am not able to align textview so that
it is overlapping around imageview how can I show it properly
I am developing news app but I am not able to align textview so that
it is overlapping around imageview how can I show it properly
below my xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorWhite"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.Guideline
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.55"
android:id="#+id/guideline"/>
<ImageView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#id/guideline"
app:layout_constraintDimensionRatio="16:9"
android:layout_margin="16dp"
android:id="#+id/articleImage"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:id="#+id/articleAuthor"
android:layout_marginStart="25dp"
android:layout_marginTop="10dp"
android:text="Placeholder"
android:layout_marginLeft="25dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/articleAuthor"
app:layout_constraintStart_toStartOf="#id/articleAuthor"
android:layout_marginTop="5dp"
android:maxLines="2"
android:text="Secondary"
android:id="#+id/articleTitle"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/articleTitle"
app:layout_constraintStart_toStartOf="#id/articleAuthor"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="10dp"
android:layout_marginTop="5dp"
android:text="Tertiary"
android:id="#+id/articleTime"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="#id/articleTime"
app:layout_constraintBottom_toBottomOf="#id/articleTime"
app:layout_constraintStart_toEndOf="#id/articleTime"
android:layout_marginStart="15dp"
android:id="#+id/articleShare"
android:background="#color/colorWhite"
android:src="#drawable/ic_share"
android:layout_marginLeft="15dp" />
<ImageButton
android:id="#+id/articleFavorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="#id/articleShare"
app:layout_constraintBottom_toBottomOf="#id/articleShare"
app:layout_constraintStart_toEndOf="#id/articleShare"
android:layout_marginStart="15dp"
android:background="#color/colorWhite"
android:src="#drawable/ic_bookmark"
android:layout_marginLeft="15dp" />
</android.support.constraint.ConstraintLayout>
below current screenshot of app
below screenshot which I want to achieve
screenshot I want
Add this attribute to both your articleAuthor and articleTitle TextViews:
app:layout_constraintEnd_toStartOf="#id/guideline"
Additionally, set the layout_width attribute to 0dp (i.e. "match constraints") for both of these same views:
android:layout_width="0dp"
This will cause the TextViews to be exactly as wide as the space between the left edge of the parent and the right edge of the guideline. For text that is shorter than this width, you'll get one line of left-justified text. For text that is longer than this width, you'll get multiple lines of left-justified text that wrap before the ImageView.

Can't figure out layout dependencies in Android

I need to create a layout which should look like this:
The TextView content should be wrapped so the ImageView is always at the ent of the text.
TextView should not overlap with other views regardless of content.
ImageView can have visibility GONE during runtime, so TextView should use the space of ImageView.
My current layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#android:color/white">
<TextView
android:id="#+id/pref_list_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="16dp"
android:fontFamily="sans-serif"
android:text="Long long"
android:textSize="#dimen/preference_text_size" />
<ImageView
android:id="#+id/pref_list_item_help_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/pref_list_item_title"
android:layout_centerVertical="true"
android:layout_margin="8dp"
android:src="#drawable/ic_help_primary_color"
android:contentDescription="#string/help" />
<Switch
android:id="#+id/pref_list_item_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp" />
</RelativeLayout>
ConstraintLayout is an option, but I couldn't create constraints that satisfy my needs.
Using ConstraintLayout you can do it like this:
<?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/pref_list_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:fontFamily="sans-serif"
android:text="Long long asdasd asd asd aasdadasd"
android:textSize="#dimen/preference_text_size"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/pref_list_item_help_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="#+id/pref_list_item_help_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/pref_list_item_title"
android:layout_margin="8dp"
android:src="#drawable/ic_help_primary_color"
android:contentDescription="#string/help"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/pref_list_item_switch"
app:layout_constraintStart_toEndOf="#id/pref_list_item_title"
app:layout_constraintTop_toTopOf="parent"/>
<Switch
android:id="#+id/pref_list_item_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
The TextView and the ImageView are chained together with packed style and horizontal bias of 0 to keep them aligned to the left. The app:layout_constrainedWidth="true" has to be set for the TextView to prevent it from overlapping other Views in case the text gets too long. All this also works well when you want to toggle ImageView's visibility.

How to give background color to Group in Constraintlayout

I have grouped 3 textview in a constraint layout. I have background to the group, but its not working.
<android.support.constraint.Group
android:id="#+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/text_color_3"
app:constraint_referenced_ids="price_tv,currency_unit_tv,frequency_tv" />
Is there anyway other round to do it.
According to the documentation, Group is only used for controlling the visibility of a set of widgets.
You can set the background to a View and constrain the view to how you desire the background to appear.
In the code sample below, after setting the background to the View with ID background, I constrained the top, left and right sides of the view to the parent and the bottom of the view to the last TextView in the group, which in this case is the TextView with ID textView3. I also added a 16dp bottom padding to textView3 so the background doesn't look weird. You could also use a Guideline for this.
Also note that the view background needs to be added before the group of views that need the background. If it's placed after the group of views, the background would be drawn over the group (and that's not what you want).
<?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="match_parent"
android:background="#444444">
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FFFFFF"
app:layout_constraintBottom_toBottomOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="TextView 1"
app:layout_constraintEnd_toEndOf="parent"
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:layout_marginTop="16dp"
android:text="TextView 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView1"/>
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:paddingBottom="16dp"
android:text="TextView 3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView2"/>
</android.support.constraint.ConstraintLayout>
I hope this helps.
Though the group is only for visibility purpose but you can easily put a background to group.
Group view doesn't have any width and height, so wrap content wouldn't be visible on actual screen.
Provide constraints to Group view and set background attributes.
Eg:
<android.support.constraint.Group
android:id="#+id/group"
android:layout_width="0dp" //match constraint
android:layout_height="0dp" //match constraint
android:background="#color/text_color_3"
app:constraint_referenced_ids="price_tv,currency_unit_tv,frequency_tv"
app:layout_constraintBottom_toBottomOf="#+id/frequency_tv"
app:layout_constraintEnd_toEndOf="#+id/price_tv"
app:layout_constraintStart_toStartOf="#+id/price_tv"
app:layout_constraintTop_toTopOf="#+id/price_tv" />
//below are your TextViews aligned vertically
<TextView android:id="#+id/price_tv"/>
<TextView android:id="#+id/currency_unit_tv" .../>
<TextView android:id="#+id/frequency_tv" .../>
Hope it helps :)
Group is useful for the visibility purpose in ConstraintLayout. ConstraintLayout is introduced to remove the hierarchy of the multiple ViewGroups(Layouts).
We can simply use for the background purpose. If you simply have 3 TextView and want to apply the background color to the TextView don't add it to any ViewGroup(Layout), just check this:
<?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:background="#AAA">
<View
android:id="#+id/background"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FFF"
app:layout_constraintBottom_toBottomOf="#+id/textView3"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toTopOf="#+id/textView1" />
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toBottomOf="#+id/textView1"
tools:text="TextView" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
app:layout_constraintEnd_toEndOf="#+id/textView1"
app:layout_constraintStart_toStartOf="#+id/textView1"
app:layout_constraintTop_toBottomOf="#+id/textView2"
tools:text="TextView" />
</android.support.constraint.ConstraintLayout>
Result:
You can find the source here
Group is only used for controlling the visibility of Referenced Ids in app:constraint_referenced_ids. According to the documentation. Solution is just put views in a Viewgroup. I had to put all the views in ConstraintLayout to constrol the visibility + benefits of chaining views in CL.
<android.support.constraint.ConstraintLayout
android:id="#+id/area_range_constraint"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
visibility = "View.VISIBLE"
>
<TextView
android:id="#+id/area_title_tv"
style="#style/filter_heading_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/STR_AREA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/area_range_from"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:hint="#string/STR_MIN_AREA"
android:inputType="number"
android:maxLength="10"
android:text='#{searchQueryModel.areaMin==null ? "": StringUtils.getDelimeterString(String.valueOf(safeUnbox(searchQueryModel.getAreaMin())))}'
android:textAlignment="center"
android:textDirection="anyRtl"
android:textSize="14sp"
app:layout_constraintEnd_toStartOf="#+id/textView254"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/area_title_tv" />
<EditText
android:id="#+id/area_range_to"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:hint="#string/STR_MAX_AREA"
android:inputType="number"
android:maxLength="10"
android:text='#{searchQueryModel.areaMax==null ? "": StringUtils.getDelimeterString(String.valueOf(safeUnbox(searchQueryModel.getAreaMax())))}'
android:textAlignment="center"
android:textDirection="anyRtl"
android:textSize="14sp"
app:layout_constraintBaseline_toBaselineOf="#+id/textView254"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/textView254" />
<TextView
android:id="#+id/textView254"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/STR_TO"
android:textColor="#color/text_color_3"
android:textSize="#dimen/text_size_normal"
app:layout_constraintBaseline_toBaselineOf="#+id/area_range_from"
app:layout_constraintEnd_toStartOf="#+id/area_range_to"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/area_range_from" />
<TextView
android:id="#+id/area_range_value_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text='#{`(` + areaUnit + `)`}'
android:textColor="#color/colorPrimary"
android:textSize="#dimen/text_size_normal"
app:layout_constraintBottom_toBottomOf="#+id/area_title_tv"
app:layout_constraintStart_toEndOf="#+id/area_title_tv"
app:layout_constraintTop_toTopOf="#+id/area_title_tv" />
</android.support.constraint.ConstraintLayout>
Use the new Layer that was introduced in ConstraintLayout 2
As per the official documentation, group is only used to control the visibility and you cannot change the background of the views of a particular group.
Documentation: This class controls the visibility of a set of referenced widgets. Widgets are referenced by being added to a comma separated list of ids.
To change it dynamically, use for all the three TextViews.
textView.setBackgroundColor(Color.RED);
or
textView..setBackgroundColor(Color.parseColor("#ffffff"));

ConstraintLayout, when constraint dependent view is gone, the layout view behave weirdly

I'm using ConstraintLayout where I will show as below
I would like to hide First (using gone), and which the view I expect to be as below (where ElasticBody will stretch over to use up the original First view space as well.
However, when I actual set First to gone, my view turn out to be as below (all image as from Android Studio Design view). My Elastic Body is missing as well, and the height expanded weirdly.
My layout code as below
<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"
android:padding="16dp">
<TextView
android:id="#+id/txt_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#0ff"
android:text="First"
android:visibility="gone"
android:textSize="26sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/txt_body"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt_body"
android:layout_width="0dp"
android:background="#f0f"
android:layout_height="wrap_content"
android:text="Elastic Body"
android:textSize="26sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/txt_tail"
app:layout_constraintStart_toEndOf="#+id/txt_first"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt_tail"
android:background="#ff0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tail"
android:textSize="26sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/txt_body"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
(Note, if you remove the gone, you'll get the first image view).
Why is this so? How could I fix it where when my First is gone, I could the Elastic Body stretch out correctly?
p/s: I know how to do it in LinearLayout and RelativeLayout... but wonder if this is a limitation on ConstraintLayout?
Try following.
Set the first view's left and top constraints to "parent". After that:
set the txt_body textview width to "0dp"
set the left constraint to the first view's right side
set the right constraint to the tail view's left side.
So, whenever you set the first view's visibility to "gone", the body view will be stretched like how you want it.
<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"
android:padding="16dp">
<TextView
android:id="#+id/txt_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#0ff"
android:text="First"
android:textSize="26sp"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="#+id/txt_body"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
<TextView
android:id="#+id/txt_body"
android:layout_width="0dp"
android:background="#f0f"
android:layout_height="wrap_content"
android:text="Elastic Body"
android:textSize="26sp"
app:layout_constraintRight_toLeftOf="#+id/txt_tail"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="#+id/txt_first"
/>
<TextView
android:id="#+id/txt_tail"
android:background="#ff0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tail"
android:textSize="26sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
Update
If you want to do using barrier then also you can do it.
<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="wrap_content"
android:padding="16dp">
<TextView
android:id="#+id/txt_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#0ff"
android:text="First"
android:textSize="26sp"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="#+id/barrier"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt_body"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#f0f"
android:text="Elastic Body"
android:textSize="26sp"
app:layout_constraintStart_toEndOf="#+id/barrier"
app:layout_constraintEnd_toStartOf="#+id/txt_tail"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt_tail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff0"
android:text="Tail"
android:textSize="26sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="txt_body,txt_first" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
app:constraint_referenced_ids="txt_body,txt_tail" />
</androidx.constraintlayout.widget.ConstraintLayout>
Say, you want to have a picture like this:
Here you have indents between the title and "Nice work", between "Nice work" and time, also horizontal indent to "Opinions". They are centered vertically.
"Opinions" is attached to the star, so that can be multilined and stay centered. I show results for 2 variants: in the first row opinions are multilined, while in the next row it is a single line. In columns you can see 4 variants of showing/hiding 2 labels.
A more simple and preferrable way is to wrap both labels into LinearLayout and insert it into parent ConstraintLayout. Then you can set vertical gravity, show or hide labels, hide the LinearLayout itself.
If you don't want to have nested layouts, use Barriers and Groups. It is a difficult task that can waste many hours. A key is having additional Views for aligning. Here I have 2 hiding labels ("Nice work" and "Opinions"), and I have to add 2 views (spaces).
The height of the right space is equal to the height of the star (14dp).
To simplify hiding several views, I joined them into groups.
You can see horizontal dotted lines - they are Barriers. I align them on tops and bottoms of the most big views (barrier_2 is similar):
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="left_text,opinion" />
Vertical aligning is based on these 2 additional Spaces (see marginTop="10dp"):
<Space
android:id="#+id/left_text_space"
android:layout_width="25dp"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:layout_constraintStart_toEndOf="#id/left_text"
app:layout_constraintTop_toBottomOf="#id/title" />
It is difficult to cover all situations, so see the following layout:
<?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"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:paddingRight="15dp"
android:paddingBottom="5dp">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lineSpacingExtra="4sp"
android:lines="1"
android:paddingBottom="5dp"
android:text="«Title text»"
android:textColor="#333333"
android:textSize="15sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="left_text,opinion" />
<TextView
android:id="#+id/left_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#112233"
android:paddingLeft="5dp"
android:paddingTop="4dp"
android:paddingRight="5dp"
android:paddingBottom="4dp"
android:text="Nice work"
android:textColor="#ffffff"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="#id/barrier_2"
app:layout_constraintStart_toStartOf="#id/title"
app:layout_constraintTop_toTopOf="#id/left_text_space" />
<Space
android:id="#+id/left_text_space"
android:layout_width="25dp"
android:layout_height="10dp"
android:layout_marginTop="10dp"
app:layout_constraintStart_toEndOf="#id/left_text"
app:layout_constraintTop_toBottomOf="#id/title" />
<androidx.constraintlayout.widget.Group
android:id="#+id/left_text_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="left_text,left_text_space" />
<Space
android:id="#+id/opinion_space"
android:layout_width="1dp"
android:layout_height="14dp"
android:layout_marginTop="10dp"
app:layout_constraintStart_toStartOf="#id/left_text_space"
app:layout_constraintTop_toBottomOf="#id/title" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="left_text,opinion" />
<ImageView
android:id="#+id/opinion_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="#null"
app:layout_constraintBottom_toBottomOf="#id/barrier_2"
app:layout_constraintStart_toEndOf="#id/left_text_space"
app:layout_constraintTop_toTopOf="#id/opinion_space"
app:srcCompat="#drawable/ic_filled_rate_star" />
<TextView
android:id="#+id/opinion"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:lineSpacingExtra="1sp"
android:text="1. Opinion 1.\n2. Opinion 2.\n3. Opinion 3.\n4. Opinion 4."
android:textColor="#1122aa"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="#id/opinion_icon"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/opinion_icon"
app:layout_constraintTop_toTopOf="#id/opinion_icon" />
<androidx.constraintlayout.widget.Group
android:id="#+id/opinion_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="opinion_icon,opinion,opinion_space" />
<ImageView
android:id="#+id/time_icon"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="8dp"
android:contentDescription="#null"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/barrier_2"
app:srcCompat="#drawable/ic_time" />
<TextView
android:id="#+id/time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="7dp"
android:layout_marginLeft="7dp"
android:ellipsize="end"
android:lineSpacingExtra="1sp"
android:lines="2"
android:paddingBottom="7dp"
android:text="17:00"
android:textColor="#9e9e9e"
android:textSize="11sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="#id/time_icon"
app:layout_constraintTop_toTopOf="#id/time_icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
Then in your activity you can show/hide labels. Hide Groups, not views inside, because strangely inside a Group views are always visible.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
left_text_group.visibility = View.GONE
opinion_group.visibility = View.VISIBLE
}
An answer has already been given linking to Barriers. I will provide an example of how I've actually implemented it:
<TextView
android:id="#+id/textView1"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:text="Some text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView2"
app:layout_constraintTop_toBottomOf="#id/textView1"
app:layout_constraintLeft_toLeftOf="parent"
android:text="Some other text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<androidx.constraintlayout.widget.Barrier
android:id="#+id/barrier1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:barrierDirection="bottom"
app:constraint_referenced_ids="textView1,textView2" />
This example shows 2 TextViews either of which can be gone. The Views are on stacked from top to bottom, so barrierDirection is set to bottom. Should you need another direction, just change that line accordingly.
Setting any of the 2 TextViews to gone, will result in the Barrier shifting to the bottom of the other, and if we set both to gone, it'll just shift up to the element that textView1's top constraint was referencing, in this case, the parent.
Note: If your textView1's top constraint is something else, i.e. it's below another element, the barrier will end up there if both views are set to gone.

How to make view "wrap_content but not larger than" with ConstraintLayout?

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.

Categories

Resources