I have a list view with each list item being designed in a RelativeLayout. Within each relative layout I have three buttons and two text views. Everything should be in one row. The first text view is supposed to be left aligned, while the buttons are in one horizontal row aligned to the end of the parent, with the second text view being directly before them. My problem is, that very long text in the primary text view overlaps with the buttons and the second text view. The text does break into a second line if long enough, but I'd like it to break.
For now I have achieved the list to look like this. Sadly the text does not break before the buttons/associated text, but only at the end of the parent.
Previously I had a layout_marginEnd of 160dp, which worked fine on my personal phone, but since then I have received bug reports from users with other phones that own another brand.
My code looks as follows:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/nameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:textIsSelectable="false"
android:textSize="#dimen/listItemTextSize"
tools:ignore="UnusedIds" />
<LinearLayout
android:id="#+id/buttonLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
tools:ignore="RelativeOverlap,UnusedIds">
<TextView
android:id="#+id/amountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="8dp"
android:textIsSelectable="false"
android:textSize="#dimen/listItemTextSize" />
<ImageButton
android:id="#+id/subtractButton"
style="#style/Theme.ShoppingList.ImageButton"
android:background="#drawable/ic_minus"
android:contentDescription="#string/mainSubtractButtonDescription" />
<ImageButton
android:id="#+id/addButton"
style="#style/Theme.ShoppingList.ImageButton"
android:background="#drawable/ic_plus"
android:contentDescription="#string/mainAddButtonDescription" />
<ImageButton
android:id="#+id/deleteButton"
style="#style/Theme.ShoppingList.ImageButton"
android:background="#drawable/ic_trash"
android:contentDescription="#string/mainDeleteButtonDescription" />
</LinearLayout>
</RelativeLayout>
Thank you in advance for your help!
Add android:layout_alignParentStart="true" and android:layout_toStartOf="#id/buttonLayout" to the nameTextLayout.
This will break nameTextView before LinearLayout and keep nameTextView's text left aligned.
Add android:layout_toStartOf="#id/buttonLayout" to the nameTextLayout. This will make it stop before that linear layout and break there.
Related
so I'm currently working on an app on Android, and I got stuck on a specific problem regarding the RelativeLayout, which I can't find a way to solve.
I have in the layout three views as follows: TextView, Textview and ImageView (laid horizontally), here is a screenshot of the ios counterpart:
the Textview at the middle should stick to the first one, until he gets to the Imageview, when he does, he keeps his minimum size (wrap content), while the first Textview truncate.
On IOS I setted priorities to the constraint to accomplish this, but I can't figure out how to solve this on Android.
Here what I tried:
<android.support.percent.PercentRelativeLayout 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"
android:background="#drawable/daily_movie_title_box">
<TextView
android:id="#+id/daily_header_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="New Text aawi oa ioawfwi"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#color/white"
android:lines="1"
android:singleLine="true"
android:layout_alignParentStart="true"
/>
<TextView
android:id="#+id/duration_text"
android:text="138 mins"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textSize="13sp"
android:textColor="#color/white"
android:lines="1"
android:layout_alignBaseline="#id/daily_header_textview"
android:layout_toStartOf="#+id/certification_icon"
android:layout_toEndOf="#id/daily_header_textview"
/>
<ImageView
android:id="#id/certification_icon"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:src="#drawable/uk12a"
android:layout_alignBottom="#id/daily_header_textview"
app:layout_aspectRatio="100%"/>
</android.support.percent.PercentRelativeLayout>
Which resulted in this (which is what I want):
But when I increase the first Textview text it's not behaving as I desire...
Is it possible to achieve the behaviour I want in Android (keep the middle Textview wrap content, and truncate the first one if needed)?
I will post an update if I find a solution eventually, just wanted to see if anyone can find an easy way to achieve this behaviour, as I suspect there is.
Thanks.
From my understanding, you want the first TextView to be as large as possible, without adding space after the text if the text is too small. The second TextView should only wrap_content, but it should fill the rest of the parent layout when the row doesn't. The ImageView is set to wrap_content.
I tested it with this layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0"
android:stretchColumns="1">
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="Shrinking text dddddddddddddddddddddd"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Midle column"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"/>
</TableRow>
</TableLayout>
</LinearLayout>
The only problem is that if the second column has a incredibly large text, it will push the other views out of the parent. But in your case, I don't think that will be a problem. Otherwise, I think it does the job.
These are some suggested solutions:
You can use LinearLayout with horizontal orientation and weight for each component (TextViews and ImageView).
You can set the minimum and maximum text length for the second TextView.
But i prefer to apply the first solution. You can assign a weight for each component ( amount of space on the screen ) using:
android:layout_height
Hi my ListView's list items layout is as below: Also attaching Image that shows the output of this layout . In the above output image we can see the text present in 2nd line over laps with right aligned TextView. I want 3 dots to be placed at the end of Text with out overlap.
<?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" >
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="15dp"
android:layout_marginTop="16dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/sname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/name"
android:layout_below="#+id/name"
android:layout_marginTop="15dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/abbr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/sname"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
Can anyone help me in solving this issue ?
Thanks in Adavnce
Just add these layout attributes for your TextView
android:ellipsize="end"
android:maxLines="1"
This tells android you want your textview to be ellipsized at the end (add the 3 dots to the end of the text) and that you don't want your text to wrap to the next line (by setting the max lines).
The only thing you would need to then is make sure your TextViews don't overlap (the cri... portion). There are a number of ways to do this.
Move your abbr TextView to above your other TextViews and add android:layout_toLeftOf="#id/abbr" to your non-abbr TextViews
Redo your layout in general to make sure there is no overlap, using LinearLayouts would help achieve this with the benefit of things like weight.
Dynamically setting your widths once you know your window size.
In my user interface, I have a fragment with a RelativeLayout. At the bottom of this RelativeLayout, I have two buttons: one should be on the left, the other on the right, with empty space between them. The left one has static text (but because the app will be translated, I don't know what width it will be). The text in the right one can change arbitrarily.
Since I already have a RelativeLayout, I started out trying to lay them out inside the RelativeLayout like this:
<Button
android:id="#+id/button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="#string/left" />
<Button
android:id="#+id/button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="#string/right" />
But this has the problem that if the text in the right-hand button is too long, it will overlap the left-hand button.
I next tried to constrain the left-hand edge of the right-hand button by adding android:layout_toRightOf="#+id/button_left", but with this, the right-hand button would always fill the available width. When the text in the right-hand button is short, I want it to shrink to leave a gap between it and the left-hand button.
I next tried to use a LinearLayout, so I could set layout_gravity on the buttons, like this:
<LinearLayout
android:id="#+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<Button
android:id="#+id/button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/left" />
<Button
android:id="#+id/button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:drawableLeft="#drawable/pass"
android:text="#string/right" />
</LinearLayout>
Still no joy. I expected this to work, but the right-hand button stays just to the right of the left-hand button, instead of sticking to the right edge of the screen. I can see in the layout editor that the LinearLayout correctly fills the width of the screen, but the button stubbornly stays next to its friend.
I tried adding android:layout_weight="1" to the right-hand button too, but again, that made it always expand to fill the available space.
Next, I tried to add an empty View between the buttons, to expand and force the right button to the right, like this:
<LinearLayout
android:id="#+id/buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<Button
android:id="#+id/button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/left" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="#+id/button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="#string/right" />
</LinearLayout>
This works fine when the text is short, just like my original RelativeLayout did, but now when the text on the right-hand button is long, its width is limited by the width of the screen, not the available space, so it extends off the right-hand edge of the screen. Again, I can see in the layout editor that the LinearLayout has the correct width, but the button is extending ourside its parent's bounds. This happens even if the button has android:layout_width="match_parent". Oddly enough, increasing the layout_gravity on the right-hand button makes it smaller until it fits inside the available space, but of course that also makes it fill the space when the text is small.
I can't believe it's this hard to get this right. I've seen half a dozen similar questions on SO, but they all have easy workarounds. If the button text is fixed, you can set the margin to a fixed width by hand. If the expanding widget is a TextView instead of a Button, you can just let it expand and use android:gravity to move the text inside the widget, but you can't do that with a button because the background and borders are visible on the screen.
It turns out that adding the LinearLayout was the wrong approach. Using android:layout_toRightOf="#+id/button_left" android:layout_alignParentRight="true" works fine with a TextView, because that can soak up the available space without changing its appearance. Instead of trying to change the layout, I just need to use something that can expand to fill the available space and contain the Button: a FrameLayout. Here's the working code, which still goes inside my root RelativeLayout:
<Button
android:id="#+id/button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="#string/left" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/button_left" >
<Button
android:id="#+id/Turn_button_pass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="#string/right" />
</FrameLayout>
Now, the FrameLayout always takes up all the space to the right of the left-hand button, and lays out the right-hand button inside that space using android:layout_gravity="right".
This answer only adds one extra layout, but if someone has a way to do it only using the existing RelativeLayout, to minimise the number of ViewGroups in the layout, I'll accept that as a solution.
IF you can live with the constraint, that the right button only can take up to up half of the available space, this could be a solution for you:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_weight="1" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A short text" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="A very long text which is limited to one half of the available space" />
</RelativeLayout>
</LinearLayout>
You could just use a TextView and make it look like a button. Create a dummy button, extract the background and set that background to the textfield programmatically.
(Not tested but should give it the apperance of a button)
Drawable d = button1.getBackground();
textView1.setBackground(d);
then you just set the onClickListener and that should yield what you're looking for. The TextView would take the place of the "button_right" in your first layout.
**Edit
Your xml would look something like this
<Button
android:id="#+id/button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="#string/left" />
<TextView
android:id="#+id/button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:maxEms="10"
android:text="TextView" />
I wanted to make two equally-sized radio buttons with a custom background, text, and an image to the right of the text. Because of how different these are from a standard "Button", I made them using a clickable "RelativeLayout".
The text and the image are of different heights, but I want each one to be centered vertically in the button. I also want the combination of the text+image to be centered horizontally in the button. This second part is what I'm having trouble with; it's off-center, close to the left side. In the image below, the left side is what I want, but the right side is what's happening. The image on one of the buttons (the one with the longer text) is resized to be smaller, too... Though there is still plenty of space on the right side of the button.
Here is my code:
<LinearLayout
android:baselineAligned="false"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:id="#+id/my_button"
android:background="#drawable/radio_button"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<TextView
android:id="#+id/button_textview"
android:text="#string/button_label"
android:textAppearance="?android:attr/textAppearanceButton"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></TextView>
<ImageView
android:contentDescription="#string/image_description"
android:id="#+id/button_imageview"
android:layout_centerVertical="true"
android:src="#drawable/my_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_textview">
</ImageView>
</RelativeLayout>
<RelativeLayout
... same thing for the second button ...
</RelativeLayout>
</LinearLayout>
What am I doing wrong?
Use this as your button:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="MyButton"/>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:src="#drawable/my_image"/>
</LinearLayout>
Now, you can place it in other parent views. To apply layout attributes to above button, place those attributes in the outer <LinearLayout> tag of above button.
Alternative:
You can set custom images to be drawn on sides(Left,Right,Top,Bottom) of a TextView using attributes like:
android:drawableLeft="#drawable/my_image"
Turns out the solution was adding
android:paddingRight="0dip"
strangely enough, even though I didn't put any padding there in the first place.
I'm having real difficulty coming up with a layout which works. I have a view which fills the width of the screen. It contains three sub-views:
Some text
A number in parentheses after the main text
A button
The button is right-aligned, and the text items are left-aligned one after the other, as shown:
| Some heading text (n) [button] |
The problem is controlling what happens when the text is too long. I want it like this, so that the number is always visible just to the right of the main text. The main text should be truncated if needed so the other two views remain visible.
| Some very very long headin... (n) [button] |
The closest I've got which succesfully truncates the main text results in the (n) always being right-aligned next to the button even when the main text is short enough to fit. That's not what I want.
How would you approach this?
I'm not posting any of my current XML yet, lest it prejudice anyone's suggestions.
I do not believe there's any xml layout for that. My guess is that you will need to extend TextView and measure the text length inside onDraw(...), adjusting the text accordingly through some iteration (i.e., removing one character at a time until the text fits the canvas)
I just found another question that is quite similar to yours: Ellipsize only a section in a TextView . No other answer than ellipsize in the middle.
Another thoughts:
I'm wondering if it would work to have one textview with the main text (ellipsize left, wrap_content) and another with the number in the parenthesis (wrap_content), both inside an horizontal linear layout. That layout would be inside a relative layout and layout_toLeftOf the button, which would be wrap_content, layout_alignParentRight.
Does it make any sense? I don't have Eclipse now to test it myself. Not sure if the (n) textview would be lost behind the button or not with a long text.
Alternatively (and less interesting), you can setup one single relative layout with the two textviews all layout_toRightOf and the button aligned to the right (layout_alignParentRight) and set the max witdth ot the first textview (android:maxWidth). You would need to set up different layouts for different screens, though.
An example with a fixed max width that will work as required:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
android:id="#+id/bt1"
android:layout_alignParentRight="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="short text"
android:lines="1"
android:ellipsize="end"
android:id="#+id/t1"
android:layout_alignParentLeft="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="(n)"
android:lines="1"
android:id="#+id/n1"
android:layout_toRightOf="#id/t1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
android:id="#+id/bt2"
android:layout_below="#id/bt1"
android:layout_alignParentRight="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="very long text that will not fit in any layout, regardless of the size of the screen"
android:lines="1"
android:ellipsize="end"
android:id="#+id/t2"
android:layout_below="#id/bt1"
android:layout_alignParentLeft="true"
android:maxWidth="220dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="(n)"
android:lines="1"
android:id="#+id/n2"
android:layout_below="#id/bt1"
android:layout_toRightOf="#id/t2"
/>
</RelativeLayout>
Try a linearlayout, set the weight of the text view as 1,, and set ellipsis as TruncateAt.MIDDLE. Check this layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content">
<TextView android:id="#+id/text" android:layout_width="0dp"
android:layout_height="wrap_content" android:lines="1"
android:ellipsize="middle" android:gravity="left"
android:layout_weight="1" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
The key is the ordering of the items as this is the order they are measured, in order to ensure your button and (n) text get enough space in the overall layout:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
/>
<TextView
android:id="#+id/middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_toLeftOf="#id/button"
android:text="(n)"
/>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/middle"
android:layout_alignParentLeft="true"
android:gravity="left"
android:ellipsize="end"
android:text="Some really long to text to make this flow over"
android:lines="1"
android:maxLines="1"
/>
</RelativeLayout>