android:gravity fails on API 18+ - java

I have some TextViews on my app, I don't know why but the android:gravity attribute is not centering the text content where it should be on devices running the API 18+ (4.3+).
There is the code I use on my custom TextView, this is a child of RelativeLayout:
<com.package.custom.CustomTextFont
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/seekbar"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/seekbar"
android:layout_marginLeft="#dimen/margin_tiny_double"
android:layout_toLeftOf="#+id/seekbar"
android:gravity="center_vertical|left"
android:paddingRight="#dimen/margin_tiny"
android:text="#string/text1"
android:textColor="#color/black"
android:textSize="#dimen/size_text_normal" />
This code should take the edges of this TextView and align it to the top and bottom and put it to the Left of the SeekBar, this is working, but the TextView gets big, so with android:gravity I center the text to the center and left from it self. It works, but I don't know why, the text is not centered at center|left on devices running android 4.3 and 4.4. This issue can be reproduced on real devices and as well on the layout preview (Graphic layout) of Eclipse.
There is any changes made on API 18+ or on android:gravity that I'm missing?
PS: I'm targetting the API 19 on the project and on AndroidManifest.xml
PS2: My TextView is custom just to set an external font.tff
This is how it looks like on API 17-
This is how it looks like on API 18+
Thanks in advance!
= UPTADATE =
On my Manifest, I changed the android:targetSdkVersion to 17 instead of 19 and the problem disappeared, but this is a "trick", not a solution, what can I do since it could be an issue from the API ? And yes, I have the latest version of the API 18 and 19 (today, 01/30/2014).

