TextView text aligment is horrible! How to work around it? - android

I always seem to have the biggest issues with aligning a text on a layout. Seems like the TextView doesn't measure its text properly. The reported TextView width and height are a lot bigger than the actual text. One would expect the TextView width and height to be tightly wrapped around the text.
The image below shows how the number 18 and the text "SEC" are not aligning on the same bottom baseline. This is due to the larger text height being a lot bigger than the text is. My xml layout can be seen below.
How to achieve better text alignment accuracy?
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#drawable/scan_block_1_bg" >
<LinearLayout
android:id="#+id/staticCountDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/tvStaticScanning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:shadowColor="#ffffff"
android:shadowDy="1.0"
android:shadowRadius="0.01"
android:text="SCANNING"
android:textColor="#878787"
android:textSize="20sp" />
<TextView
android:id="#+id/tvCountDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:shadowColor="#66000000"
android:shadowDy="-1.0"
android:shadowRadius="0.01"
android:text="03"
android:textColor="#b6b6b6"
android:textSize="81sp" />
</LinearLayout>
<TextView
android:id="#+id/tvStaticSeconds"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/staticCountDown"
android:layout_toRightOf="#id/staticCountDown"
android:gravity="left"
android:shadowColor="#ffffff"
android:shadowDy="1.0"
android:shadowRadius="0.01"
android:text="SEC"
android:textColor="#878787"
android:textSize="12sp" />
</RelativeLayout>

//use this attribute in your TextView
android:layout_alignBaseline="#id/staticCountDown"
and android:layout_marginBottom="-10dp"

As strange as it may sound if you look at the screen shot provided Both the textviews have the same bottom base alignment. Try putting letters "gj" in tv countdown. You can actually see both will come to have same bottom base alignment. Its better go with padma Kumar's answer.

Related

Relativelayout position view between two views

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

Textview width doens't adjust after change content

I'm trying to update the content of a TextView with the data introduced by an EditText. But after change the text, if the original text (hint) was bigger than the new text, the width doens't change.
I have the next string in the Hint Attribute of the TextView, "Please, introduce a amount". If I put 25'5, for example, the textview doesn't resize it width.
First Screen
Second Screen
The Euro symbol is invisible behind the textview, and It's shown after insert some value.
The piece of code for the Amount:
<RelativeLayout
android:id="#+id/rlImporte"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/rel_layout_colors"
android:clickable="true"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<ImageView
android:id="#+id/lst_img3"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_margin="5sp"
android:layout_marginTop="5dp"
android:src="#drawable/icon_importe"/>
<TextView
android:id="#+id/tvImporte"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="false"
android:layout_marginTop="5dp"
android:layout_toRightOf="#+id/lst_img3"
android:text="#string/IMPORTE_TITLE_STRING"
android:textColor="#android:color/black"
android:textSize="#dimen/title_text_size" />
<TextView
android:id="#+id/tvImporteDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tvImporte"
android:layout_toRightOf="#+id/lst_img3"
android:textColor="#android:color/darker_gray"
android:textSize="#dimen/subtitle_text_size"
android:visibility="visible"
android:hint="#string/IMPORTE_PLACEHOLDER_STRING"
android:textColorHint="#android:color/darker_gray"
android:ellipsize="start"
android:layout_marginRight="4dp" />
<TextView
android:id="#+id/tvEuroSymbol"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvImporte"
android:layout_toRightOf="#+id/tvImporteDesc"
android:textColor="#android:color/darker_gray"
android:textSize="#dimen/subtitle_text_size"
android:visibility="gone"
android:hint="#string/euro_symbol"
android:textColorHint="#color/blue_quantion"
android:ellipsize="start"
android:paddingLeft="4dp" />
</RelativeLayout>
You seem like you want to change the width of tvImporteDesc dynamically. The short of it is that Android does not allow this, though some people have developed work arounds. (Toggling the visibility that some answers suggest did not work for me). Similar questions:
Change Relative layout width and height dynamically
WRAP_CONTENT not working after dynamically adding views
Since you are trying to fit text on the same line it might be easier to use a single TextView for that line of text, and concatenate the euro symbol?

Keep ImageView on the right size of the text and yet prevent long text to push it out of view?

The situation is the same no matter if I use LinearLayout or RelativeLayout. I think this is a old Android XMl bug, but I have no idea why it still exists.
Namely, in a layout where an ImageView is on the right side of a TextView can disappear from the screen when text becomes too long. It simply pushes it off the screen. I must NOT make TextView single line.
Here is the XML.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="some long text blahblahblahblahblah"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="17sp"
android:layout_marginRight="10dp"
android:layout_centerVertical="true"
/>
<ImageView
android:layout_toRightOf="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/key"
android:layout_centerVertical="true"
/>
</RelativeLayout>
I cannot use layout_weight attribute as image will then stick to the right side of the screen. It HAS to be on the right side of the text.
Anyone has any ideas how to solve this bug?
Check images when the text is short and long. On the 2nd image the text is long and the image is being pushed away from the screen.
You can achieve your task, if you use the layout_weight properly. Please refer the code below:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="The quick brown fox jumps over the lazy dog. As you can see it easily handles the long length of the text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="17sp"
android:layout_marginRight="10dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher"
/>
</LinearLayout>
The output for long text:
The output for short text:
EDIT:
This works because of the layout whose width is set as wrap_content. If it were match_parent then in all cases, all the extra space would have been given to TextView because of it's layout_weight but since the parent is wrap_content, there is no extra space for the TextView to fill when the text is small. But when the text is large, the weight property is applied to the TextView but since there is no layout_weight for the ImageView hence, it takes only the amount of space it has to.
Set
android:layout_marginRight="30dp"
for the TextView
and
android:layout_marginLeft="-20dp"
for the ImageView
You can change the values depending on your needs.
But, if the image can have different sizes, you will have to set margins programmatically.
there is 2 solutions for these
either set the image as a drawableRight to the textview
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="The quick brown fox jumps over the lazy dog. As you can see it easily handles the long length of the text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="17sp"
android:layout_marginRight="10dp"
android:drawableRight="#drawable/ic_launcher"
/>
or
alignt the image to right and make textview toleft of the image

