I was trying to set the padding of a LinearLayout in XML layouts of Android.
But it gives me 2 options - paddingLeft and paddingStart.
What are the differences, and is one the more correct/better attribute to use?
I want the best answer, because this needs the best quality code.
The short answer is: paddingStart is right-to-left (RTL)-aware, which paddingLeft is not.
You should favor paddingStart to make your app RTL-friendly, but make sure you test it (there's a developer option to force RTL on in your language, so you don't have to test your app in a language that you can't read).
If the user is in a locale that writes from right to left (RTL), then paddingStart will be applied on the right side, while if they're in a left-to-right (LTR) locale (such as English), it will be applied on the left side. paddingLeft, on the other hand, will always be applied on the left, regardless of the locale's text direction.
This is useful, because layouts are often reversed in RTL locales. For instance, a contacts list with contact photos might show the contact photo on the left for LTR locales, and on the right for RTL locales. Since the padding for the photo might be different than the padding for the other side of the item, you'd specify the paddings with paddingStart (for the photo's padding) and paddingEnd (for the padding on the other side of the item).
it's all about RTL support, if you choose paddingLeft then when your app operates in RTL Locale eg. Arabic your padding will be reversed. so, using paddingStart and paddingEnd is much more safer when trying to work with RTL world like Urdu or Arabic...etc.
Note : this doesn't matter if you assign the same values for Left and right padding, it obviously will behave the same in LTR and RTL worlds.
Related
I understand that texts may be LEFT or RIGHT on different languages, so that END or START may be useful for international apps.
However, LEFT or RIGHT as Gravity are also simple placement of things. If I want my button or icon to be aligned to the RIGHT, why on earth does lint complain on using END instead? Probably, if use END, the layout will become broken on a foreign device.
This seems like a basic question, but I couldn't find a similar one on SO. While reading the documentation, I was having trouble grasping the concepts. I want to understand what the difference is between top and ascent and also bottom and descent. And where exactly is the baseline? Do you have a diagram to help me visualize it?
Let's first review what the documentation says:
Top - The maximum distance above the baseline for the tallest glyph in the font at a given text size.
Ascent - The recommended distance above the baseline for singled spaced text.
Descent - The recommended distance below the baseline for singled spaced text.
Bottom - The maximum distance below the baseline for the lowest glyph in the font at a given text size.
Leading - The recommended additional space to add between lines of text.
Note that the Baseline is what the first four are measured from. It is line which forms the base that the text sits on, even though some characters (like g, y, j, etc.) might have parts that go below the line. It is comparable to the lines you write on in a lined notebook.
Here is a picture to help visualize these things:
Remember that when drawing on a canvas in Java and Android, going down is an increase in y and going up is a decrease in y. That means that FontMetrics' top and ascent are negative numbers since they are measured from the baseline (while descent and bottom are positive numbers). Thus, to get the distance from top to bottom you would need to do (bottom - top).
The leading is the distance between the bottom of one line and the top of the next line. In the picture above, it is the space between the orange of Line 1 and the purple of Line 2. As #MajorTom noted below, in typography the term is more properly defined as "the distance between the baselines of successive lines of type."* However, Android seems to use the term in the more historical sense. The word (pronounced "ledding") comes from the lead strip that the old typesetters used to put between lines of type. It was basically just a way to adjust the line spacing. In Android I've never actually seen the leading be anything other than 0 and I haven't seen it used for anything in the source code. (Correct me if you know where it is used to calculate anything.) You can change the line spacing in a TextView with setLineSpacing in code or android:lineSpacingExtra and android:lineSpacingMultiplier in xml. These methods, however, do not make use of or modify the leading.
Check out these links for more information:
Precise Android Text Drawing
Font Metrics in Java (and Android)
Layout documentation
Java: FontMetrics ascent incorrect?
FontMetrics not correct when run on android device. Simulator fine
Java Font Metrics (Java doesn't seem to use top and bottom)
Explore more
In order to explore Font Metrics more, I made a simple project.
Rather than listing all the code here. I added the project to GitHub. You can either clone the project, or copy the following files into a new project.
FontMetricsView.java (a custom view)
MainActivity.java
activity_main.xml
Do letters ever go above top or below bottom?
Not usually, but they could. Top and bottom, as I understand them, are set by the font (hence "FontMetrics"), so a font maker could make a glyph go higher than whatever they say the top is (or lower than the bottom). Also, with combining diacritical marks in Unicode it can very easily happen. Here is a rather extreme example (taken from here): M̵̳̙͔̟̱͕̓̀̄̉̅ͧ̋͊͌͑́͌ͪ̒̿̀̚a͔̟̝͔ͥ̈́̏ͮͯ̇͆̊̒ͦͦ͘͢͜y̵̴̢͕̝̩̱͈͕̼̣͕̟̌͗̾ͤ̎͌̄ͣͨ͊ͬb̡̯̰̪̜͙̟̝̠͚̜̥̙̤̃ͨ̋̒̒̊ͧͤ͐̓͋̌̾̇̔̈́̀́͡͠e̵ͯͪ̿̿̂̄ͫ̃҉͏͎̣̹̱̜͉̦̞̪̘̠̝̝͍̼̜̖̥̭͟ ̣̞͙͚̝̰̞̹̗̲̣͙͍͍̀̓͊̂̋ͣ̏̑̍̊͌ͩ͐̎̀ͣͣ̚͟ͅh̛͋̏̍̆ͤ͛͐ͨ̌̋ͤ̎̂ͨ̂̓̑̚̕͟͏̻̣͖̖͚͚͓̲̼̪ȁ̔̅̿͐̑͡͏̝͓̮͚̘̦̰͚͎͔͉͚̮̠̕͜ͅṱ̱̼̖̓̂ͭ̏̅͂ͥ͌ͯ͌͠sͪ̓ͪ̄̌̓ͧ͋͐ͬ̅̑҉̨̪̬͎͍̥̬?̡̮̳͙͓͔̹̘̹͓̘̻̦̣͎̫̐ͤ̐͛́͝ ̧̦̼̘͕̪̠̙͖̦̯̦̘͉͈͕͔̘̻̲͑ͨ̊̈́̐ͫ͐̌ͯ̀͘͝Ḩ̷̸̸̹͉̩̜̹̞ͯ̃̃ͧͬͨ̌̀̾̐̈̇ͧ͛̃͐̀ͦ͞A̴̦̗̬̠͙̭͉̟̺͇̭̰͔͕̯̅̃͋ͪ̈́̉̓̌ͯ̈́͆̋̀ͤ̇̂̿̈́̂͡͡Ṱ̲͎͉̣̳̺̱̜̦̬͕̣͉͇͊̌ͥ͐͒̈́̓́ͥ́́̋͂̅ͬ̆͗ͥ̕͢͡S̍ͧ͗̒͗̂̈ͬ͊̚̚͢͏̗̣̳ͅ!̶̨̡͇͚̙͚̭̱̣̲̳̤̞̫̗̣̦̮̖̞͒͆̿̄͑̃̎͡
Plugging that string into Android we get this:
The diacritical marks go above the top and below the bottom. It is interesting to note that the total width and height are correctly measured by the text bounds, though.
Anyway, for all practical purposes in your programming, you can just assume that the max and min for glyph letters are top and bottom. And usually they will stay within ascent and descent. If for whatever reason you need to know for sure if the letters go beyond top or bottom you can use TextPaint.getTextBounds.
Leading is NOT space between lines in typography. Apparently this is something Android code does not take into account. We've been struggling with this ourselves. The proper definition of leading (from Wikipedia):
In typography, leading /ˈlɛdɪŋ/ refers to the distance between the
baselines of successive lines of type. The term originated in the days
of hand-typesetting, when thin strips of lead were inserted into the
forms to increase the vertical distance between lines of type.
From what I can tell, Android does not have a way to specify this.
We are working on an app that requires RTL and LTR language text on the same screen, often in the same sentence, rendered using custom fonts. This poses several non-trivial problems:
The design uses different custom fonts for each of the LTR and RTL
languages. If we use the LTR font, the RTL text doesnt look good and vice
versa.
RTL fonts have greater line heights than LTR fonts so if the line
height is adjusted for RTL, it gets messed up in LTR and vice versa.
One suggestion is to use text markup for language boundaries in multiline text. Then based on markup we will use the equivalent of <span>s in text labels and apply a custom font to each span with custom line height. This sounds like a solution that will require significant text processing on the device and may not be portable, so the questions are:
Has any one successfully tried this approach for mixed-language text rendering?
Are there any other suggestions to render mixed language text on mobile devices?
On android you can add different layout xmls for both ltr and rtl, just like you do for mdpi/hdpi/etc.. Thats the approach (as far as I know) you are expected to take. IOs I have no idea.
This question already has answers here:
What is the difference between Android margin start/end and right/left?
(3 answers)
Closed 5 years ago.
I was making a xml file and was applying gravity to make view content to shift it to extreme right side of window but i saw gravity as right and end.So, what is the actual difference between the both and which one to use where.
in Arabic, Persian and all rtl (Right-To-Left) Locales, end is left but for English and other ltr (Left-To-Right) Locales end means right
Left and right gravities might not work correctly in applications localized for right-to-left languages like Hebrew, Arabic etc. In those languages left and right sides are mirrored to european languages. If you use hardcoded left and right gravities for some elements of your UI, then they might be misplaced in right-to-left localizations. If you use begin and end, then Android will map them correctly to left or right depending on current system language. Thus begin for English is equal to left and for Hebrew to right etc.
If you app has a localization for one of right-to-left languages, then you should always use begin and end. Otherwise you can safely stay with left and right.
In my opinion when we set
android:orientation="horizontal" in the main layout, then it's better to set gravity of its child as start and end to make it more effective with the layout.
BUT
when other orientations are used then we can use other gravity forms as well.
I would like to add some space between the left display border and an ImageView. Android SDK made me aware of "android:layout_marginStart".
Consider adding android:layout_marginStart="10dp" to better support right-to-left layouts
Why should I use android:layout_marginStart="10dp" instead of android:layout_marginLeft="10dp"? I have never done so and never encountered any problems with so-called "right-to-left layouts".
start and end are the same as left and right for left-to-right (LTR) languages. For right-to-left (RTL) languages (Arabic, Hebrew, etc.), start and end reverse and become equivalent to right and left, respectively.
This Android Developers Blog post gets into a bit more detail.
Some APIs were introduced to support languages that use a right to left reading direction e.g Arabic and Hebrew.
One of which is android:layout_marginStart
See the link for more info : http://developer.android.com/about/versions/android-4.2.html#RTL