I'm trying to create a message layout in a chat application.
This message layout should contain:
Message Textview in a rounded rectangle
Message status check icon ImageView within that same rectangle
Message send time TextView outside the rounded rectangle and to its right.
When text is short, the whole layout should align itself to the right.
When the text is long, message TextView is going to expand itself to the left and upon touching the left side of the screen, it expands to a new row.
The problem is: Rounded rectangle stretches to the whole screen regardless of the message being short or long although underlying FrameLayout width is set to wrap_content.
Here is an image of the problem:
The layout I am using is:
<RelativeLayout
android:id="#+id/outer_rl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingTop="8dp">
<TextView
android:id="#+id/text_message_time"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:textSize="10sp"
app:showDate="#{message.postedAt}" />
<RelativeLayout
android:id="#+id/bubble_ll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/text_message_time"
android:background="#drawable/rounded_rectangle_bubble_sent"
android:padding="8dp">
<ImageView
android:id="#+id/iv_check"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_alignParentRight="true"
android:layout_gravity="center_vertical"
android:layout_marginLeft="4dp"
app:setStatusPng="#{message.status}" />
<TextView
android:id="#+id/messagetext_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="2dp"
android:layout_toLeftOf="#id/iv_check"
android:singleLine="false"
android:text="#{message.messageText}"
android:textColor="#ffffff" />
</RelativeLayout>
</RelativeLayout>
The inner RelativeLayout named bubble_ll has its width equals wrap_content.
What I am expecting is:
text_message_time TextView should be attached to the right of the screen due to its layout_alignParentEnd property set true.
bubble_ll stands left of the text_message_time view, due to its layout_toLeftOf property set. And it should have a width of its contents.
I have tried other layouts such as Linear, ConstraintLayout etc.
The LinearLayout approach did not work, since the width is set to wrap_content for TextView always overlaps status info checks and message time make them disappear when the message in the TextView is long.
With ConstraintLayout I could not align bubble to stay still on the right. It stays on the center of the screen horizontally since it is constrained on both horizontal sides of the screen.
Any help will be appreciated.
I have come up with the following layout which is a combination of RelativeLayout and LinearLayout. I hope this serves your purpose. Please change the drawables and the ids if necessary.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/outer_rl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="8dp">
<TextView
android:id="#+id/text_message_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/message_container"
android:layout_alignParentRight="true"
android:layout_margin="4dp"
android:text="10:30 am"
android:textSize="10sp" />
<LinearLayout
android:id="#+id/message_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_toLeftOf="#+id/text_message_time"
android:background="#android:color/holo_blue_dark"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="#+id/messagetext_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
android:padding="4dp"
android:singleLine="false"
android:text="You have a long message here. This is so long that it takes two lines inside the TextView. No wonder, now its taking three lines and now its four. How long this message can go? I now have that question!!!"
android:textColor="#android:color/white" />
<ImageView
android:id="#+id/iv_check"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_centerVertical="true"
android:layout_margin="8dp"
android:src="#android:drawable/presence_online" />
</LinearLayout>
</RelativeLayout>
Related
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.
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.
I'm trying to build the following layout on Android without any success.
I want a text to be displayed on my screen. It can take the whole width, but must be centered horizontally.
On the same line, on the right side of the screen I want to display a small layout. It shouldn't impact the horizontal centering of the main text and the main text shouldn't be visible behind the layout displayed on the right.
I cannot use a hard color for my layout background as it's displayed on a transparent background over a bitmap...
Any idea on how to achieve this ?
I can either use a RelativeLayout in which case the main text isn't centered based on the middle of the screen (it takes the right layout width into account)
Or the text is displayed behind the right layout...
Edit:
Here is one of my test
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom|center_horizontal"
android:layout_centerInParent="true"
android:fontFamily="sans-serif"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:singleLine="true"
android:textColor="?android:attr/textColorPrimary"
android:textSize="17sp"
android:text="very looooooooooooooooooooooooooooooooong text"
android:textStyle="bold" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerInParent="true"
android:layout_alignParentRight="true"
android:padding="3dp"
android:visibility="visible" >
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_vertical"
android:filter="true"
android:src="#drawable/device_access_time" />
<Spinner
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
</LinearLayout>
</RelativeLayout>
RelativeLayouts adhere to the principle of z-indexes, so if you put the right-aligned layout first, the centered text view will be drawn correctly on top.
I am sorry I know it's simple question but I can't make this happen now.
I want one text always will be in center and another in right.
But when texts is too loo long they come to each other.
Let's say I want second text always be in the right and first text is in center but when one of these texts is too long the centered texts have to move left.
How could I do this?
I write this but it doesn't work properly.
<RelativeLayout
android:id="#+id/workout_footer_text"
android:layout_width="match_parent"
android:layout_height="#dimen/workout_header_height"
android:background="#color/green"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingLeft="#dimen/activity_horizontal_margin">
<TextView
android:id="#+id/review_comments_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/text_color_white"
android:textSize="#dimen/review_top_text_size"
android:singleLine="true"
android:gravity="center"
android:layout_toLeftOf="#+id/review_write_label"
android:layout_centerInParent="true"
android:layout_gravity="center"/>
<TextView
android:id="#+id/review_write_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/text_color_white"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:singleLine="true"
android:layout_marginLeft="20dp"
android:textSize="#dimen/review_top_text_size"
android:layout_centerVertical="true"/>
</RelativeLayout>
Instead of layout_toLeftOf="#+id/review_write_label" in your first TextView, remove that line and add layout_toRightOf="#id/review_comments_label" to your second TextView to make sure the first view stays centered and the second view stays to the right.
Update
Then make the second view's width match parent and set it's gravity to right. This will right justify the text in a container that stretches from the right edge of the centered TextView to the right edge of the parent thanks to the match_parent width.
You can try this:
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:orientation="horizontal">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="text1" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="text2" />
</LinearLayout>
Here's the code:
<RelativeLayout
android:id="#+id/tc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/tc"
android:layout_marginLeft="185dip"
android:layout_marginTop="25dip"
>
<ImageView
android:id="#+id/tc_icon"
android:background="#drawable/count_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/tc"
android:layout_mar
/>
<TextView
android:id="#+id/tc_icon_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:text="1"
android:layout_gravity="bottom"
android:textColor="#f7e906"
android:textStyle="bold"
/>
</RelativeLayout>
I have somehow managed to make the image and the text views overlap each other (which I wanted). Now, I want them to be placed to the bottom left corner of their parent RelativeLayout (with id 'tc').... However, they just wouldn't move.
If I used alignParentBottom.... the entire relative layout stretches across the screen and aligns to its parent relativeLayout.
Please help. Thanks! :)
If you wanna overlap an image and a textview, simplw use a android:drawableleft or ony position where you want.
For example:
<TextView
android:id="#+id/tc_icon_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:text="1"
android:layout_gravity="bottom"
android:textColor="#f7e906"
android:textStyle="bold"
android:drawableleft="#drawable/yourimage.jpg"/>
This will give you an image on the left of your textview. Check it out