Am I missing something, if I just have a standard TextView and set its text size over a set number the gravity to center the text stops working, see below example.
Gravity working:
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="B"
android:textSize="472sp" />
Gravity not working
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="B"
android:textSize="572sp" />
This happens on a device as well as the emulator / preview.
I would have guessed it's because the total size of the TextView including implicit padding (such as may exist) is simply larger than your screen, so the field is pinned at the top and the visible portion is forced down the screen. What happens if you put it onto a bigger display? Edit: In the 572sp example, it comes pretty close to centered in portrait mode on a tablet.
Related
In the image above, the black speech bubble and the red background behind it are a single ImageView that spans the width of a vertical phone screen. The "Hello" is a TextView and the layout is relative. Using margins, I was able to position the "Hello" inside the speech bubble in my Android emulator -- but the positioning is off when I emulate a different phone.
Is there a better way to position my TextView
is there a way to make it responsive (so that the Hello is always in
the speech bubble, no matter what the device)?
Here's my xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/mainGraphic"
android:src="#drawable/finished2"
android:layout_marginBottom="97dp"
android:layout_above="#+id/enterValue"
android:layout_alignParentStart="true" />
<TextView
android:maxWidth="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/helloText"
android:textColor="#FFFFFF"
android:layout_marginEnd="29dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="45dp" />
</RelativeLayout>
I would use a FrameLayout instead of the RelativeLayout with same size like the image.
Then use the attributes android:layout_gravity="center" and android:gravity="center" for the TextView.
Try this:
...
<TextView
android:maxWidth="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/helloText"
android:textColor="#FFFFFF"
android:layout_alignTop="#+id/mainGraphic"
android:layout_alignBottom="#+id/mainGraphic"
android:layout_alignLeft="#+id/mainGraphic"
android:layout_alignRight="#+id/mainGraphic"
android:gravity="center" />
...
Best approach is to use 9-patch image & set it as the background of the Textview. If you use a normal png file, we can't guarantee that it will align correctly on all resolutions & it can become blurred when stretched.
9-Patch image automatically resize to accommodate the contents of the view and the size of the screen. Android SDK provides a tool for creating 9-patch images which is inside SDK sdk/tools directory. See https://developer.android.com/studio/write/draw9patch.html.
You should use a 9-patch for the message shape. What you can do is make the root view of your layout as a FrameLayout and then add a TextView to it. Set the message shape Nine-patch as the background of the TextView.
For creating the 9-patch visit https://romannurik.github.io/AndroidAssetStudio/nine-patches.html by Roman Nurik. There just upload a png file of the image asset and choose the xhdpi definition for best results. The Nine-patch has 3 main properties -
Stretch regions : Defines which areas of the asset can stretch for accommodating different screen densities.
Content Padding : Defines the padding area for the content (text) that is going to appear inside the image.
Optical Bounds : Defines how much area should be optically visible around the asset.
Pros of using Nine-patches :
Scalable
Easy to use
Lightweight
Any amount of content can be put in it.
Hope this helps.
Ideally, you should be using a complete red background to the RelativeLayout, and a black speech 9patch image for the TextView.
But if you really want the RelativeLayout to have background as red with speech bubble, you have to set it at run time.
Calculate the height and width of RelativeLayout at run time say 150px and 300px respectively.
Carefully look at the background image, and determine the edge points of bubble from top, right, bottom and left. For example, if image height is 100px by 200px, and bubble top starts at 30px and bottom ends at 70px, right edge starts at 150px and left ends at 250px. Also calculate the width and height of TextView.
At run time, change the position of TextView based on the above figures.
I'm just starting out with android and trying to make a simple user interface.
I'm using TableLayout and each TableRow is supposed to contain an image and several buttons next to it. I set the width and height of the buttons to wrap_content, which is exactly what I want. Now I want the image to have exactly the same height as the buttons. The image is way bigger, so wrap_content doesn't work.
Obviously I can just adjust the dp value of the image height until it fits, but there has to be an easier way and I guess that pretty much defeats the purpose of using wrap_content in the first place...
Set the height of the image to match_parent. Your buttons are doing all the height-sizing work having the wrap_content set. When the row gets sized it uses the button height, as they say "you will be as tall as our content", and then when the image is going to be sized, it will use the available height, as specified before by the buttons. Even if the buttons are smaller than the image, the image will still take the available space.
Try this
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TableRow
android:id="#+id/tableRow1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
I'm fairly new to Android and would never have gotten as far as I am without this forum.
Here's my problem:
Am using a simple LinearLayout with an ImageView vertically positioned above a TextView. My goal is to display a series of screens with a images on the top and a short text caption on the bottom. The text is wrappable and the image should be scaled to fill the remaining available vertical space.
Everything works fine if I keep the text font size constant (I use .setTextSize(35) normally). The problem is that when I display an empty image, I choose to enlarge the text (.setTextSize(120)). That works OK..but then when I next display a subsequent image and revert to the text size to 35, there's a large unfilled gap between the bottom of the image and the top of the now smaller text area.
What appears to be happening is that using the larger text size once has somehow permanently increased the minimum height of the TextView. I've tried clearing the TextView (.setText("")..changing the size to very small (.setTextSize(12)...and endlessly fiddling with the LinearLayout parameters (weight, gravity)...to no avail. Any thoughts on how to fix this would be most welcome.
<ImageView android:id="#+id/img" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_weight="1.0" android:layout_gravity="fill_vertical" android:contentDescription="#string/desc" />
<TextView android:id="#+id/caption" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_weight="0" android:layout_gravity="bottom"
android:gravity="center"/>
***Solution discovered after posting: Turns out that this is a known bug since Android 3.1. See Android:TextView height doesn't change after shrinking the font size.
Of the recommended solutions/workarounds listed there, the one that I'm liking is that every time you set text do:
setText("I am a Text",TextView.BufferType.SPANNABLE);
Or after resizing your text just do: setText(getText(),TextView.BufferType.SPANNABLE);
Whether this answer helps much or not, I think android:layout_weight="0" is redundant. A weight statement (say android:layout_weight="1") is also more usually accompanied by a android:layout_height="0dp" or android:layout_width="0dp", depending on the orientation of the containing LinearLayout.
I have some image like this
and I want to make the red areas clickable areas.
I want to make this areas clickable meaning when user touches the screen at some red sot I want to be notified a.i I want to register a listener.
The problem is with that the image is different size for different screen, some screens have a size of 240x320 some 400x800 for the image view I use fill_parent so the image will fill the whole screen in every screen. and this clickable areas sometimes will be 50dip from the left border sometimes will be 150dip. Sometimes it is 10dip from the top sometimes it is 500dip... everything depends on the screen size
how to handle this kind of scenario ?
The best way is to cut your image for separate pieces, and put them inside RelativeLayout.
Then set click listener for those images where you need.
Another way you could handle this is determine screen size and calculate touch areas:
final Display display = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
final int width = display.getWidth();
final int height = display.getHeight();
I found a very good tutorial on this site here: http://blahti.wordpress.com/2012/06/26/images-with-clickable-areas/
The way you do it:
- You have 2 images.
- 1 is the background and the other is on top of it and is an invisible mask.
- The mask gets an OnTouchListener.
- The mask has different colored areas(your touch areas).
- If you touch the image, the mask checks for the color and do an action.
The nice thing is: If you scale the image, the touch areas also scale, so you will always have your touch areas on the right position.
It is pretty straight forward. Hope i could help, even if your question is older than a year.
Here is another example (last). You just put on top of your image transparent buttons and handle click.
<?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="fill_parent" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#android:drawable/edit_text" />
<Button
android:id="#+id/bottomLeft"
android:layout_width="100dip"
android:layout_height="100dip"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#android:color/transparent" />
<Button
android:id="#+id/center"
android:layout_width="100dip"
android:layout_height="100dip"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:background="#android:color/transparent" />
<Button
android:id="#+id/bottomRight"
android:layout_width="100dip"
android:layout_height="100dip"
android:layout_centerInParent="true"
android:background="#android:color/transparent" />
</RelativeLayout>
I have a 9 patch png in a RelativeLayout and everything looks great! However, when i create a textView in the RL, the textView is not at the top of the parent... I also tested this on the phone, same result... why does it do this?
Thanks for your assistance!
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/testLL"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/backrepeat"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="15dp"
android:layout_gravity="center_vertical|center_horizontal"
android:background="#drawable/contentbox">
<TextView
android:text="Test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
</RelativeLayout>
</LinearLayout>
In looking up how 9patches are rendered, it basically turns the non-stretchable areas into default layout padding. This is to facilitate easy entry of stuff into the target (stretchable) area, without having to go in and define paddings manually. By assigning a 9patch, you are using it's padding. It assigns paddings to top left right and bottom based on how many px the 9patch has until it reaches the stretchable center.
You may try doing something like android:paddingTop="-50px" in your textView and see what happens. I haven't tested this, so I'd be interested to see how it turns out.
Edit to your comment with pic: Since your 9patch's top stretchy region doesnt start for about 90 px, its automatically going to pad the first element 90 px down, to place it within the "stretchy target" region. Try my above suggestion to see how it works, I'm pretty interested to see how it turns out. I don't have my IDE accessible from my Mobile, otherwise I'd test it for you ;)
Edit: I apologize, I've been saying "padding" instead of margin. But the theory is the same. Not modifying the above for permanent documentation of my idiocy.