I try to translate my application to other languages. I added a few local files values/strings.xml to the project with relevant translation. The text is translated now, however it is not enough. There are 2 problems:
In some languages the words are longer then in English and as a result text exceed the space. For example a few letters in the word on the button appear in second row.
I have a form with the fields 'from' and 'to'. In English they appear left to right, however in right to left languages they should appear right to left on the screen.
How I can solve those problems?
You can define other layout for right to left languages. You should place it to layout-<your language code>.
Also you can truncate and replace last chars of the string if it is too large.
You can do this using android:ellipsize and android:singleLine attributes:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/text_mytext"
android:ellipsize="end"
android:singleLine="true"
/>
Another way is to define text size in dimens.xml for needed languages and use it as follows:
in dimens.xml:
<dimen name="text_size">32sp</dimen>
in layout:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/text_mytext"
android:textSize="#dimen/text_size"
/>
Related
We are showing some text in our application (say in a RecyclerView with GridLayoutManager). This text is shown in different languages as highlighted in the image below. Due to this, the height of TextView is different as different language fonts are taking different spacing.
Please refer to the sample image below and the required code to draw the text view.
<com.google.android.material.textview.MaterialTextView
android:id="#+id/tv_title_one"
android:layout_width="0dp"
app:layout_constraintWidth_percent="0.5"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="10dp"
android:fontFamily="#font/lato_bold"
android:gravity="start"
android:maxLines="3"
android:minLines="1"
android:singleLine="false"
android:includeFontPadding="false"
android:textColor="#541388"
android:letterSpacing="0"
android:lineSpacingExtra="0dp"
android:textSize="32sp"
android:textStyle="normal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Class 12th (Biology) 2021 - 2022" />
Dummy layout with two similar text views but with different language
Please let me know if there is anything missing in the problem description. Thanks for your valuable feedback.
Update #1:
Since there is no direct answer to it. We are going with making card height and text height-restricted as mentioned in the accepted answer.
I just think that the reason could come from the font you are trying to use for rending text in this TV. For every language, the character size maybe vary a bit from width to height due to the language specs.
Could you try to use the default system font to check if you still have that spacing issue?
Or another suggestion would be:
Use autoSizeMaxTextSize, autoSizeMinTextSize feature to allow text size being automatically resize to fix the textview when possible.
Apply a fix Height for your text content with extra Vertical Space, and add android:ellipsize as your wish.
Still wonder:
Is your app displaying multiple language at a same time on UI?
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 working on a layout that includes both English and Hebrew (intended as right-to-left) text, in separate views. When a line of Hebrew text gets beyond a certain length, it becomes written left-to-right (I assume that this has to do with length because it looks fine with shorter text, and when I display it on a tablet instead of a phone).
The relevant view looks like this:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:gravity="center"
android:textDirection="rtl"
android:text="#string/tx_middle_text"
android:textSize="#dimen/big_text_dp" />
and the string is defined in strings.xml like this:
<string name="tx_middle_text">טקסט בעברית</string>
(I've replaced the original text, which was 50 characters long, and made up entirely of Hebrew letters and white-spaces).
Note the text has the rtl attribute. I've tried replacing it with anyRtl, and I've tried changing gravity to "right" - neither helps.
I need the text to remain in one line and be cut off with an ellipsis if it doesn't fit - as it is, that's what happens, but with the text written left-to-right.
How can I fix this?
Edit: For an ad-hoc solution I made a shorter string as an alternative resource for the smaller layout (it works as long as the text is less than one line long on a given device), but I'd still like to know if there's a general solution to this.
RTL is detected automatically by the system depending on the characters. i.e for Arabic characters, text will be drawn from right to left.
This is an example on how my spinner is drawn. For this TextView:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_item"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="15sp"
android:gravity="center_vertical|start"
android:textColor="#color/spinner_filter_text"
android:ellipsize="end"
android:singleLine="true"
android:paddingStart="20dp"
android:paddingEnd="20dp"/>
And these strings:
<string name="all_categories">All Categories</string> (values)
(values-ar)
The result is:
If I modify the TextView with:
android:layout_width="100dp"
The result is:
Which I think is fine... Note that in strings.xml the string direction for ar language is wrong but Android is drawing it properly. I guess it is because of some Android Studio setting.
Replace android:singleLine="true" with
android:lines="1"
android:maxLines="1"
also add android:ellipsize="end"
I have a RelativeLayout where I have 2 TextView side by side (the left one it's the field name and the right one it's the value).
What I need it's to have the left textview always showing the full field name and the other TextView using the remaining space in that line to print the field value. Imagining that I have a field named "Field" with the value "That's a huge value!" and the remaining width of screen just leaves us with space to have half of the field value I need to have it like this:
| Field: That's a huge v... |
If, for some reason, the field name would fill the entire screen I don't event want to appear the value (I have another way of solving that).
I'm trying to find an adaptive way to do this (for any field and any value) but I can't find the right settings.
If I understood your question, the answer is simple:
<?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="wrap_content">
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FieldHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH:"/>
<TextView
android:id="#+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/tv1"
android:singleLine="true"
android:text="Value lllllllllllllllllllllllllllllllggggggggggggggggggggggggggggggggggggggggT"/>
</RelativeLayout>
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 )