I am using a nine patch image as a drawable for a selector's item element.
The nine patch image is here:
The image that finally gets rendered is this (emulator & device screenshot, both device have resolutions > mdpi):
As you can see, it has been scaled outside the stretchable area (as defined in the 9 patch file), the darker green bar is much thicker as it should be.
Why is that and can it be avoided? The draw9patch tool scales this image correctly. Does it have to do with Android trying to preserve physical dimensions on high resolution devices?
Do you only provide a mdpi version of the image?
Android scales all images that aren't available in the correct pixel density. This happens before the image is scaled via 9patch.
This would mean that your image gets scaled up to fit hdpi and then scaled to fit the content.
To fix this, you have to provide hdpi and xhdpi versions of your image. 9patch isn't supposed to target different pixel densities and rather different content/screen sizes.
I checked out your 9 patch:
Why did you color your not used bounds white? It should be transparent.
Because of this it is not recognized as a 9Patch:
Related
On iOS, you can specify #2x images that will be used in places where the pixel density (UIScreen scale) is greater than 1. You still refer to logical pixels, but the images will display using the actual physical pixels (which are usual 4x the logical pixels).
On Android, it seems like using dp to specify dimensions has a similar effect. For example, a layout such as the following
<TextView
android:layout_width="50dp"
android:layout_height="25dp"
android:id="#+id/MessageTextView"
android:background="#drawable/messageBackground" />
If the image messageBackground is a higher resolution than 50x25, the platform scales it appropriately when displayed on a screen with higher density, using the additional pixel information to fill the increased pixels. (At least that is how it appears to me).
My question, however, relates to nine patched images. These are the images that stretch based on the actual size that they are displayed over.
nine patched images I have not been able to figure out how to make them 'scale up' on higher density screens. As you'd expect, the expandle portion of the nine patch stretches to make an image larger. But the 'fixed' portions of the nine patch are just displayed using dp pixels, not actual pixels.
Is there a way to use a higher res image with nine patch, such that the 'fixed' portions of the image display at the full resolution of the device? I don't want the higher res version to just appear larger, I want it to display it's natural size using all the available pixels for the best possible image.
Is there a way to use a higher res image with nine patch, such that the 'fixed' portions of the image display at the full resolution of the device?
Yes. See Providing Resources and Supporting Multiple Screens documentation on the Android developers site.
You need to create your resources at multiple resolutions, then you simply drop them into the appropriate drawable folders for that density bucket.
Essentially, the drawables-mdpi folder is the one to use for your standard 1x resources. drawables-xhdpi is your 2x. You probably want to provide your drawables at mdpi, hdpi, xhdpi, and xxhdpi to provide appropriate quality resources for the vast majority of Android devices.
I got this image and i need to make 9 patch of it (i am using it for textview background).
I need the text to appear text to left of star like this:
I tried this but with no success:
Is this even possible or do i have to use something else than 9 patch?
Your use-case is exactly what 9-patch was invented for, so it should work!
Here are some common errors that might occur while using nine-patches:
Did you make your image with the draw9patch-tool ? Making it in photoshop or another photo-editing app, it is possible that the outer pixels are not completely white or black.
Is your filename correct ? (ending in .9.png)
If you put your nine-patch image in a resource-folder with a larger density then the device's density you are testing on, the image is probably scaled down and one of your black-pixels (on the left or the top) are removed.
You can solve this by either
Providing nine-patches for all densities (ldpi, mdpi, hdpi, xhdpi) (bold ones are the most common ones) <-- Preferred!
Make your nine-patch for xhpdi and draw a minimum of 2 black pixels. Because when scaling down from xhdpi to mdpi, your image is scaled down with a factor of 2, so if you only draw 1 black pixel in xhdpi, it might be removed when scaling down.
Hope this works for you.
I have a an image of a text field that I want to put as the background of my text field. I made a nine slice image so I can change the size of the image but retain the integrity of the corners. I have this image in my drawable xhdpi and I want to use the same image in my hdpi and mdpi. I need to do this for multiple images in my app so I do not want to have to make a nine slice image for each pixel density. When I drag my nine slice into photo shop to change the size of the image the black lines above and to the sid of the text box are now in the image, not a pixel above/left of my image. Is there any way that I can scale my nine slice? Or do I have to make a nine slice for each pixel density?
Rule of Thumb: When you scale your images for each density, watch out for aliasing problems even when the height and width are in integer multiples.
That is: make a nine slice for each pixel density to be safe as your black dots/lines may get cut out.
If you want to use the same image for all of them, just create a new folder in res called drawable-nodpi, and it'll use that same image for all densities with no scaling. That's what I do for the majority of my 9-patches if the borders are pretty thin. If you have borders intended to be thick on an xhdpi device, keep in mind they'll appear much thicker on an mdpi device if you use the same one. If that's not an issue, go for the nodpi approach, in my opinion.
Scaling an image with Photoshop will either remove or add pixels to the image. When it does that it will change the scale/fill guides so they are no longer 1 pixel wide and solid black. To avoid this crop your image to remove the guides before you scale the image then add them back in.
Or you can convert 9-patch
images to the other resolutions using this Google 9-patch tool.
When 9patch png images are used, do we need to provide them in xhdpi, hdpi and mdpi format also or only one resolution is enough? Because either way they will resize on resolution... or am I thinking something wrong?
You should use different sizes, otherwise a border on a LDPI device would look much thicker than on an XHDPI device
For the Nine patch image only one resolution is enough because 9-patch image scales the image text according to the layouts...
Nine-patches are widely used for background kind of images: most typically it would be some sort of border and a fill. You should provide only one resolution of 9patch, Android would scale it appropriately.
I am creating an android application in which I want multiple screen support.For these I have used 9 patch images.
But my question is this whether using 9 patch images will be enough for different-2 density's devices or I will need to create different-2 9 patch images for varying densities(like mdpi,ldpi,hdpi).
Thanks in advance
I recently found out myself in the same situation so let me pitch in and expand on what has been said already...
Yes, 9-patch images will scale, that's what they exist for. But if you should use a 9-patch image for all screen densities, that depends on the image really. 9-patch images are more commonly used, for instance, buttons. You can have different sized buttons in your app and a 9-patch image will help deal with them, no matter how you size your button (as long as the 9-patch image is properly created).
But let's say your button design has some really round corners for the hdpi version. You create your 9-patch image without messing the corners but when you look at it in the ldpi version, you'll realize your corners are too big for that low resolution. For this situation, you'll need a different 9-patch image with less round corners, that look better on that resolution.
So, the final answer is, it really depends on your image. If you can create a 9-patch image that looks good in all densities, than fine, use it, as you only need one image to handle all densities. But if it doesn't look good, because of corners, gradients, or whatever, than you'll need one 9-patch image for each screen density.
Hopefully it's clearer now.
From documentation: nine patch
A NinePatchDrawable graphic is a stretchable bitmap image, which Android will automatically resize to accommodate the contents of the View in which you have placed it as the background. An example use of a NinePatch is the backgrounds used by standard Android buttons — buttons must stretch to accommodate strings of various lengths. A NinePatch drawable is a standard PNG image that includes an extra 1-pixel-wide border. It must be saved with the extension .9.png, and saved into the res/drawable/ directory of your project.
the answer is no. you nine patch will scale between different screen size
Short answer is YES.
Check this:
By default, Android scales your bitmap drawables (.png, .jpg, and .gif files) and Nine-Patch drawables (.9.png files) so that they render at the appropriate
physical size on each device. For example, if your application provides bitmap drawables only for
the baseline, medium screen density (mdpi), then the system scales them up when on a high-density
screen, and scales them down when on a low-density screen. This scaling can cause artifacts in the
bitmaps. To ensure your bitmaps look their best, you should include alternative versions at
different resolutions for different screen densities.
from Android Developer Official Doc