The title is a little provocative, but I observe some behaviour thats inexplicable for me.
I have three sets of views, each having one TextView tvX and one Spinner spX, X=A,B,C. The textview is a title, or prompt, for the spinner, so I want the Spinner layout_toRightOf it's respective TextView. Since they refer to each other, I also layout_alignBaseline the Spinner to the TextView. This works properly. Now I want the three sets stacked such that the TextViews have aligned right edges (each has a trailing colon, these should be aligned), and the Spinners have aligned left edges. So in the stack of
+----------+----------+
| tvA:|spA |
+----------+----------+
| tvB:|spB |
+----------+----------+
| tvC:|spC |
+----------+----------+
the B and C views get attributes referring to A and B, respectively; namely layout_below and layout_alignLeft/Right.
It now happens that tvB and tvC have texts that are longer than tvA's. I would have guessed the RelativeLayout indents tvA such that there is space for the longer texts of tvB and tvC, and such that they are right-aligned. What happens instead is that the whole left column gets the width of tvA's text, and tvB and tvC get broken into two lines each. I tentatively tried to rearrange things to make tvB the anchor, and layout_above tvA. This results in tvA completely disappearing. It would not be a proper solution anyway, as in another language the relative lengths of the texts might be the other way! If I add characters to tvA to make it longest, tvB and tvC do not get broken anymore, but the colons still do not get aligned! In fact it looks as if tvB gets centered beneath tvA, and tvC centered beneath tvC.
It sort of looks best if I left-align the tvX and right-align the spX. But even in that situation something strange happens: The Spinners do no obey the attribute layout_width="wrap_content" anymore, they expand instead to fill all the space left over by the TextViews. The ragged alignment in the middle still looks bad, that's why I want the alignment to happen in the middle.
Android Studio displays the resulting layout while editing the XML, and it also displays the Views edges if the cursor is in the XML definition of the View. There I can nicely observe how the layout hints in the attributes get ignored! On the actual phone the same thing happens.
Here is the XML code:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/indented_margin"
android:layout_marginBottom="5dp">
<TextView
android:id="#+id/device_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:text="#string/settings_sb_device" />
<Spinner
android:id="#+id/device"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:spinnerMode="dropdown"
android:layout_toRightOf="#id/device_title"
android:layout_alignBaseline="#id/device_title" />
<TextView
android:id="#+id/can_speed_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_below="#id/device_title"
android:layout_alignRight="#id/device_title"
android:text="#string/settings_sb_speed" />
<Spinner
android:id="#+id/can_speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:spinnerMode="dropdown"
android:layout_toRightOf="#id/can_speed_title"
android:layout_alignBaseline="#id/can_speed_title"
android:layout_alignLeft="#id/device"
android:entries="#array/can_speeds" />
<TextView
android:id="#+id/baudrate_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_below="#id/can_speed_title"
android:layout_alignRight="#id/can_speed_title"
android:text="#string/settings_sb_baudrate" />
<Spinner
android:id="#+id/baudrate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:spinnerMode="dropdown"
android:layout_toRightOf="#id/baudrate_title"
android:layout_alignBaseline="#id/baudrate_title"
android:layout_alignLeft="#id/can_speed"
android:entries="#array/baudrates" />
</RelativeLayout>
I have searched the sets of available attributes for the involved views, but could not find a clue. Can anybody explain this behaviour? What have I overlooked?
Use a GridLayout for this with columnCount as 2
For example:
<android.support.v7.widget.GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
app:alignmentMode="alignBounds"
app:columnCount="2"
app:orientation="vertical"
>
For the left side Tv + colon, use a RelativeLayout or even a LinearLayout will work for that matter.
<LinearLayout
android:gravity="center"
android:orientation="horizontal"
app:layout_column="0"
app:layout_columnWeight="1"
app:layout_gravity="fill_horizontal|fill_vertical"
app:layout_row="0">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:text="Label"
android:maxLines="2"
android:ellipsize="end"
android:textColor="#color/black"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:text=":"
android:textColor="#color/black"/>
</LinearLayout>
It seem to me that a GridLayout would fit your needs way better...
Related
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.
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
Let's start with the fun part, here's the graphic of the trouble. Horizontally, everything is beautiful.
The middle button, I'd like to to be aligned with the other three. Here are the basics:
overall, it's a relativelayout
inside this relativelayout, it's a horizontal linear layout, containing the three buttons
the "sinking" of the middle button is 100% correlated with it being a dual line of text, if I change it to a single line, it aligns properly
the specified height of the buttons has nothing to do with the sinking, even at more than double their current size (from current 70 to 170) the exact same behavior (and size of behavior) is displayed
The "custom_button" background has no effect, if I change them all to no background, stock looking buttons, the same positioning occurs
And here's the XML (of just the linearlayout within the relativelayout):
<LinearLayout
android:id="#+id/wideButtons"
android:layout_below="#+id/buttonClockFinish"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:orientation="horizontal">
<Button
android:id="#+id/buttonLog"
android:layout_weight="1"
android:layout_height="70dp"
android:padding="0dp"
android:layout_marginRight="3dp"
android:layout_width="fill_parent"
android:background="#drawable/custom_button"
android:text="View Log" />
<Button
android:id="#+id/buttonLocation"
android:layout_weight="1"
android:layout_height="70dp"
android:padding="0dp"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:layout_width="fill_parent"
android:background="#drawable/custom_button"
android:text="Location\nD1-RS" />
<Button
android:id="#+id/buttonHelp"
android:layout_weight="1"
android:layout_height="70dp"
android:padding="0dp"
android:layout_marginLeft="3dp"
android:layout_width="fill_parent"
android:background="#drawable/custom_button"
android:text="Help" />
</LinearLayout>
So why on earth is it not aligning?
I was just about to post this question, and did one final experiment. I added a THIRD line of text to the button. This pushed it down even further. But what I realized it had in common was that the text of the top line of the middle button remained perfectly aligned with the text of the two buttons to either side of it.
So it wasn't that it was having trouble with an interior margin, unable to squish the text against the top border. The alignment was of the TEXT, not the button graphic. All along I had thought that there was some mystery :padding that I was not nulling out, but with three lines of button text it was quite happy to have just about 1dp or so of padding.
The solution was to add
android:layout_gravity="center_vertical"
to that button. I added it to the rest of them too, just for consistency.
Lesson: When you think things aren't aligning, perhaps they actually are, but maybe you're looking at the wrong thing.
I am wondering how to have a TextView display its content on several lines without hardcoding the width in the XML.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="false"
android:text="Long multiline text"/>
<TextView
android:textColor="#color/text_color"
android:layout_width="130dp"
android:layout_height="wrap_content"
/>
</LinearLayout>
Any thought welcome.
EDIT: my problem is that when the text exceeds the width set (because it reaches the end of the screen) a portion of the text is just not displayed. I would expect the text to be split on two lines
Though I cannot reproduce the not wrapping problem, you can fix the positioning problem by using a weight on the first TextView. Using the following XML gives the expected output in the graphical layout view in Eclipse:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:singleLine="false"
android:text="Long multiline text"/>
<TextView
android:textColor="#color/text_color"
android:layout_width="130dp"
android:layout_height="wrap_content"
/>
</LinearLayout>
Also add
android:minLines="2"
android:scrollHorizontally="false"
You could try
android:inputType="textMultiLine"
in your TextView XML. This worked for me.
I think I had very similar problem. I had a TextView with a text, where I was not sure how much lines will it take. It was encapsulated by a LinearLayout having android:layout_width="match_parent" to ensure my text will fill out all the space horizontally. However, the problem was that my text did not fit into 1 line and when it did break into a new line, the next view component below it did not move downwards to give enough space for the second line to be viewable fully.
I could achieve the solution by changing the LinearLayout that was containing my TextView into a RelativeLayout. By this way, the element below the text (actually below the Layout itself) was moved automatically to give enough space for the multi-line text.
I have an activity with two Buttons and a TextView in a LinearLayout. My TextView is offset downwards and the text doesn't fit inside the box. Can you explain what is happening? I think it is related to padding, and I've read several discussions about the perils of TextView padding, but that doesn't explain why the text is cut off at the bottom.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#800080">
<Button
android:text="This"
android:background="#drawable/button_red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:text="That"
android:background="#drawable/button_green"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:text="Copious amounts of text that overflows onto several lines on a small screen, causing the TextView to dangle below the buttons. Why it does this I can't imagine. I only hope someone can help me with this."
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#533f93"
/>
</LinearLayout>
This code produces this display:
The purple is the LinearLayout, the blue is the TextView. As you can see, the TextView's top is below those of the buttons and its bottom is below the bottom of the LinearLayout. As I add text to the TextView, the LinearLayout increases its height appropriately, but because the TextView is offset, I always lose the bottom of the last line.
I ran Hierarchy Viewer and it gave me this wireframe:
Which shows the vertical offset at the top, but misses the bottom of the TextView. The same wireframe with the LinearLayout selected looks like this:
According to Hierarchy Viewer, the top of the buttons is at 0, but the top of the TextView is at 7. I've tried various fixes, mostly culled from this site:
android:paddingTop="0dp"
android:background="#null"
android:includeFontPadding="false"
None of these fixed my issue.
Set android:baselineAligned property of your LinearLayout to false.
From documentation:
When set to false, prevents the layout from aligning its children's
baselines. This attribute is particularly useful when the children use
different values for gravity. The default value is true.
give the layout_gravity of the Textview to be center_vertical
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#800080">
<Button
android:text="This"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:text="That"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:text="Copious amounts of text that overflows onto several lines on a small screen, causing the TextView to dangle below the buttons. Why it does this I can't imagine. I only hope someone can help me with this."
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#533f93"
android:layout_gravity="center_vertical"/>
</LinearLayout>
Try setting the layout_gravity for the TextView like this:
<TextView
android:text="Copious amounts of text that overflows onto several lines on a small screen, causing the TextView to dangle below the buttons. Why it does this I can't imagine. I only hope someone can help me with this."
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#533f93"
android:layout_gravity="top"
/>
If you have this problem with several TextViews you can add android:gravity="center_vertical" to LinearLayout