Double center text issue in TextView and RelativeLayout

I've a problem centering a text in an already centered TextView:
That's the layout:
<RelativeLayout>...
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:src="#drawable/w0"
android:layout_margin="10dip"
android:background="#color/green1"
/>
<TextView
android:id="#+id/temperature"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignBottom="#id/image"
android:layout_alignTop="#id/image"
android:layout_toRightOf="#id/image"
android:text="15º"
android:textSize="60dip"
style="bold"
android:textColor="#color/blue"
android:gravity="center"
android:layout_marginLeft="7dip"
android:background="#color/green1"
/>
<TextView
android:id="#+id/min_temperature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#id/temperature"
android:layout_toRightOf="#id/temperature"
android:text="M 21º"
android:textSize="20dip"
style="bold"
android:textColor="#color/blue"
android:layout_marginLeft="5dip"
android:background="#color/orange1"
/>
<TextView
android:id="#+id/max_temperature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/temperature"
android:layout_toRightOf="#id/temperature"
android:text="m 10º"
android:textSize="20dip"
style="bold"
android:textColor="#color/blue"
android:layout_marginLeft="5dip"
android:background="#color/orange2"
/>
And that's the displayed layout image:
What I don't understand is why the 15º isn't centered in the TextView.
The problem is due the TextView's forced center using alignTop and alignBottom but I can't see why it doesn't works.
I know I can solve this using some nesting layouts but I prefer to get a solution using only the RelativeLayout or if it isn't possible understand the reason.
Also is there a solution to align the maximum and minimum TextViews with the top and bottom of the 15º text (not the TextView) as there is now.
Also is there a solution to align the maximum and minimum TextViews with the top and bottom of the 15º text (not the TextView) as there is now.
I don't think so. You can only make things relative to the actual box that the View represents. And in the case of TextView the box is larger than the Text. Any relations that you do make are going to use the position of the Box no matter where the text is at or what it looks like.
Try using
android:layout_centerVertical="true"
on your temperature TextView in addition to the gravity you have now.

Centering a TextView while keeping it to the right of a button?

I'm pretty sure I've done this before, but I've forgotten how.
Here's the problem:
I've got a button and a textview, and I want the textview to be centered, while the button is on the left side.
No problem? Just put them in a relativelayout, make the textview centerinparent, and the button alignparentleft.
But now I'm going to dynamically change the text, so it can potentially be written on top of the button! I'll just add toRightOf="#id/button" on the textview. No, now it's no longer centered.
I wish I could provide a screenshot, but it seems the computer is out of memory and can't do that.
Here's some code: http://pastebin.com/3N70Vjre (Since I can't paste xml...?)
<RelativeLayout
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<Button
android:id="#+id/leftbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="text!"
/>
<TextView
android:id="#+id/toptext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:layout_toRightOf="#id/leftbutton"
android:layout_centerInParent="true"
android:textSize="16sp"
android:textStyle="bold"
android:text="Text!"
android:singleLine="true"
/>
</RelativeLayout>
Try this (unfortunately I'm at work so can't jump into Eclipse to get you some code) -
Change the layout_width of the TextView to fill_parent.
Set the gravity of the TextView to center (so the text centers inside the TextView)
Set the layout_weight of the Button to 1 and the layout_weight of the TextView to 2. Note that you may have to fudge with these numbers to get the layout you're looking for.
This should center the text of the TextView after the Button, though it will not center the TextView itself. You can accomplish that by replacing the TextView with a container (Linear/Relative Layout) and doing the same method as above on the Layout instead of the TextView. You would then put your TextView inside the container and set the container's gravity to "center".
Hope this helps point you in the right direction :)
You can try this (pseudo-code):
<RelativeLayout>
<Button>
<LinearLayout toLeftOf="toptext" type="horizontal">
<TextView gravity="center">
</LinearLayout>
</RelativeLayout>
You might have to have the LinearLayout as width="fill_parent". Not sure if that will work nor not. You can subsequently try some of the things listed here: http://thinkandroid.wordpress.com/2010/01/14/how-to-position-views-properly-in-layouts/
Try declaring the TextView first, then aligning the button to the left of the text view. Keep in mind you may run into issues if the TextView becomes too wide.
EDIT: I see, so you're trying to do something sort of like the iPhone's header with back/next buttons (similar anyway). Try this modification. I still believe you're going to run into issues if the TextView gets large enough to hit the Button, though.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
>
<TextView
android:id="#+id/toptext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:layout_alignParentCenter="true"
android:textSize="16sp"
android:textStyle="bold"
android:text="Text!"
android:singleLine="true"
/>
<Button
android:id="#+id/leftbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="text!"
/>
</RelativeLayout>
Try this FrameLayout instead. This may do more what you're expecting:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/toptext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#android:color/white"
android:textSize="16sp"
android:textStyle="bold"
android:text="Text!"
android:singleLine="true"
/>
<Button
android:id="#+id/leftbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text!"
/>
</FrameLayout>

Categories

Resources