Align TextView baseline and another TextView bottom - android

I have RelativeLayout and two TextView, one of which with background.
On image two baselines aligned, but I want to align baseline of one and background bottom of another.
Here is my xml code.
<RelativeLayout
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="#dimen/chat_room_item_height"
android:background="?attr/selectableItemBackground"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp"
>
<!-- other stuff -->
<TextView
android:id="#+id/text_view_unread_message_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/text_view_last_message_date"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:background="#drawable/chat_unread_message_count_background"
style="#style/ChatRoomUnreadMessageCountTextStyle"
tools:text="101"
/>
<TextView
android:id="#+id/text_view_last_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/text_view_title"
android:layout_toEndOf="#id/image_view_icon"
android:layout_toLeftOf="#id/text_view_unread_message_count"
android:layout_toRightOf="#id/image_view_icon"
android:layout_toStartOf="#id/text_view_unread_message_count"
android:ellipsize="end"
android:layout_alignBaseline="#+id/text_view_unread_message_count"
android:gravity="bottom"
android:maxLines="1"
tools:text="My life is a story book with many different chapters but I don’t let everyone read it."
style="#style/ChatRoomLastMessageTextStyle"
/>
</RelativeLayout>
I have tried wrap TextView with background to different ViewGrops, wrap both TextView to layout, no avail.

You can do a little trick, here we go:
Put the text_view_unread_message_count inside a some viewgroupo e.g. RelativeLayout and add a paddingBottom with using SP scaling (this is your space for manually align), something like this:
Obs.: You need to give a new ID to you TextView, this is a example ID's and size values can be changed.
<!-- sp scaling will change with font size -->
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingBottom="10sp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_toEndOf="#id/image_view_icon"
android:layout_toLeftOf="#id/text_view_unread_message_count"
android:layout_toRightOf="#id/image_view_icon"
android:layout_toStartOf="#id/text_view_unread_message_count">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/chat_unread_message_count_background"
style="#style/ChatRoomUnreadMessageCountTextStyle"
tools:text="101"
/>
</RelativeLayout>
Put you locations definitions on parent and text definitions on textview. This should work.

You can set the required bottom margin programmatically.
val bottomToBaselineHeight = textViewLastMessage.height - textViewLastMessage.baseline
textViewUnreadMessageCount.margin(bottom = bottomToBaselineHeight)

Related

Wrap right-aligned view when there is no space

I have 2 views in a layout - TextView and Button. TextView is aligned/anchored to the left side and the button is to the right side.
What I'm trying to achieve is the natural "wrap behavior" of the Button. When TextView will be wide enough so that there won't be space for the button (in the same line), it should move below the TextView, while still anchored to the right.
Here are 3 scenarios for the layout which I want to achieve:
I was trying to make this with FlexBoxLayout, but the button appears on the left side after wrapping.
<com.google.android.flexbox.FlexboxLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="space_between"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text text"
android:gravity="start"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:text="Button"
/>
</com.google.android.flexbox.FlexboxLayout>
So how can I do that? It doesn't need to be FlexBox, I can use any layout, even 3rd party.
Use justifyContent="flex_end" in the parent and set layout_flexGrow to the children like this works for me.
<com.google.android.flexbox.FlexboxLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="300dp"
android:layout_height="wrap_content"
app:flexDirection="row"
app:flexWrap="wrap"
app:justifyContent="flex_end">
<TextView
android:id="#+id/textview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="blah blah"
app:layout_flexGrow="1" />
<TextView
android:id="#+id/textview3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="( . )( . )"
app:layout_flexGrow="0" />
</com.google.android.flexbox.FlexboxLayout>
No need for a 3rd party layout.
ConstraintLayout should be more than enough - with a small tweak in code.
Your TextView will have straightforward constraints, set to parent layout (start, top, end).
<?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"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Text text text text text text" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="#+id/text" />
</android.support.constraint.ConstraintLayout>
In the code, just check the width of the TextView and compare it with the width of the parent (basically check it should overlap with the button).
If it does change(you will have to do this in code but this is the principle):
app:layout_constraintTop_toTopOf="#+id/text"
to
app:layout_constraintTop_toBottomOf="#+id/text"
If you need to do this dynamically ConstraintLayout has neat feature "Keyframe animations" that creates awesome looking animations when you are changing constraints.
Doesn't seem like there is a way to do it with Flexbox. I would just do it programmatically when you've inflated the resource (in onCreateView() or something like that). The parent of both of the views would be a RelativeLayout, with the Button aligned to the TextView top when the widths combined don't exceed the width of the RelativeLayout, and aligned to the bottom of the TextView when the widths are larger than that.

