Android RTL layout direction align center issue - android

I'm developing an Android App that needs to be support Arabic language. (Which should be read from Right To Left). After quick googled the solutions, I figure out android fully support Arabic language natively in API level 17 with the declaration of
android:supportsRtl="true"
in the application tag inside of the AndroidManifest so that I can use the layout mirroring to automatically flip the layout for better right to left reading experience. However, I've noticed there is an issue happening while I use centerInParent in a view that inside of a sub RelativeLayout during the layout mirroring. Below are my codes and expected layout.
<RelativeLayout
android:background="#color/white"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:padding="20dp">
<RelativeLayout
android:background="#drawable/shape_flag_imageview_boarder"
android:id="#+id/imageLayout"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_height="100dp"
android:layout_width="100dp"
android:visibility="invisible" />
<ProgressBar
android:id="#+id/progressbar"
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</RelativeLayout>
<TextView
android:id="#+id/text"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_toEndOf="#id/imageLayout"
android:layout_width="wrap_content"
android:text="Some text here bla bla bla"
android:textColor="#color/black" />
</RelativeLayout>
Image above showing the expected result in normal layout direction which is Left to Right. The purpose I wrap the ImageView and ProgressBar together in a sub view is because I want the ProgressBar showing in the middle of the ImageView while the image is loading from the internet. After the I've changed Locale to Arabic, it becomes like
As I've try and error and figure out that this is causing by the centerInParent of the ProgressBar. It instead of centering inside the sub view, it align center to the root parent view which is the most outer RelativeLayout. Below is the screen shot of removing centerInParent code from the ProgressBar.
It clearly shows the layout mirroring works good, but the ProgressBar position is not what I'm expected. So I've try to work on centerVertical and centerHorizontal, the result are shown in images below respectively.
None of the solutions works, and none of the topic I've searched related to this issue. So I guess this might be a bug from Android library? If anyone knows the issues or solutions, please share to me. Thanks

I fixed it by adding android:layoutDirection="ltr" into the child RelativeLayout. Basically, it deactivates the RTL formatting for this particular RelativeLayout, and the android:layout_centerInParent="true" behaves correctly again. It solves our particular issue as our particular RelativeLayout contains only centred elements. But this trick should not be used if the Layout contains other elements which have to support correctly RTL, like text views for example. Hope it helps.

This is an RTL layout bug in the Android framework, which only affects Android 4.2 specifically (API 17) and when android:supportsRtl="true" is enabled in AndroidManifest.xml.
It happens when you use a RelativeLayout that contains items positioned with android:layout_centerVertical="true" or android:layout_centerInParent="true".
You can fix it in Java code like this:
View relativeLayout = layoutInflater.inflate(R.layout.my_relative_layout, parent, false);
// Fix RTL layout bug on Android 4.2 (for Arabic and Hebrew mode)
if (Build.VERSION.SDK_INT == 17 &&
getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
// Force a left-to-right layout
relativeLayout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR);
}

let me tell you correct answer, look your RelativeLayout(id:imageLayout),it's width is wrap_content, and your ProgressBar(id:progressbar) add an attribute android:layout_centerInParent="true".It means parent not limit witdh,and child also want to center,so parent will be stretched.

Related

ImageView overlaps BottomBar but it doesn't get displayed

