Background:
I've got a layout that consists of 6 items layed out as a grid (2x3). All items are as wide as half the screen (minus a little margin on each side). Each item is a RelativeLayout that contains an ImageView (the background) and a TextView (the label). The label is set to wrap the text, and it's allowed to grow almost as wide as the image it sits on top of. After that it will break into two lines.
Problem:
Everything looks good as long as the text fits on a single line (see top element in picture). The background wraps the text nicely. However, when the text is displayed on two lines the background gets too wide (see bottom item in picture). It fills up the maximum allowed width even though the text on the first line doesn't take up that much space. Is there a way to make the background wrap the text in the same way as it does when only one line is used?
Picture:
Layout XML:
<ImageView
android:id="#+id/item_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop" />
<!-- some stuff I had to remove... -->
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:paddingBottom="11.33333dp">
<!-- some other stuff I had to remove... -->
<!-- the gray background color is set to the TextView below programmatically together with the text itself. -->
<TextView
android:id="#+id/item_text_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5.33333dp"
android:paddingLeft="7.33333dp"
android:paddingRight="20dp"
android:paddingTop="1dp"
android:paddingBottom="5.33333dp"
android:layout_alignParentRight="true"
android:gravity="right" />
</RelativeLayout>
</RelativeLayout>
One of the possibility of such problem is textSize.
It depends on how you are setting and which measuring unit you are using to set textSize of your TextView.
dp,sp,pt and in may cause to create such problems.
So try to go with mm or px specifically.
And as per my testing px will give you the best result.
EDITED :
Add following attribute to your TextView in layout file.
android:gravity="right|start"
Instead of :
android:gravity="right"
Thanks.
Related
I have rows (of horizontal LinearLayout) with a TextView at the end that displays time. An this is how it looks:
Now I need the suffix (am/pm) in all rows to be aligned vertically. This is not the case in the above layout, as you can see, the last row is misaligned as the displayed time is longer.
I achieved this using the tab character \u0009. This means I would set the text to be for example "7:21\u0009\u0009pm". This produces desired result as show below:
However, I need to know if (1) this is the most efficient way and (2) that this would work on all android devices. If there is an alternative way to achieve this please let me know.
And here is an XML layout of a row for your reference:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="#dimen/prayer_time_row_height"
android:layout_marginLeft="48dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<com.devspark.robototextview.widget.RobotoTextView
style="#style/text_subhead"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Today"
android:textColor="#color/material_light_secondary_text"
android:visibility="invisible" />
<com.devspark.robototextview.widget.RobotoTextView
style="#style/text_subhead"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Event"
android:textColor="#color/material_light_primary_text" />
<com.devspark.robototextview.widget.RobotoTextView
style="#style/text_subhead"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="12:06\u0009\u0009am"
android:textColor="#color/material_light_primary_text" />
</LinearLayout>
BONUS
Bonus points for pointing out a way to vertically align the hour-minute separator, i.e., colon character.
Maybe using tabs is the most efficient, but the gap is pretty big and not configurable. If you need all those rows in a single view group, you may try to check out RelativeLayout: align am/pm vertically on common left, and put hours to the left and on the baseline. This is the most flexible way, since you can control relative positions and margins, but computation-wise it's less efficient because it requires extra calculation upon laying out elements.
As per aligning colons — in most fonts (not just monospace) digits are designed to take equal space, so just align the numbers on the right (e.g. in relative layout) and it should do.
For the colon character, you could try using the character "\uee01" instead of ":". This is what google does with the clock in the lock screen.
https://github.com/android/platform_frameworks_base/blob/master/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java#L247
You can use a 2-column TableLayout. The first column is the time without AM/PM and the second column is just the AM/PM. Set the gravity of the first column to "end" or "right" and the times will be lined up at the colons if you are using a fixed width font.
I'm trying to achieve the following layout: a fixed width TextView aligned to the left of its parent, with the text inside it aligned to the right side of that TextView (that's why fixed width, can it be done other way?) and the rest of the parent is filled with a drawable (simple line). Like this:
It's a ListView containing 2 types of rows and the layout for the rows with lines is quite trivial - LinearLayout with TextView and ImageView (I can post the exact code later if needed). And I'm getting a warning that it could be replaced with a single TextView with compound drawable.
I'm all for optimization so I really tried to follow that advice. Unfortunately I wasn't able to get the same result - the line is either constrained to TextView's width or text is aligned to the right side of the ListItem, now to fixed position.
Am I missing something?
Edit: Apparently it is not actually possible and since there are some other complications (the drawable is now a level-list drawable, which is not always a line and sometimes it has a non-fixed height that I have to set) I will leave it as it is now - linear layout, containing one TextView and one ImageView.
I don't think that you're missing anything. The TextView compound drawable features are not very customizable and in general are not worth the time you spend trying to get them to look right. Some lint warnings are a little overzealous and premature.
The optimization that the lint refers to is something that is better attributed for a fixed size image. In your case, the line has to stretch the rest of the screen length and as such it is not something that can be done with a textview with compound drawable. This kind of lint warning is more of a suggestion rather than something that MUST be done and is detected by just checking for a linear layout with only a textview and an imageview rather than checking what would need to go in the image view. If you already have it working the way you did it I think you should leave it alone.
Your view create from this -
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/time"
android:layout_width="#dimen/today_time_width"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:gravity="right"
android:layout_marginRight="5dp" />
<ImageView
android:layout_gravity="center"
android:id="#+id/border"
android:layout_width="match_parent"
android:layout_height="#dimen/today_current"
android:src="?attr/item_boundary" />
</LinearLayout>
There is no way to achive this using only standart TextView. If you really want to reduce view count you can create your custom TextView class, set layoutWidth to matchParent and draw line from text end to right border. But it's not worth to be doing. Some extra views won't slow your list.
I am not sure if you will be able to achieve what you really want to , but then you could change the linear layout in the link you posted to something like this:
<RelativeLayout
android:id="#+id/relTrial"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/txtTime"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="right"
android:text="12:45 AM"
android:layout_alignParentLeft="true"/>
<LinearLayout
android:id="#+id/lnrSep"
android:layout_width="fill_parent"
android:layout_height="1dp"
android:gravity="bottom"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:orientation="horizontal"
android:background="#android:color/darker_gray"
android:layout_toRightOf="#+id/txtTime"
android:layout_alignParentRight="true"></LinearLayout>
</RelativeLayout>
This way the time text will be right aligned although being at the left side, and the line will also be visible.
Hope that helps.
If I got you right, you want to add bottom border to list view item?
What about to try this:
android:drawableBottom="#drawable/line"
I am trying to have an image be fitted, and have a layout below it with some black background and whit text. My problem is that the layout ends up leaving space between the image and the text itself, and I don't understand why:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitStart" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="15dp"
android:layout_below="#+id/image" >
<TextView
style="#style/text_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Couple more elements -->
</RelativeLayout>
</RelativeLayout>
I would want this second RelativeLayout of 15dp touch the bottom of the image, but unless I change the image height to something small, it leaves some space. This layout specifies how to display an image + some text below it, but I have a total of 4 images that use this layout to get loaded on the screen, in a 2x2 display. (Each image takes 25% of the screen).
Any idea how to make the RelativeLayout align exactly with the bottom of the image please?
I do not fully understand your question though I think you might have a look at the launcher layout for my Newspaper Puzzles app...
http://code.google.com/p/newspaper-puzzles/source/browse/np/res/layout/launcher_layout.xml
or perhaps from the Open Sudoku Game look at the number pad layout found here:
http://code.google.com/p/newspaper-puzzles/source/browse/np/res/layout/s_im_numpad.xml
Use the ADT tools to get the right layout is probably best if possible but I know sometimes it is difficult to use to get specific results I still recommend using the xml tools included in the Android Development Tools.
http://developer.android.com/tools/help/adt.html#graphical-editor
I would recomend using a compound drawable if you're trying to put text directly below an ImageView.
See the following question for more details: How do I use a compound drawable instead of a LinearLayout that contains an ImageView and a TextView
I want two TextViews to overlap such that individual letters will overlap perfectly (i.e. you can't even see there is another TextView on the screen). Here is the relevant part of my layout:
<com.testing.android.animals.OutlinedTextView
android:id="#+id/label_left_name"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Elephant"
android:layout_alignTop="#id/picture_left"
android:layout_centerHorizontal="true"
android:textColor="#ffffff"
android:textSize="40dp"
android:background="#99000000"
></com.testing.android.animals.OutlinedTextView>
<com.testing.android.animals.OutlinedTextView
android:id="#+id/label_left_letter"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="E"
android:layout_alignBaseline="#id/label_left_name"
android:layout_alignLeft="#id/label_left_name"
android:textColor="#ffffff"
android:textSize="40dp"
android:background="#99ffffff"
></com.testing.android.animals.OutlinedTextView>
When rendered, it looks like this:
Notice the individual "E" (in light gray) is aligned too high.
What can I change in the layout that will get them to overlap better?
The issue is that the p makes the bottom of the full word textview taller. and since you have wrap_content as the height, the two heights of the textviews are different.
If you set the height of each textview to a specific size (the same size), they should align.
But in general, i think your approach might be wrong - you may want to either look into spannable strings for formatting or, since it appears you are using a custom control anyway, have it do the formatting of the first letter. (here is an example of spannable strings: http://www.chrisumbel.com/article/android_textview_rich_text_spannablestring )
I have a row of buttons with custom 9 patch images, and variable length text. I would like the buttons to be the same height. When the text is long enough to wrap, it expands the button size, making the button with wrapped text bigger than the others. I'm laying these buttons out in code in linear layouts. I can fix the size of the button, but then it just cuts off the bottom. How can I make the text take up more of the padding space of the button, so that the text butts up against the top line of the button?
9patch content area is just used to set a padding. If you change the button's padding you will override the one set by the 9patch.
edit
try something like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button android:text="ButtonButton"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingTop="0dp"
android:paddingBottom="10dp"/>
<Button android:layout_width="wrap_content" android:text="Button"
android:layout_height="match_parent"/>
<Button android:layout_width="wrap_content" android:text="Button"
android:layout_height="match_parent"/>
</LinearLayout>
this way the button will be as high as the others. Sadly, I don't know if it depends on the original button's 9patch that might have asymmetrical paddings, but I can't make the text align with that from other buttons (I think gravity is by default set to center). Maybe with your 9patch it works though. (EDIT: oh, but if you'll have two lines of text who cares about alignment)
Ultimately I was unable to find a nice way of doing this without creating a custom view class.