This appears to be a known issue in API 18+:
https://code.google.com/p/android/issues/detail?id=59368
https://code.google.com/p/android/issues/detail?id=59700
The problem seems to occur when a TextView is part of a scrollable container (e.g. ListView), making the view ignore the vertical gravity for some reason (some sources suggest this has to do with the TextView being the child of a RelativeLayout, though it's been my experience that this can happen even when no such layout is involved).
A possible workaround (albeit not a particularly elegant one), would be to wrap the TextView in a LinearLayout. You can then use "layout_gravity" on the TextView to center it inside the LinearLayout, instead of relying on "gravity" (just make sure to wrap_content so the text itself is properly centered).
E.g., in your example:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignBottom="#+id/seekbar"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/seekbar"
android:layout_toLeftOf="#+id/seekbar"
android:layout_marginLeft="#dimen/margin_tiny_double" >
<com.package.custom.CustomTextFont
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="left"
android:paddingRight="#dimen/margin_tiny"
android:text="#string/text1"
android:textColor="#color/black"
android:textSize="#dimen/size_text_normal" />
</LinearLayout>
This method does have the disadvantage of adding an otherwise-unnecessary level to your view hierarchy, but it currently seems to be the only way around this (other than reverting to an earlier API level).
Also see similar question at:
Android sdk 18 TextView gravity doesn't work vertically

Your textview height is "wrap_content", which means the height of the textview will be the same as the height of the text. If you change the background of the textview to black, it might be easier to see the bounds of the view. I'm guessing you'll find that the textview doesn't have as much height as you expect.
Try setting the height of the textview to match_parent. You can wrap the textview inside another view if needed and modify its height as appropriate.

Related

Android, should I center content?

I'm pretty new to android and wanted to ask about the centering practices, what I mean is that for example:
Before I say something, I don't know what are the good practices are so...
I can have a LinearLayout with height as match_parent and android:layout_marginTop="?attr/actionBarSize"(btw, according to google's material 56dp).
So that is one option, but, I saw apps where the content is centered nicely if the device is really long(such as Galaxy Note devices), so what I did is:
Same LinearLayout but with height as wrap_content and android:layout_gravity="center", but the problem here is with for example a form with 1 field(almost no content height), the problem is that almost no content will leave you with a lot of space between the toolbar and the content and below that content as well.
My question: altought may be obscure I'm asking for the best practices, what is the best approach that will make content(bigger or smaller) appear nicly on multiple devices, maybe it would require multiple layouts/dimens, I'm ok with that, just looking for the right path.
There is another view group named RelativeLayout.
You can use it like this:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
// here you can use attributes such as `android:layout_below`, `android:layout_above`,`layout_toRightOf`
//to modify and control your items
/>
</RelativeLayout>

Changing AlertDialog buttons alignment

Been fighting for hours about changing the alignment of the buttons inside AlertDialog (support.v7 one), since they won't align themselves according to the locale view direction, despite the whole app DOES align to left and also the text inside the AlertDialog.
(Why would this happen you say? I'm programatically configuring the locale language to be "en" since that's my default app language, even though the system locale might be something else).
So like I said, I don't need to touch the message inside the dialog, but as an example, that's how to change it's direction:
TextView messageView = (TextView)dialog.findViewById(android.R.id.message);
messageView.setGravity(Gravity.RIGHT); // or LEFT
Of course it doesn't work on the buttons, since I need to change the layout gravity instead.
Here's how I find the buttons (after I call show() on the AlertDialog.Builder of course, else they would be null):
AppCompatButton accept = (AppCompatButton)dialog.findViewById(android.R.id.button1);
AppCompatButton cancel = (AppCompatButton)dialog.findViewById(android.R.id.button2);
And here's how I attempt to change their alignment inside their parent LinearLayout:
((LinearLayout.LayoutParams)accept.getLayoutParams).gravity = Gravity.RIGHT;
((LinearLayout.LayoutParams)cancel.getLayoutParams).gravity = Gravity.RIGHT;
I chose RIGHT since the side of the buttons inside the dialog is always opposite to the side which the text is aligned to. (Yes - I tried LEFT also, nothing changed).
This doesn't work. Does anyone have an idea how to achieve this? It seems they are just stuck to their place.
Edit:
Title isn't aligned also, I just confirmed this (for some reason it appears on the right, like my system configuration, and not like my locale configuration).
The problem isn't the Gravity settings... When you look at the xml source (../sdk/platforms/android-23/data/res/layout/alert_dialog_material.xml), the layout's AlertDialog contains this:
<LinearLayout android:id="#+id/buttonPanel"
style="?attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content" ...>
<Button android:id="#+id/button3"
style="?attr/buttonBarNeutralButtonStyle" ... />
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="invisible" />
<Button android:id="#+id/button2"
style="?attr/buttonBarNegativeButtonStyle" ... />
<Button android:id="#+id/button1"
style="?attr/buttonBarPositiveButtonStyle" ... />
</LinearLayout>
There is a Space view with the buttons. This view fills the container with its weight. Therefore, you actually have a widget which pushes the buttons at the right's parent container.
A simple solution might to get the parent's buttons container and remove the Space element before setting a gravity.
// get the container
LinearLayout containerButtons = (LinearLayout) dialog.findViewById(R.id.buttonPanel);
// remove the Space view
containerButtons.removeView(containerButtons.getChildAt(1));
// set a gravity to the children buttons
containerButtons.setGravity(Gravity.RIGHT);
However, you should create and use your own custom layout, in case of future Google's development changes might occurring.
You can completely customize an AlertDialog.
The trick here is probably to use a custom view for the dialog, and create your own buttons in that view.
For an example, see
How can can I add custom buttons into an AlertDialog's layout?

Android: Fixed size ScrollView not scrolling/scrolling weird

I have a problem with a fixed size scrollview that i'm trying to make. I've read many questions that are similar (but not equal) to mine here in StackOverflow and other sites and none of the answers have helped me, so I decided to ask my own question.
Basically, i want a fixed size scrollview with different controls inside. The basic one would be a textview of a dynamically changing size inside it. When I change the text of the textview and it is bigger than the scrollview, the scrollbars flash quickly, as they should, indicating that I can scroll but no matter how many times I swipe my finger, it doesn't scroll. Then I tried swiping with two or three fingers and sometimes (only a counted number of times) it scrolls.
I have tried many different approaches to this, like changing the textview to an edittext with focusable = false so it doesn't give the user chance to edit the text; or putting the textview alone in the scrollview, or wrapping it in linearlayouts, relative layouts etc. and it still doesnt scroll.
Below is the code as it is today. This scrollview is inside a vertical linearlayout along with other controls that I'm not putting 'cause of the length, but if someone needs it, I'll put it. I would appreciate very much if someone can point to my problem or help me solving this.
XML:
<ScrollView
android:id="#+id/scrollFifthHorizontalLineDetails"
android:layout_width="304dp"
android:layout_height="133dp"
android:layout_gravity="center"
android:layout_marginTop="5dp" >
<LinearLayout
android:id="#+id/rrrr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/txtlblPlaceDetails"
android:layout_width="302dp"
android:layout_height="wrap_content"
android:background="#drawable/placedescriptionbg"
android:text="#string/null_text"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
</ScrollView>
the line in which I populate the TextView:
((TextView) findViewById(R.id.txtlblPlaceDetails)).setText(mJsonOb.getString("placeDescription"));
I had a similar problem with an Android app I was developing a few months back. I got around the scrolling problem by increasing the layout width for the scroll view. In the editor you can actually drag the RHS of the scroll view to exceed the visible area. I think I set the android:layout_width to about 1024.

How to create a Layout were I can place anything where I want?

I'm designing an app with many images, buttons and textViews strewn across the screen. At the moment I am using the relative layout as it seemed the most flexible of the lot. However were I place my elements and their size is still restricted to being aligned with other elements. Even worse if an element changes size any elements aligned to it will also change size.
There must be a simple solution to this! Apple's nib files perform this so easily with an effortless drag and drop to any location; yet android appears to be stuck with restrictive table/linear/relative/grid layouts.
If possible can the solution be performed via eclipse. If not please guide me to the relevant documentation to learn to create my own layouts via xml, create a huge grid layout or whatever horrors await me :)
Thanks
I think what you want is something like an absolute layout tho these were deprecated a while ago, Im pretty sure you can still do this via a Relative layout, you don't necessarily need to align the via with another view, I guess you could just do something like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="70dp"
android:layout_marginTop="82dp"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="172dp"
android:layout_marginRight="84dp"
android:src="#drawable/ic_launcher" />
</RelativeLayout>
all I'm doing here is aligning it with the side of the parent and having a margin between it
You can do what you ask with a Frame Layout and setting the position of each object. But do so at your own risk. The reason Apple nib files let you arbitrarily place objects is taht the aspect ratio of all their devices is the same. So your layouts just scale up and down evenly.
Android is a more diverse ecosystem, and you should try to embrace layouts that adapt to different screen sizes and orientations.
Take a look at Android custom layout and Android - How to draw a letter at a specific point?
Are you planning to only use the app on a single android device model? If yes, check AbsoluteLayout's Alternatives. (FrameLayout or RelativeLayout)
It's not a good idea to put "Anything Anywhere you want" since Android devices have a lot of different screen sizes and properties. The only option would be to define your own custom layout.
I actually really like the way Android tries to make your layout compatible with as much devices as it can using alignment and structured layout views.
The reason it's simple for Apple is that you're only targeting iPhone, which has a fixed screen properties accross all devices.
Hope it helps. Good luck.

RelativeLayout and accessebility support

I am adding accessebility support to some application. It works fine with standart UI elements (buttons for example), but for some reason does not work with my custom element, wich is RelativeLayout with ImageView and TextView (it looks like icon). I've defined android:focusable="true" and set contentDescription.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
android:contentDescription=”my content description”
android:focusable="true">
<ImageView
...
/>
<TextView
...
/>
</RelativeLayout>
Could someone please list here all posible causes?
UPDATE:
Is there some way to know what layouts are on the screen at the moment and what order do they have (some layouts are transparent)?
Use hierarchy viewer for understanding where is your invisible views.
The android docs have a section about designing for accessibility, is this any use to you?

Categories

Resources