I'm using a library named AHBottomNavigation and what I want to achieve in my layout is add an ImageView on top of the bottom bar.
So I wrapped the bottomBar inside a FrameLayout and added an ImageView :
<FrameLayout
android:layout_width="match_parent" android:layout_height="wrap_content">
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/bb_bottom_bar_navigation"
android:layout_width="match_parent" android:layout_height="wrap_content"/>
<ImageView
android:src="#drawable/icon"
android:layout_gravity="center" android:contentDescription="Take Photo"
android:layout_width="32dp" android:layout_height="32dp" />
</FrameLayout>
and while it seems to work (and I can confirm that on three devices I have already tested I can see the image) when I test it on devices that run android 5.0 or later the image is not there!
I have tried different pngs, adding background color to the ImageView but still no result.
If I use uiautomatorView I can see the View is in the position I want it and takes the space I have already defined in the xml.
Obviously there's something that intercepts the view from drawing, but I don;t know such a mechanism on android. I tried digging through the code of the library but don't knowing what I'm searching for didn't help.
Any ideas ? (cause I'm out of ideas)

Fixed-width TextView with stretched compound drawable

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"

Android: Adding text below an image

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

Android Eclipse placing a text view in specific places

I'm creating this in a XML file and want a text view to be placed in a specific spot.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="200dp"
android:text="Text"
android:textColor="#color/blue"
/>
It's underneath the last button that was placed so it's around in the middle of the screen. I want it to be at the bottom of the screen of to the right.
Easy if you're using a RelativeLayout as parent.
android:layout_alignParentRight
android:layout_alignParentBottom
(check the capitalization, I'm not anywhere I can double check).
Using a RelativeLayout would be perfect if you would be specifying each views' positions. It is the most flexible layout among the Android Layouts.
Take a look at this tutorial. It discussed how to position views in a RelativeLayout.
I hope you can get ideas from it in solving your problem.

Android layout_below not working

I use RelativeLayouts extensively in my app and thought I knew how to specify them, but this has me at a loss. I am basically positioning 4 TextViews in two rows of two each consisting of a label and text that will be supplied. It should look something like:
Born: 23 Aug 1810 Mason Co., Kentucky
Died: 15 Jul 1865 Cincinnati, Hamilton Co., Ohio
This is the relevant portion of the layout:
<TextView android:id="#+id/birth_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/given_layout"
android:layout_alignLeft="#+id/given_layout"
android:layout_marginTop="6dip"
style="#style/label"
android:text="#string/born"
/>
<TextView android:id="#+id/birth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/birth_lbl"
android:layout_alignBaseline="#+id/birth_lbl"
android:layout_marginLeft="10dip"
android:layout_marginRight="6dip"
style="#style/main_text"
android:text="dd Mmm yy"
/>
<TextView android:id="#+id/death_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/birth"
android:layout_alignLeft="#+id/birth_lbl"
android:layout_marginTop="4dip"
style="#style/label"
android:text="#string/died"
/>
<TextView android:id="#+id/death"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/death_lbl"
android:layout_alignLeft="#+id/birth"
android:layout_alignBaseline="#+id/death_lbl"
android:layout_marginRight="6dip"
style="#style/main_text"
android:text="dd Mmm yy"
/>
For some reason, this displays the death line views ABOVE the birth line views! If I change the spec of the death_lbl view to instead be 'layout_below="#+id/birth_lbl"', the lines are positioned correctly! However, it is possible for the "birth" view to wrap to multiple lines, so I really need to position the 2nd line below "birth", not "birth_lbl".
Anyone know the reason for this behavior? It occurs both in the Graphical Layout editor in Eclipse and at runtime on my tablet running Android 4.0.
Try changing android:layout_below="#+id/birth" in death_lbl to android:layout_below="#id/birth", because at this point it is already declared, which the + implies, it could lead to problems when declaring it again.
I was also facing the same problem because I was using constraint layout, but align_below works only in Relative Layout. so check which layout you are using.
If fixing your + signs doesn't help, you could always position your id/death below id/birth, and then put id/death_label toLeftOf id/death.
I was actually able to duplicate this phenomenon by coding up a temporary layout with only those fields, and was able to determine that the problem went away if I did not position the initial birth_lbl view relative to the view above it ("given_layout" in this case).
So I'm not sure if this is classified as a fix, a workaround, or a kludge (is that still a word these days?), but what I did was to position the text views inside their own RelativeLayout and position the RelativeLayout relative to id/given_layout. In any case, it works...
Your problem is that you are calling the properties on the relative layout as if though you are declaring it again.
When you declare an ID for a view then it should be done like this android:id="#+id/button"
and when you want Android to position that particular view above or below any other view in a relative layout you have to call it like this android:layout_below="#id/textview"
This tells android that you declared a button with id button and want it to be positioned below the textview, remember do not use #+id to postion view use #id instead.

Categories

Resources