Why does setting LayoutDirection on a LinearLayout not take effect immediately? - android

I am working on an application, using API 17 (4.2). In the application I am designing a layout class, and I would like to configure it according to the layout direction. However, I haven't been successful in retrieving the applied layout direction within the class:
LinearLayout layout = newLayout(context);
layout.setLayoutDirection(LAYOUT_DIRECTION_RTL);
int ld = layout.getLayoutDirection(); // STILL 0! I was expecting 1
My question is, how do I configure a layouts direction, and retrieve it within the class?

add this to your AndroidManifest.xml:
<application
...
android:supportsRtl="true"
>
As View checks RTL support first, if true, then resolve layout direction.
You can get more details in View.resolveLayoutDirection().

Related

text alignment - Android GravityFlags.Right cutting off first character of each line

I am working on a project that has RTL and LTR languages in it, and am currently modifying the layout such that controls are compatible with RTL languages, generally meaning that side-by-side text/control paradigms need to be reversed. In order to align the text in a certain TextView to the right, I am using GravityFlags.Right, but that's causing the first character of every line of text to be cut off. I have tried many different combinations of GravityFlags to get this to work, but no dice. Putting a non-breaking space at the beginning of the translation works, but only for the first line. And it's impossible to know where every line will break. See example below...
Control with text using GravityFlags.Center:
vs.
Control with text using GravityFlags.Right:
I have tried to remove the margins around the outside of the control, which simply pushes the control and the text to the edges of the screen, and the result is the same. The text being clipped to the right is clearly seen in the second picture.
Thanks for any help.
If you want to support LTR and RTL, you should better use start/end instead of left/right. You could have a try, more info can refer to here.
In addition, not forget to add android:supportsRtl in AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<uses-sdk android:minSdkVersion="17" ... />
<application ... android:supportsRtl="true">
</application>
</manifest>
android:minSdkVersion should above 17.

Setting layoutdirection with supportsrtl=false

I have an application on which I do not have the liberty to add supportsRtl = true
With that being set to false I have two questions.
1) Is it possible to set supportsRtl true programatically?
2) This is the code that doesn't work when supportsRtl = false
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
Any ideas as to how can I have a single layout file be displayed in ltr/rtl while the supportsRtl is false?
Setting only one layout direction to RTL wouldn't be a good idea since users who uses RTL direction will need to see the right texts direction for all Activities-layouts.
Just set the android:supportsRtl="true" in the AndroidManifest.xml then go to:
Refactor -> Add RTL Support Where Possible
This will satisfy your need by adding RTL to where it's possible.
About that start-end attributes in the xml side, all you need to do is:
Right-click on the project -> Replace in Path
Then replacing your start-end attributes easily by using this.

How to override RTL support on a layout in Android

I set android:supportsRtl="true" in the <application> tag in AndroidManifest.xml, but I need to force one of the views to be left-to-right nonetheless, even when the language of the interface is Hebrew or Arabic. How can I force a specific view to be LTR in an RTL application?
Specifically, I want to force some linear layout to go left-to-right instead of the default right-to-left even when the language is right-to-left.
Generally gravity="left" is enough to force text to be left-to-right. But it didn't help with the direction of a linear layout. The solution was to add android:layoutDirection="ltr".
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutDirection="ltr">
for letf to right all layout content.
To complete the answers, aside from XML, layout direction can also be changed programmatically with ViewCompat.setLayoutDirection(view, LayoutDirection.RTL). This API can be used from API 19 and onwards, so If your min sdk version supports API below 19, an if-check needs to be performed:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ViewCompat.setLayoutDirection(...)
If you want to force your application to ltr even on rtl languages you don't need layout direction (it works on api>17) you can just set android:supportsRtl to false.

How to set z index by using some integer values

