I have a textview which has to use a 9-patch drawable as the background. But the 9-patch drawable has left and right paddings which make the background image not stretch properly to cover the whole text. I tried resetting the paddings for the textview itself but it doesn't fix the problem.
Would anyone have any idea how to make it work?
Thanks.
The black lines on the left and top defines the stretchable are, and those on the right and bottom marks the "content" area in a 9-patch image.
So, if you don't want padding means you want a full-length content area. You should mark full-width content area by drawing a full-length line at the bottom and right of the 9patch image.
In this image, the black lines on the right and bottom represent the content area. You can see the preview on the right side, and notice the content area in light blue color. You can fill the content area by extending the bottom and right lines.
Editing 9-patch file is not a good idea, because this method may deform the background image.
I used a trick to handle this:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<View
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/textView"
android:layout_alignTop="#+id/textView"
android:background="#drawable/your_9_patch_image"/>
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="a custom text!"/>
</RelativeLayout>
I have set the 9-patch background drawable for a View behind my TextView in a RelativeLayout. So the there is no unwanted padding :)
Theoretically you cant really change the padding of 9 patch image programatically.
So you have two options:
1) Have several 9 patch images in your drawable folder for each resolution: drawable-hdpi, drawable-xhdpi etc
2) Embed a inner layout:
<RelativeLayout
android:background="#drawable/nine_patch_image_without_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_margin="10dp" // Your padding goes here
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="How you doing"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
It worked for me. I use the second options as it is simpler and quicker to use :)
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.
Ok here is the problem...
I have a image background that need some text and additional graphics on it. The background image needs to be in the center of the screen and may not stretch. Here is what i need to do:
The problem is that i need to align the text to the background image.
I've tried to wrap it all into a relative layout - something like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bg_image"
android:layout_centerInParent="true"
android:src="#drawable/member_card"/>
<TextView
android:layout_height="wrap_content"
android:layout_alignLeft="#id/bg_image"
android:text="#string/membercard_info"
android:layout_marginTop="40dp"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignLeft="#id/bg_image"
android:layout_marginTop="200dp"
/>
</RelativeLayout>
This will not work since android adds additional padding to the image to avoid it from stretching.
Here is what happens in two different cases:
So how do I align the text to the background image?
I've solved this problem in the past in code by baking it all into one image,- but would like to do this in xml.
If you want to remove padding, you can use manually set it. However, if you want overlapping elements, you generally want to use FrameLayout. Look here: http://mobile.tutsplus.com/tutorials/android/android-sdk_frame-layout/
Set a gravity inside the frame layout to align it.
if you want an ImageView with additional layers drawn on top of that, see this thread: How to maintain multi layers of ImageViews and keep their aspect ratio based on the largest one?
There a padding around the image because you set the imageView size to fill its parent ( using match_parent )
You should try to set it to wrap its content :
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
.../>
EDIT : If your picture is bigger that the screen size, you need to have it scaled keeping the aspect ratio.
To do this, use match_parent in vertical with a scaleType to FIT_CENTER
and keep the wrap_content setting for the width ( since we want the image view left/right bounds stuck to the image content )
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:scaleType="fitCenter"
.../>
Is this better ?
I am really confused about this.I have set the background color of the whole screen to blue and I have a framelyout with image view under it. When I choose playingcard drawable as its source then the white background of the playing card is becoming blue and the image is not clear. Why is this happening?
Below is what the screen is looking like:
.
My image is :
:
And here is Part of the XML code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0000FF" >
<FrameLayout
android:id="#+id/frameLayoutBottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" >
<ImageView
android:id="#+id/ivBottom2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:src="#drawable/c11"/>
I don't want to set the background of image to white as I am using padding and I don't want the padding to be white.. The weird thing is that if I use other images that are say red then it shows perfectly, it is just when I use playing cards (I have 52 cards), it is showing like that
Any help please?
Thank you.
Your image has transparent pixels. Use an image editor to convert them to white.
Alternatively, you can specify a margin instead of padding and setBackgroundColor() on your ImageView.
I have a PopupWindow that I am using in my Activity, and everything works fine except for the padding of the elements contained within the PopupWindow - it's much too large - literally taking up most of the small PopupWindows space. Here is the XML I use to define the PopupWindow:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/homescreen_popup_bg_levels">
<TextView
android:id="#+id/x"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textSize="12dp">
</TextView>
<TextView
android:id="#+id/y"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12dp"
android:textColor="#FF000000">
</TextView>
</LinearLayout>
Here is a screenshot of the PopupWindow:
Any idea why the text is being padded down and to the right so much? I've tried adjusting the XML padding, etc but no luck.
Figured it out. The issue was indeed the padding of the 9-patch image - not including any meant the OS was guessing as to where to allow text, and pushing that text towards the center. Setting the padding element of the 9-patch images used for the background solved the issue.
Oh, and something else to note... when using a level list, it appears that Android is only looking at the padding of the first image that is loaded, then applying that to each and every image. As I am (was) using the levels to contain four asymmetric images (call-outs to the top left, right, bottom left, right), all of the images are getting the same padding, pixel for pixel, as the first one that gets loaded.
To solve this issue, I'm now simply setting the background image dynamically, rather than changing the level.
I would guess that your issue is the homescreen_popup_bg_levels drawable.
Try removing it and see what happens. If that's the issue, create a correct 9-patch.
I've got following 9patch, which I got thanks to nice people who answered my previous question:
I use it for background in relative layout and TextView and got following.
Thats for RelativeLayout:
<RelativeLayout
android:id="#+id/relativeHeader"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:orientation="horizontal"
android: background="#drawable/cap_stack">
And for TextView:
<TextView
android:paddingTop="5dp"
android:gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="22dp"
android:background="#drawable/cap_stack"
android:textStyle="bold"
android:textColor="#FFFFFF"/>
As you can see, I got 1px wide line visible in both cases. And in case of TextView text is not placed in the center vertical. How can I fix it(is it drawable problem or xml)? Will appreciate any help
You shouldn't have a solid border all the way around. The top and left borders define the stretch areas (you only need one pixel on the top for stretching, and you want JUST the gradient to stretch on the vertical axis). The bottom and right borders define the content area, so you want to leave some padding as well. The four corner pixels should never be filled.
Try this one:
or this one:
try this for your textview, the problem is your layout_height You are wanting the textSize attribute instead. Also, notice I used the SP unit instead of DP as that is what the docs recommend for text size values. I hope this helps!
<TextView
android:paddingTop="5dp"
android:gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textSize="22sp"
android:background="#drawable/cap_stack"
android:textStyle="bold"
android:textColor="#FFFFFF"/>
Did you named your image as cap_stack.9.png? It seems android is not processing it as 9patch.
android:gravity="center_vertical" works with LinearLayout Only , Use Layout_centerVertical=true for relativeLayout .
and that lines on border seems part of your image , not seeing any other possibility //////so rechecking image once might be helpful .