Centering textview with right aligned button

I have an arbitrary length textview+icon (icon+text) that needs centering on the screen. On the same row, there is a button aligned to the right side of the screen. (X)
| icon+text | X |
Using a LinearLayout I can center it with the view, but the button on the right shifts it left.
With a relative layout, I can achieve what I want but if the text is too long the button overlaps the text.
What's the right way to do this? I haven't used constraintLayout before, would that solve it?
I suggest you to use a constraint layout,
Example:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".YourActivity">
<TextView
android:id="#+id/my_text_view"
android:text="My Long Text That must not overlap the button"
android:layout_width="0dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#+id/my_btn"
app:layout_constraintTop_toTopOf="#+id/my_btn"
app:layout_constraintBottom_toBottomOf="#+id/my_btn"/>
<Button
android:id="#+id/my_btn"
android:layout_marginTop="16dp"
android:text="My Nice Button "
android:layout_marginEnd="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="#id/my_text_view"
app:layout_constraintEnd_toEndOf="parent"/>
</android.support.constraint.ConstraintLayout>
Example Output:
You can set it like this,
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:drawableLeft="#mipmap/ic_launcher"
android:text="Click" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="TextView" />
</LinearLayout>
just use a Relative Layout.
Center your Textview
and put toRightOf=txtViewsName on the button.
//UPDATED Forcing Widths in DP to ensure text is always centered and never overlaps button.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#mipmap/ic_launcher"
android:maxWidth="230dp"
android:layout_centerHorizontal="true"
android:ellipsize="end"
android:text="My text to show test abcdefghyijkldkf here" />
<Button
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="Button" />
</RelativeLayout>
You will need to adjust the button width and textview maxwidth to match your design, and confirm on preview all resolutions, but dp should cover you pretty well in this case.
NOTE*
This simply answers your issue, but does not do any funny behavior, i.e. if text grows too much ignore center command and start moving to the left, this does not do that. If that is your desire, please update your question.
//Centering Text in left view and using weight to ensure text area takes proper percentage of the space (based on your comments, not the layout you are looking for, but I'll leave it in case it helps someone else).
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="10">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="7"
android:drawableLeft="#mipmap/ic_launcher"
android:gravity="center"
android:text="My text to show here" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="Button" />
</LinearLayout>
for best practice i think ConstraintLayout is the best solution for designing and yes of course it helps you for what are you looking for.
for more info check this Build a Responsive UI with ConstraintLayout and this
ConstraintLayout.
Since your ImageButton on right has a fixed width (let's say 40dp for the purpose of this example) you can achieve the desired result by adding a margin of the same width at the end of your TextView to ensure that they're not overlapping. To keep the TextView centered on the screen you have to add the same margin at the start as well:
<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/textview"
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginEnd="40dp"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageButton
android:id="#+id/button"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constrainedWidth="true"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/textview"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
If you want to center the text within the TextView use android:gravity="center":
If the ImageButton's width was wrap_content then this approach wouldn't work, because there is no way to constraint the end of the TextView both to the end of the parent (so it's centered on the screen) and to the start of the ImageButton (so they don't overlap if the text gets long) at the same time.
In the end I ended up using RelativeLayout per Sam's suggestion with maxWidth and margin set on the TextView.

How to make view at the end of textview even if the textview is so long?

I have this layout, where I have text view and an icon next to it.
However, the text is dynamically changing, so sometime it will be too long which push the icon out of the screen.
I tried to add weight to the text but it makes the icon on the right side of the screen which I don't want, I just want it right after the text even if the text go to the next line.
There is my code:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Text"
android:layout_marginLeft="25dp"
android:text="llllll"
/>
<android.support.v7.widget.AppCompatImageButton
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:background="#android:color/transparent"
android:src="#drawable/ic_arrow_drop_down_black_24dp" />
</LinearLayout>
any idea :(?
You can use ConstraintLayout to handle this.
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/image"
app:layout_constraintWidth_default="wrap"/>
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toRightOf="#+id/text"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
Just simply add one property line in textview "android:maxWidth" like below :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Text"
android:layout_marginLeft="25dp"
android:text="llllll"
android:maxWidth="100dp" //it can be your specific size
/>
<android.support.v7.widget.AppCompatImageButton
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:background="#android:color/transparent"
android:src="#drawable/ic_arrow_drop_down_black_24dp" />
</LinearLayout>
You could use <img> tags in the HTML
to know how to do that see this qution (is-it-possible-to-display-inline-images-from-html-in-an-android-textview)
Put the text view inside a relative layout with match parent as width and height wrap content.
Set text view to the same dimensions ie march parent as width and height as wrap content.
Have the image button in the same relative layout and use alignParentEnd as true. You'll see it always add the end of your text view.
If you choose to do this, set some maxEms and ellipsize end so that the text does not overlap the button. You'll get the value by testing it yourself, depends on the text size usually.
Since you want it as a button I'm suggesting this. If you want it just be an icon with no use, you should look into drawableEnd property of the text view.

Elements superposed using Android RelativeLayout

I have the following Android layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:orientation="vertical" >
<TextView
android:id="#+id/slideTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:padding="#dimen/px20"
android:text="#string/login_message"
android:textSize="#dimen/px25"
android:textStyle="bold" />
<TextView
android:id="#+id/slideDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="#drawable/password"
android:drawablePadding="#dimen/px20"
android:drawableStart="#drawable/password"
android:padding="#dimen/px20"
android:text="#string/login_message_body"
android:textSize="#dimen/px20" />
<TextView
android:id="#+id/swipeMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="" />
</RelativeLayout>
But all the elements are positioned at the top of the screen one on top of the other, like if they didn't occupy any space.
That's not what what it seems to happen in the RelativeLayout documentation, where all elements are vertically positioned one below the other.
What's going on here?
So you need to use the id of the other components to align then properly.
For example the TextView with the id #+id/slideDescription should also have
android:layout_below="#+id/slideTitle" as one of the properties of the xml.
And the TextView with the id #+id/swipeMessage should also have
android:layout_below="#+id/slideDescription" as one of the properties of the xml.
In order to place one view below another in RelativeLayout you have to use layout_below property and set the ID of View you want to be above the specified one. But actually in order to place views vertically below each other it is more convenient to use LinearLayout with orientation set to vertical
layout_below is missed in the above xml code.I replaced the code with that please use that.
In Relative layout elemnets will be arranged relative to other elements in order to do this we should use id values of individual view elments
android:layout_below="#id/slideTitle" should be placed in description text view
android:layout_below="#id/slideDescription" should be placed in message text view
in order to get the output you desired please use the below code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="16dp" >
<TextView
android:id="#+id/slideTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:padding="#dimen/px20"
android:text="#string/login_message"
android:textSize="#dimen/px25"
android:textStyle="bold" />
<TextView
android:id="#+id/slideDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/slideTitle"
android:drawableLeft="#drawable/password"
android:drawablePadding="#dimen/px20"
android:drawableStart="#drawable/password"
android:padding="#dimen/px20"
android:text="#string/login_message_body"
android:textSize="#dimen/px20" />
<TextView
android:id="#+id/swipeMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/slideDescription"
android:text="" />

Text being truncated in TextView with width set to wrap_content

I'm trying to create a simple component in my layout, where there are two TextViews horizontally next to each other. The one on the right should start where the one on the left finishes. My code for this is as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#android:color/white"
android:textIsSelectable="false"
android:textSize="25sp" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textColor="#android:color/white"
android:textSize="20sp" />
</LinearLayout>
I programmatically set the text on each TextView after the view has rendered. However, sometimes the text does not display correctly in the first TextView- I can see that the width has been set correctly, as the second TextView is not next to it, but the text is truncated rather than using the space. If I lock/unlock the device to refresh the screen then the text displays correctly (without the widths of the TextViews changing).
I've tried changing this to use a RelativeLayout, but I see the same issue.
Any ideas?
Although i dont understant what exactly you mean, would suggest you to use weightSum property in the parent view and android:layout_weight in child views. The same allows to put many child views inside a parent view with respect to ratio (like navigation tabs).
for eg :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1" >
<TextView
android:id="#+id/text1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#android:color/white"
android:textIsSelectable="false"
android:textSize="25sp"
android:layout_weight="0.4" /> //60% width
<TextView
android:id="#+id/text2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textColor="#android:color/white"
android:textSize="20sp"
android:layout_weight="0.6" /> //40% width
</LinearLayout>
also, dont forget to put the width if child views as 0dp. as that will result in ignoring the calculations regarding the width of view. or you can set the width of child view as "match_parent" as well. any other property to width will not work. (and if you want half matchparent for both child views set layout_width to 0.5 both views.. ithink thats obvious to note)
Hopw it helps.

Categories

Resources