I am having scaling problems when using the 9-patch images for the background of EditText fields. I have a table which stretches the entire width, inside here I have the following tablerow which fills the width of the table.
The problem is that I am using a 9-patch image as the background but the edit text field is not stretching to the entire width, it only stretches to the width of the hint text.
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal" >
<EditText
android:id="#+id/et_username"
android:contentDescription="#string/hint_enterUsername"
android:hint="#string/hint_enterUsername"
android:singleLine="true"
android:textSize="#dimen/edittext_textsize"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical"
android:background="#drawable/background_field_top" />
</TableRow>
I can see in the graphical view that the width of the row does stretch but the EditText field does not, as shown in the attached image
Has anyone any ideas on how to make the edittext stretch to the entire size? The following is the 9-patch image I'm using.
From Android Developers documentation on TableRow
A layout that arranges its children horizontally. A TableRow should
always be used as a child of a TableLayout. If a TableRow's parent is
not a TableLayout, the TableRow will behave as an horizontal
LinearLayout.
#Nipun Gogia answer is not correct, why put a TableRow (behaving like a Horizontal LinearLayout) inside a LinearLayout with only one EditText child?
You should instead place the EditText view as a direct child of the TableLayout, it will then be displayed as a single row that spans all the table columns. And you can add more TableRow's and Columns if you want.
Stretch a background image of a EditText View with Nine-Patch:
You need to edit the 9-patch rule of the 9.png file setting the stretchable area of the image, place the top rule (black 1px line) in the middle of the image, now it is only stretching at the transparent end leaving the image un stretched.
Learn how to her: http://developer.android.com/tools/help/draw9patch.html
Importent! remember to save the image with the extension .9.png
Nine-patch Image saved with file extension: background.9.png
Modified smaller image, it will look the same as the above because of the nine-patch rules.
Modified image, but with a non stretchable height.
Note: if downloading the images above with "save image as..", remember to add .9.png to the file name for it to work.
your is working fine for me ..i am using my own 9 patch... here is my code :
<LinearLayout
android:id="#+id/layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal" >
<EditText
android:id="#+id/et_username"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/areanumber"
android:gravity="center_horizontal|center_vertical"
android:singleLine="true"
android:text="hello" />
</TableRow>
</LinearLayout>
here areanumber is my 9 patch image... just try to wrap your code inside linearlayout
i implemented your 9 patch image and its also working fine
Make sure that your image file name is background_field_top.9.png (make sure that the .9. is there)
I made small changes to your image, so that the corner rounding is smoother, but that is not the core issue.
If this does not help, check if the background works well without the table, to isolate if the issue is the layout or the background image.
Related
I have a layout (can be relative, linear or constraint)
with TextView aligned to parent left and then ImageView (fix width) aligned that start right to the textView.
I want the image to be rendered first and only then to render the text view.
Meaning I want the text view to be truncated according to the left space after the image was rendered.
<RelativeLayout
android:id="#+id/account_name_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginBottom="#dimen/account_menu_account_name_layout_bottom_margin">
<TextView
android:id="#+id/account_name"
style="#style/AccountDataAccountName"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:lines="1"
android:ellipsize="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
tools:text="emailisverylongaswellwewantittogettruncated#gmail.longdomain.com"/>
<ImageView
android:id="#+id/account_name_chevron"
android:layout_width="#dimen/account_menu_chevron_size"
android:minWidth="#dimen/account_menu_chevron_size"
android:layout_height="#dimen/account_menu_chevron_size"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/account_name"
android:layout_marginTop="#dimen/account_menu_chevron_top_margin"
android:layout_marginLeft="#dimen/account_menu_chevron_left_margin"/>
</RelativeLayout>
I have tried few options:
1) telling the text to be left to the image view
2) putting weight on the text view - made gap between the two elements.
3) setting minWidth to the image view - didn't help just made the imageView scale smaller.
Any idea how to render the image first and how to limit textView's width according to left width?
You can force the width on the imageView. That will prevent the textview from pushing it off the space. If you are saying you did this, please post the resulting image as that wouldn't make any sense.
Your above example has no constraints to each other, no enforcement to not overlay or push off. You need some constraints, such as "toTheLeftOf" or "Weight" or LinearLayout to enforce it as Weight only works in LinearLayout.
The easiest way is to just give the imageView a hard coded DP width and height, then set the text to 0 width with a weight of 1 inside a Linear Layout.
You can also use percentages if you want, use a LinearLayout then put a weight sum of like 100 for example (representing 100%). Then assign your image whatever percentage it needs like layout_weight=30 and give the textview 70.
Any of these options will work fine for you. If you try it, and it does not, then post your tried code as it will work unless you are doing something goofy that is not visible in your current example. As I do this all the time, every time you make a row, you typically have an image on the left fixed and text on the right to grow.
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 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 :)
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'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 .