9-patch drop shadow disappears when image nears the edge - android

I'm using 9-patch to produce drop shadow for a box. If the image width is at 280dp (20dp off the edge of the box), I get a good drop shadow (#315 degrees):
However, if I make the image touch the box edge, the shadow on the right edge almost disappears:
Here's my layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#drawable/dropshadow">
<ImageView
android:id="#+id/frontimage"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_alignParentTop="true"
android:scaleType="center"
/>
...
</RelativeLayout>
Here's the 9-patch I'm using:
Does anyone know why this is happening?
Thanks!

Reduce your top and left black border to 1 px (the stretchable area).
Like so:
Optionally, you can also reduce the right and bottom black border by some pixels (to introduce some padding).
Like so:
Optionally, you can add some blank (transparent) space (let's say 4px per side) between the image (shadow included) and the black borders.
This will add some padding.
OR
You can add some padding to your RelativeLayout

Related

How do I make my TextView positioning responsive?

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.

How to remove paddings in a 9-patch background for textview

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 :)

Content area defined in 9 patch image doesn't work for custom view

Currently, I have a custom view BarChart. I wish to have some red shadowing effect on it. I'm using nine patch image technique to achieve so.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="240dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/card_background_red"
android:orientation="vertical"
android:padding="0dp" >
<org.yccheok.jstock.gui.charting.BarChart
android:id="#+id/bar_chart"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
In my custom view, there is line of code, where I will draw string at the end-y of the view.
// Drawing string at end-y of BarChart custom view.
canvas.drawText("2007", x0, getHeight(), textPaint);
canvas.drawText("2008", x1, getHeight(), textPaint);
I avoid my custom view from "touching" any of the red shadow, I define my content area of 9-patch, so that it doesn't touch the red shadow.
As you can see, the content area are pretty much stay away from red shadow.
I thought my drawn text will never touch the red shadow area, as I restrict my content area (entire custom view?) stay away from red shadow area. However, it doesn't work.
Am I having wrong expectation on the content area of 9 patch image? I thought Linear Layout's "content" is my custom view BarChart. Hence, BarChart shouldn't be touching the red shadow as specific in 9 patch image. (http://www.shubhayu.com/android/9-patch-image-designers-vs-developers)
Remove android:padding="0dp" from LinearLayout. It overrides padding from 9-patch.

Margin/Padding Shrinks ImageView

I recently tried to position an imageview's x and y coordinates with no luck, it seems there is no way to do it in Gingerbread. I then decided to try out paddings and margins, but when I set them, it shrinks my imageview. I set a left padding of 250dp and image view became tiny. The layout_height and width are set to wrap_content. I'm not sure what's going on. Does anyone know why setting a padding/margin would shrink an imageview?
You're confusing margin and padding. Margin is the area outside of your view, while padding affects the content inside your margin.
If you set padding, then it is going to affect your available content area, and assuming you have a ScaleType set, it's going to shrink your image down to fit the available space.
Now, you say you've tried margins, but margins will do exactly what you're asking.
For example, if you wanted an ImageView placed 10dp from the top-left corner, you can 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/my_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:src="#drawable/my_image_id"
/>
</RelativeLayout>
Keep in mind that this places it 10dp with respect to the parent boundaries. If your parent layout also has padding, then that will affect your content placement.
if by shrink you mean the picture's ratio is messed then you should use
android:scaleType="centerInside"
this will prevent the ratio from changing

ImageView within RelativeLayout has top and bottom padding

I have a 640px wide, 208px tall PNG that I've placed in my /drawable folder and I'm having a very hard time properly placing it in an ImageView. I want to scale the image so that it maxes out the horizontal resolution, and I want it to scale vertically only as much as it takes to stay in proportion.
The problem I am having is that my ImageView ends up taller than it needs to be to fit the image. The image itself looks perfect; as wide as the screen and in proportion. But the ImageView appears to have padding on the top and bottom. From what I can tell it's the drawable that the ImageView contains that's actually too tall.
I can't post an image because I'm new to SO, but if I did it would be of the Graphical Layout view. When I click on the ImageView the regular blue box shows up around it, but with padding on the top and bottom, the same padding I'm seeing on the device. Even if I drag the blue box to attempt to resize the ImageView, I am not allowed to make it any smaller than it already is (perhaps because the ImageView thinks the drawable is that tall, or something). From what I can tell, this may have something to do with the density of the image...the ImageView ends up being 312 pixels tall (208*1.5) on an hdpi device.
Here is 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="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/back" android:src="#drawable/categoryheader2"
android:layout_width="wrap_content" android:layout_height="wrap_content">
</ImageView>
</RelativeLayout>
Thanks in advance for any help!
I guess android:adjustViewBounds="true" on the ImageView should do the trick. I recently had a similar problem, when I was trying to scale an image to fit the whole width of the view without loosing its proportions.
did you tried the tag : android:scaleType="fitXY" or android:scaleType="centerCrop" on your ImageView ?

Categories

Resources