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.
Related
I have two textViews aligned next to each other as such:
Here is the image, I am not allowed to embed it for now
My current layout works fine if I try to increase the text for the first text view, it remains within the constraint as it should. Here is it how it looks and this is fine.
But when I try to do the exact opposite of this, i.e increase the width for the second textView, I expect the first one to remain in place, but the same does not happens and it overflows.It goes out of bounds like this.
So I cannot understand what is it that I am doing wrong? I want both the textViews to take whatever space is available to them within the constraints. Could someone guide me where I am going wrong?
Both the textViews are chained to each other.
Here is my current XML Code.
<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:background="#color/colorPrimaryBackground">
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guidelineStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.04" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guidelineEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.96" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guidelineTop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.04" />
<TextView
android:id="#+id/tvStart"
style="#style/StyleRegular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="Text A"
android:textSize="20sp"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toStartOf="#id/tvEnd"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="#id/guidelineStart"
app:layout_constraintTop_toTopOf="#id/guidelineTop" />
<TextView
android:id="#+id/tvEnd"
style="#style/StyleRegular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:maxLines="1"
android:text="Text B Text B Text B Text B Text B T"
app:layout_constrainedWidth="true"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="#id/guidelineEnd"
app:layout_constraintStart_toEndOf="#id/tvStart"
app:layout_constraintTop_toTopOf="#id/guidelineTop" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can try something like this
<?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">
<TextView
android:id="#+id/tvStart"
style="#style/TextAppearance.AppCompat.Body1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintEnd_toStartOf="#id/tvEnd"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="Text A Text A Text" />
<TextView
android:id="#+id/tvEnd"
style="#style/TextAppearance.AppCompat.Body1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintStart_toEndOf="#id/tvStart"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Text B Text B Text B Text B Text B T" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is what the layout will look like. You can change up the layout_width from 0dp to wrap_content and see how that works between the 2 views to get it where you want.
Experimenting with android:maxLength="" or android:maxWidth="" on first text view dynamically can give you desired result. At runtime, find the best-suited maxLength and maxWidth values based on the strings for two text views. Also, You can also check FlexLayout or FlowLayout if they solve your UI requirement.
This one works as you expected for shorter strings with the use of FlexboxLayout
<com.google.android.flexbox.FlexboxLayout 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"
app:alignItems="flex_start">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
tools:text="Text A" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
tools:text="Text B Text B Text B Text B Text B T" />
</com.google.android.flexbox.FlexboxLayout>
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" />
I want my imageview to stay directly to the right of my textview. I can accomplish this by setting toLeftOf in the attributes for TextView. But for really long text strings, I have ellipses set, and after it reaches the width of the layout, it'll push the ImageView off as well.
I can have the ImageView displayed by setting gravity to 1 for TextView, but then the ImageView is anchored to the right. What should I do?
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="left">
<TextView
android:id="#+id/title_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:layout_weight="1"
android:text="MY TEXT TO THE LEFT"
android:layout_toLeftOf="#id/img_button" />
<ImageButton
android:id="#+id/img_button"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginLeft="4dp"
android:layout_marginTop="6dp"
android:background="#drawable/some_img"
app:srcCompat="#drawable/ic_edit" />
</LinearLayout>
So w/ setting the weight=1, that hugs the image to the far right, i need it to be dynamic and be to the right of the textview at all times and then when the width of the textview becomes longer than the parent, for the image to not get pushed off screen.
You can use constraintLayout and set your textView width to 0dp (also called match constraint).
The result will cause your textView to drop a line if the is a lot of text.
Here is an example:
<?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">
<ImageView
android:id="#+id/textView8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="#android:color/holo_green_light"
android:padding="10dp"
android:text="something"
android:textColor="#color/colorAccent"
app:layout_constraintBottom_toBottomOf="#+id/textView10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="#+id/guideline3"
app:layout_constraintTop_toTopOf="#+id/textView10" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="#+id/textView10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="this is really long text and it wont push the green image because of android:layout_width attribute"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/guideline3"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
And it will look like this :
I set paddingRight to the size of the image button, inside the textview and I used alignRight on my image button.
And changed the container to RelativeLayout. It works as intended!!
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="left">
<TextView
android:id="#+id/title_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:paddingRight="22dp"
android:text="MY TEXT TO THE LEFT"
android:layout_toLeftOf="#id/img_button" />
<ImageButton
android:id="#+id/img_button"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginLeft="4dp"
android:layout_marginTop="6dp"
android:layout_alignRight="#+id/title_view"
android:background="#drawable/some_img"
app:srcCompat="#drawable/ic_edit" />
</RelativeLayout>
Use LinearLayout with the orientation="horizontal" attribute . Than set the weight_sum = 100 for the LinearLayout , and than for your TextView and ImageView , just place the weight attribute according to what you want . Hope it helps .
If I have a constraint layout like this
<android.support.constraint.ConstraintLayout >
<TextView
android:layout_width="200dp"
android:layout_height="50dp"
android:text = "Some text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="#+id/preview"
app:layout_constraintTop_toTopOf="#+id/parent">
/>
<Button
android:layout_width="57dp"
android:layout_height="281dp"
app:layout_constraintBottom_toBottomOf="#+id/textview"
app:layout_constraintEnd_toEndOf="#+id/textview"
app:layout_constraintStart_toStartOf="#+id/textview">
/>
</android.support.constraint.ConstraintLayout>
Where textview is another widget. then this will make the button and the textview bottom boundaries aligned.
Is there anyway where I can push button 10dp lower? So I want the button bottom to be anchored to the bottom of the textview however I wanted to be pushed a bit lower by 10dp. I tried to set the android:layout_marginBottom="-10dp" but that didn't work!
Any idea?
use android:layout_marginTop="10dp" in your button layout
Put them in a FrameLayout, with layout_height="wrap_content". Then, set layout_gravity="bottom" on both the child Views. Give your TextView layout_marginBottom="10dp".
The result should be something like (this is a skeleton with only the relevant attrs):
<ConstraintLayout>
<FrameLayout
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_marginBottom="10dp"
android:layout_gravity="bottom"
/>
<Button
android:layout_gravity="bottom"
/>
</FrameLayout>
</ConstraintLayout>
in java or kotlin seet textview.bringToFront();
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="#+id/button"
android:layout_width="157dp"
android:layout_height="140dp"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/textview"
android:layout_width="150dp"
android:layout_height="50dp"
android:text = "Some text"
android:gravity="center"
android:textSize="15sp"
android:textColor="#05afaf"
app:layout_constraintBottom_toBottomOf="#id/button"
app:layout_constraintStart_toStartOf="#id/button"
app:layout_constraintEnd_toEndOf="#id/button"
android:layout_marginBottom="20dp"
/>
</android.support.constraint.ConstraintLayout>
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>