I have been working in android for past few months. The problem for me is now related to Z index value. I am having a layout with a textview,edittext and imageview.
Suppose i have a xml file something like this..
<Layout1>
<edittext><zindex>3</zindex></edittext>
<textview><zindex>2</zindex></textview>
<imageview><zindex>1</zindex></imageview>
</Layout1>
So my question is that am reading this xml file by DOM parser and i want to set the z index value for all these by the values defined in the xml. Now is there any function or property that i can use to do it.
I have learnt about coding it with xml, but that will make it hardcoded. I want a dynamic display so how do i adjust layout with the zindex values.... HELP PLZ
there is no Z-index in android layouts. You'll need to use FrameLayout or RelativeLayout if you need to place elements on top of each other in reverse order.
see Placing/Overlapping(z-index) a view above another view in android
You can use view.setZ(float) starting from API level 21. Here you can find more info.

Defining Z order of views of RelativeLayout in Android

I would like to define the z order of the views of a RelativeLayout in Android.
I know one way of doing this is calling bringToFront.
Is there are better way of doing this? It would be great if I could define the z order in the layout xml.
The easiest way is simply to pay attention to the order in which the Views are added to your XML file. Lower down in the file means higher up in the Z-axis.
Edit:
This is documented here and here on the Android developer site. (Thanks #flightplanner)
If you want to do this in code
you can do
View.bringToFront();
see docs
Please note, buttons and other elements in API 21 and greater have a high elevation, and therefore ignore the xml order of elements regardless of parent layout. Took me a while to figure that one out.
In Android starting from API level 21, items in the layout file get their Z order both from how they are ordered within the file, as described in correct answer, and from their elevation, a higher elevation value means the item gets a higher Z order.
This can sometimes cause problems, especially with buttons that often appear on top of items that according to the order of the XML should be below them in Z order. To fix this just set the android:elevation of the the items in your layout XML to match the Z order you want to achieve.
I you set an elevation of an element in the layout it will start to cast a shadow. If you don't want this effect you can remove the shadow with code like so:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
myView.setOutlineProvider(null);
}
I haven't found any way to remove the shadow of a elevated view through the layout xml.
I encountered the same issues: In a relative layout parentView, I have 2 children childView1 and childView2. At first, I put childView1 above childView2 and I want childView1 to be on top of childView2. Changing the order of children views did not solve the problem for me. What worked for me is to set android:clipChildren="false" on parentView and in the code I set:
childView1.bringToFront();
parentView.invalidate();
Please note that you can use view.setZ(float) starting from API level 21. Here you can find more info.
Thought I'd add an answer since the introduction of the
android:translationZ
XML field changed things a tad. The other answers that suggest running
childView1.bringToFront();
parentView.invalidate();
are totally spot on EXCEPT for that this code will NOT bring childView1 in front of any view with a hardcoded android:translationZ in the XML file. I was having problems with this, and once I removed this field from the other views, bringToFront() worked just fine.
API 21 has view.setElevation(float) build-in
Use ViewCompat.setElevation(view, float); for backward compatibility
More methods ViewCompat.setZ(v, pixels) and ViewCompat.setTranslationZ(v, pixels)
Another way collect buttons or view array and use addView to add to RelativeLayout
childView.bringToFront() didn't work for me, so I set the Z translation of the least recently added item (the one that was overlaying all other children) to a negative value like so:
lastView.setTranslationZ(-10);
see https://developer.android.com/reference/android/view/View.html#setTranslationZ(float) for more
Or put the overlapping button or views inside a FrameLayout. Then, the RelativeLayout in the xml file will respect the order of child layouts as they added.
You can use custom RelativeLayout with redefined
protected int getChildDrawingOrder (int childCount, int i)
Be aware - this method takes param i as "which view should I draw i'th".
This is how ViewPager works. It sets custom drawing order in conjuction with PageTransformer.
Check if you have any elevation on one of the Views in XML. If so, add elevation to the other item or remove the elevation to solve the issue. From there, it's the order of the views that dictates what comes above the other.
You can use below code sample also for achieving the same
ViewCompat.setElevation(sourceView, ViewCompat.getElevation(mCardView)+1);
This is backward compatible.
Here mCardView is a view which should be below sourceView.

Categories

Resources