I have a layout like in this picture below, containing a title, some text view, and a list view. Title is aligned with the top of the screen, and list is aligned with bottom of the screen and should take as much space as possible.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="Title"
android:textSize="30sp" />
<TextView
android:id="#+id/some_text"
android:layout_below="#id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:text="Some random text which can change"
android:textSize="14sp" />
<ScrollView
android:id="#+id/list_wrapper"
android:layout_below="#id/some_text"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
After activity is created, text in text view below title can dynamically change, and when it happens it could shrink and list view could change its size. I want to prevent this, so that list view keeps its position and size, and only text view above shrinks and moves down to the list like in this picture below.
How can I accomplish this? I am okay with any layout type, I just used RelativeLayout code above as an example.
It would be easy if list view could have fixed size, but I want list view to take as much space as possible, and after activity is created I want it to stay in place and not change its size.
You can use ConstraintLayout with guideline to tell your list view and your text view exactly where to be on your screen (It will be responsive to all screen sizes).
It Will look something 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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline31" />
<TextView
android:id="#+id/tes"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Text"
app:layout_constraintBottom_toTopOf="#+id/guideline31"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:id="#+id/guideline31"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.2"/>
</android.support.constraint.ConstraintLayout>
And now your layout will look the same with long text or short text for the title:
just add this line in your textview xml android:maxLines="1"
<TextView
android:id="#+id/title"
android:maxLines="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:text="Title"
android:textSize="30sp" />
Related
I am new to recycler views and beginning with Room databases. I am working on this app that lets the user enter records into Room database. The user enters the info and it gets stored. The top part of the screen is the data entry and the bottom is the recycler view where the records are displayed. Everything is fine until there are enough records to fill the available space. Then the new records just disappear below the screen. There is animation when the user tries to scroll, but the items don't move. I tried to make the items bigger by adding a padding, and strangely enough there is scrolling now, but just to the same item that displayed before.
This is the main.xml
<?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="match_parent"
android:padding="10dp"
tools:context=".MainActivity">
<TextView
android:id="#+id/tvNameLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
app:layout_constraintBottom_toBottomOf="#id/etName"
app:layout_constraintTop_toTopOf="#+id/etName"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/etName"
/>
<EditText
android:id="#+id/etName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Enter Name"
android:layout_marginStart="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="#+id/tvNameLabel"/>
<TextView
android:id="#+id/tvEmailLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email Id"
app:layout_constraintBottom_toBottomOf="#+id/etMailId"
app:layout_constraintEnd_toStartOf="#+id/etMailId"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/etName"/>
<EditText
android:id="#+id/etMailId"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="Enter Email Id"
android:layout_marginStart="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/tvEmailLabel"
app:layout_constraintTop_toBottomOf="#+id/etName"/>
<Button
android:id="#+id/btnAdd"
android:layout_width="match_parent"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_height="80dp"
android:text="ADD RECORD"
app:layout_constraintTop_toBottomOf="#+id/etMailId"/>
<TextView
android:id="#+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:gravity="center"
android:text="All The Inserted Records"
android:textColor="#color/black"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintTop_toBottomOf="#+id/btnAdd"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvItemsList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/tvName"
android:visibility="visible"
tools:visibility="visible"
/>
<TextView
android:id="#+id/tvNoRecordsAvailable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btnAdd"
android:gravity="center"
android:textSize="18sp"
android:textColor="#997b66"
android:text="There Are No records"
tools:visibility="visible"/>
</androidx.constraintlayout.widget.ConstraintLayout>
and this is the items xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/llMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:padding="20dp">
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/black"
android:textSize="16sp"
android:text="Name"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:textSize="18sp"
android:textStyle="bold"
android:text=":"/>
<TextView
android:id="#+id/tvEmail"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textColor="#color/black"
android:textSize="16sp"
android:text="Email"/>
<ImageView
android:id="#+id/ivEdit"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="image"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:scaleType="center"
android:src="#drawable/ic_action_edit"/>
<ImageView
android:id="#+id/ivDelete"
android:layout_width="50dp"
android:layout_height="50dp"
android:contentDescription="image"
android:foreground="?attr/selectableItemBackgroundBorderless"
android:scaleType="center"
android:src="#drawable/ic_action_delete"/>
</LinearLayout>
I don't know if any of the other files could be the culprits; but I can add them.
Any help would be greatly appreciated.
Add bottom constraint to recycler, then 0dp to height
I think you need to two things.
Try making the Recycler View in the main.xml file as big vertically as possible. For example android:layout_height="0dp"
I think you should add constraints to the Recycler View. Something like app:layout_constraintStart_toStartOf="parent" and app:layout_constraintEnd_toEndOf="parent"
Your RecyclerView is set with a height of wrap_content - that makes the size of the widget enough to display all its contents. It won't need to scroll, because it's big enough to display everything!
The problem there is you can't see the whole widget, because it's so tall the bottom is off the screen at this point. For scrollable containers, you usually want to constrain their height (or width if it's a horizontal scroll) to give you a "window" into the contents. If the contents are too big to fit in that window, the container will scroll behind that window.
In your case, you probably want to constrain the bottom of your RecyclerView to the bottom of the screen, or maybe the top of that TextView that sits below it:
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/tvName"
app:layout_constraintBottom_toBottomOf="parent"
That defines the area that the list takes up, as the available space between tvName and the bottom of the layout. 0dp means it has no absolute height, and it'll just size to fit those vertical constraints. You can be a bit more clever with it, but that's the basic idea - define an area for your list to use, and if it's not big enough for the contents, the list will scroll
I have a problem with correct display of ImageView. I want to display ImageView inside ConstraintLayout. On preview it looks exactly as i need, but when i'm starting it on device it looks completly dirrerent. This layout is places inside recycle view. What is wrong with this code?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/promotionRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="10dp"
android:background="#fff"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp">
<android.support.constraint.ConstraintLayout
android:id="#+id/promotionImageLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintHeight_default="spread"
android:background="#color/colorPrimary">
<ImageView
android:id="#+id/promotionImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="#mipmap/ic_start_promotion"
android:background="#mipmap/ic_start_promotion"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHeight_min="150dp" />
<ImageView
android:id="#+id/fadeGradientImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#drawable/fade_image_background" />
<TextView
android:text="Sample title"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="6dp"
android:textColor="#ffffff"
android:id="#+id/promotionNameTextView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>
<TextView
android:id="#+id/promotionDescriptionTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="13sp"
android:layout_marginTop="12dp"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:text="Sampe description" />
</LinearLayout>
EDIT: Deep explanation:
I want to create row for RecycleView. Each row have to contains image, title and description. Title have to be in the left bottom corner of the image. Description have to be below the image. After that i have to put gradient (black in the bottom) into the image. Screen with "Preview" is exactly what i need.
EDIT2: Everything with this layout is ok. It is working as expected, i forget that i made some changes in kotlin code... Sory for problem.
First things first, every view should apply the attribute rules of its parent ViewGroup. ConstraintLayout doesn't support match_parent. It supports the 0dp value which means "match constraint". This way the view will expand to fill the constraint bounded space.
Next, ConstraintLayout was created to achieve a flat view hierarchy for better layout performance. So, never nest it inside a LinearLayout as it has the chains feature to get the same behavior in a more flexible way. Plus, you can achieve the structure with a ConstraintLayout at the top level .
Another thing, If you are going to define the same margin in all directions, you can just use layout_margin.
Finally, you have overdraw problems. ConstraintLayout is flexible enough to allow us to position views as backgrounds and help us avoid overlapped backgrounds.
Here's a solution:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/promotionRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="#+id/promotion_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/promotion_image"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="#mipmap/ic_start_promotion"
app:layout_constraintHeight_min="150dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/shadow"
android:layout_width="0dp"
android:layout_height="80dp"
android:adjustViewBounds="true"
android:background="#drawable/fade_image_background"
app:layout_constraintBottom_toBottomOf="#+id/promotion_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="#+id/promotion_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="Sample title"
android:textColor="#android:color/white"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="#+id/promotion_image"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<TextView
android:id="#+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:padding="12dp"
android:text="Sampe description"
android:textSize="13sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/promotion_image" />
</android.support.constraint.ConstraintLayout>
Try it. Hope this helps!
First of all, trying to write more presicely what do you want? Display image view inside layout it's somthing common words. As for your code, beside you don't have any constraints. You have strange view height, for second ImageView:
android:layout_height="match_parent"
It may overlay all other children view, it's very strange parameter.
Consider the following layout:
<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/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text" />
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="#id/text_view"
app:layout_constraintTop_toTopOf="parent"
tools:background="#android:color/black" />
</android.support.constraint.ConstraintLayout>
The image view (or button, or any other widget, important is that it has a fixed size) is aligned right/end of a TextView with a size of wrap_content, thus, the text itself only takes the space it needs.
What I now want is, when the text expands (aka if it's longer), that the button gets aligned to the right of the parent, and the text view only gets the width that is left and gets ellipsized.
At the moment, the image view is pushed outside and the text gets ellipsized once it fills the whole parent.
I tried to fix this by adding a endToEnd="parent" constraint the the image and setting the horizontal bias to 0 (see code), but that doesn't work.
Any suggestions on what I could do instead?
In order to prevent the ImageView from getting pushed outside the parent you need to constrain the end of the TextView to the start of the ImageView to create a chain. Now to ensure that the TextView only takes the space it needs but also has its constraints enforced, you need to add app:layout_constrainedWidth="true" attribute to your TextView.
If you want the ImageView to stay immediately to the right of the TextView can use packed chain style with a horizontal bias of 0.
If you want the ImageView to be aligned to the right of the parent you can use the spread_inside chain style without bias.
The resulting XML with above changes might look 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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:textSize="18sp"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/image_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text" />
<ImageView
android:id="#+id/image_view"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/text_view"
app:layout_constraintTop_toTopOf="parent"
tools:background="#android:color/black" />
</android.support.constraint.ConstraintLayout>
EDIT: As requested in the comment, here's how it would work with a Barrier sparating the 3 TextViews and the ImageView. In this case you don't specify the constraints for the ends of the TextViews thus you no longer have them chained horizontally. Instead, you create a Barrier with the direction being the end of all TextViews that are referenced in the Barrier. This will ensure that the Barrier is always at the end of the widest TextView. The last thing to do is to constrain the start side of the ImageView to the Barrier.
Example 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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:textSize="18sp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toTopOf="#id/text_view2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text1" />
<TextView
android:id="#+id/text_view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:textSize="18sp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toTopOf="#id/text_view3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/text_view1"
tools:text="Text2" />
<TextView
android:id="#+id/text_view3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:textSize="18sp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/text_view2"
tools:text="Text3" />
<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="text_view1,text_view2,text_view3" />
<ImageView
android:id="#+id/image_view"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/barrier"
app:layout_constraintTop_toTopOf="parent"
tools:background="#android:color/black" />
</android.support.constraint.ConstraintLayout>
I have an EditText, which gets aligned with other TextView below it.
But as soon as I add ListView, and try to Left align with plain text at the top the width and location of the EditText and TextView fields below it changes.
Also, if I try to use another Linear Layout instead of a ListView I face the same issue. What wrong could I be doing here?
I have tried setting width and height of listView, to match_contraint, but that did not work too.
Below is the xml for it,
<?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"
tools:context="com.example.testapp.app">
<EditText
android:id="#+id/editText6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:ems="10"
android:inputType="textPersonName"
android:text="Name"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="#+id/listView4"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="#+id/editText6"
app:layout_constraintStart_toStartOf="#+id/editText6"
app:layout_constraintTop_toBottomOf="#+id/editText6" />
<TextView
android:id="#+id/textView3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="#+id/textView"
app:layout_constraintStart_toStartOf="#+id/editText6"
app:layout_constraintTop_toBottomOf="#+id/textView" />
<ListView
android:id="#+id/listView4"
android:layout_width="395dp"
android:layout_height="472dp"
app:layout_constraintHorizontal_weight="0"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="123dp" />
</android.support.constraint.ConstraintLayout>
I think you put constraints in the wrong direction. So you aligned all TextViews to the start of the EditText. But EditText in its turn is aligned to the start of the ListView.
app:layout_constraintStart_toStartOf="#+id/listView4"
And as ListView doesn't have aligning, it is positioned at (0, 0), I guess.
I want to center a view under another like this "sign out" button under the email:
I did this by using a ConstraintLayout as the parent and constraining the bottom view's left and right edges to the left and right edges of the top view. This properly centers the two views. (Note that I don't want to center the views in the parent.)
The problem I'm having is that if the top view is narrow, the bottom view can end up truncated on the right by the parent, as here (from the layout editor):
I don't know in advance how narrow the top view will be at run time. (It won't necessarily be an email address, and, even if it were, I know someone whose email address is only 8 characters!)
I would like to set up constraints so that the bottom view is centered under the top view, but if it ends up too far to the right, it shifts left just enough to avoid crossing a guideline. The right edge of the top view needs to remain fixed. How can I achieve this effect? (I'm not wedded to using a ConstraintLayout if there's another way that will work better.)
Here's the actual layout file I'm using:
<?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">
<TextView
android:id="#+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:text="user"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1"/>
<View
android:id="#+id/scrim"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/transparent"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_constraintLeft_creator="1"
tools:layout_constraintTop_creator="1"
tools:visibility="visible"/>
<Button
android:id="#+id/sign_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#android:drawable/dialog_holo_light_frame"
android:text="#string/sign_out"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/user_name"
tools:visibility="visible"/>
</android.support.constraint.ConstraintLayout>
This sounds to me like a case where ConstraintLayout isn't the best tool for the job. You might still wind up using ConstraintLayout as your top-level view, but to get what you want I believe you will have to nest your TextView and Button inside a LinearLayout.
The core of the problem is that you want whichever view is wider to touch the edge of the parent, and whichever view is smaller to be horizontally centered against the wider view. Given that ConstraintLayout doesn't let you do more than one constraint for a given view's edge, it's not capable of doing this.
A vertical LinearLayout with android:gravity="center_horizontal" should do exactly what you want, however. And then you can position that at the top-right of your screen (maybe by using ConstraintLayout, or maybe some other way).
Edit
After re-reading your question, I realize I misunderstood your requirements. You need the TextView to always be positioned in the top-right corner, and the Button to be centered beneath the text view unless that would cause it to be clipped by the edge of the parent.
I still think LinearLayout is the way to go here, but you'll need to be a little more sophisticated with its children. This should work:
<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">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
constrants=top-right>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
</ConstraintLayout>
Suppose there are 2 views.
Select first view
Press shift
Select the second view.
Right click
Select Align >> Horizontal Centers.
Done.
I didn't get you perfectly, but I'm posting the answer for what I understood.
<?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">
<TextView
android:id="#+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:text="user"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1" />
<Button
android:id="#+id/sign_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#android:drawable/dialog_holo_light_frame"
android:text="SIGNOUT"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="#id/user_name"
tools:visibility="visible"
app:layout_constraintLeft_toLeftOf="#+id/user_name"
app:layout_constraintRight_toRightOf="#+id/user_name" />
I think here it is try it
<?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">
<TextView
android:id="#+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginTop="10dp"
android:text="user#mail.com"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText"
tools:layout_constraintRight_creator="1"
tools:layout_constraintTop_creator="1"/>
<View
android:id="#+id/scrim"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/transparent"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"
app:layout_constraintVertical_bias="0.0"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/sign_out"
app:layout_constraintHorizontal_bias="0.0" />
<Button
android:id="#+id/sign_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="11dp"
android:background="#android:drawable/dialog_holo_light_frame"
android:text="sign_out"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/user_name"
tools:visibility="visible"
android:layout_marginRight="11dp" />
</android.support.constraint.ConstraintLayout>