Android drawable resources with numbers - android

I'm implementing a code-snipped in my android application, where i open a popup window. This popup window takes a little drawable and put it around itself. This png resource is named *.9.png. I can rename it as i prefer, but if i remove the 9 the output of the resource is different. With the number the png is displayed correctly; otherwise it is stretched on the entire window.
What does it mean? Does the framework do something special seeing this number. Moreover i noticed that that when this resourced is used in code or XML, the .9 has to be omitted...so i think that it is for the framework.
Could someone explain it in detail?
The code comes from the QuickAction3D package.

Yes, a *.9.png naming indicates a Nine-patch image, which is an image with annotations to modify stretching behaviour.

Related

Android Studio for Mac: Use original colour image for splash screen

I have a multi-color image that I wish to use on a splash screen. I am using a guide from here which requires specifying the image under a AppTheme.Launcher style, and using the item android:windowBackground to specify the image name through #Drawable/SplashIcon
I am stuck on how to actually add the image to the project. I have so far been adding images using the menu action new -> Image Asset which flattens the colour and doesn't seem to have an option to just import as is.
I have resorted to drag and drop onto the drawable folder in Android Studio, which adds the image, but I cannot reference it using Drawable/SplashIcon.
Here is what I have:
How do I reference my image?
Seems like it is an issue with the file name. Have to use lowercase letters and underscores for the file name, nothing else.
I therefore drag and dropped my image with the name splash_icon.png and it's now appearing under #drawable/...
I am also now using the different pixel densities too, as recommended.

9patch image and Android Studio build failing

I have an interesting issue, and I dont know how to handle it.
So, until now everything was fine, I was able to build my project. I just replaced an image with it`s 9patch version in three different sizes(mdpi, hdpi, xhdpi).
tw.setBackgroundResource(R.drawable.tag_rotate)
This is the line, where the building failing. It`s interesing, because the studio is able to show me the image on the left, and it is NOT marked as red. But the build is failing with the following message:
Error:(196, 52) error: cannot find symbol variable tag_rotate
UPDATE:
if I remove the image from the code, and replace with a normal image, it works ! Im using the default 9patcher provided by SDK
What kind of nine-patch generator do you use?
I recomend you to use this generator.
I tried to use standart android 9patch generator, which delivered with android SDK, and I had the problems with it.
Check if there is a line on your imports that says import android.R;.
If there is,Delete the import and it should be fine.
The Draw 9-patch tool is a WYSIWYG editor that allows you to create bitmap images that automatically resize to accommodate the contents of the view and the size of the screen. Selected parts of the image are scaled horizontally or vertically based indicators drawn within the image.
http://developer.android.com/tools/help/draw9patch.html
Nine-patch generator
https://android-ui-utils.googlecode.com/hg-history/9472134d092f3375aa9cf767d6a4b2eca561c0ba/asset-studio/dist/nine-patches.html
If you are make online generator tools then Don't use the any special character for image name
The 9 patch tool in android studio is automatically generating bad patches.
You need to repatch till the red bad patches go away and the error should be fixed. To see bad patches just select the Show bad patches checkbox.

nine-patch images with 1px width or height -- special case or faulty files?

In the process of altering the images found in Launcher2.apk, I found some files that are obviously nine-patches, but have a height or width of 1px only:
$ file **/*.9.png G "\( 1 x\|x 1,\)"
Launcher2/res/drawable-land-xhdpi/workspace_bg.9.png: PNG image, 400 x 1, 8-bit gray+alpha, non-interlaced
Launcher2/res/drawable-sw720dp-xhdpi/workspace_bg.9.png: PNG image, 1 x 400, 8-bit gray+alpha, non-interlaced
Launcher2/res/drawable-xhdpi/workspace_bg.9.png: PNG image, 1 x 400, 8-bit gray+alpha, non-interlaced
Are these files that are messed up somehow by their creators or are they special cases, i. e. fixed width but variable height or vice versa?
Is there any formal definition of the format of nine-patch files? Of course I googled, which took me quite some time, without finding any information that would help me here. Would be best if it'd also cover other aspects, because I found many other
suspicious images in several packages that contain none-binary information in there left-/top-/right-/bottom-most pixels; hence I'd also like to know exactly which values encode repeat/stretch/as-is, and which are ignored.
This section in Googles Canvas and Drawables document doesn't give many details (actually none). and the distributed draw9patch.jar doesn't help much either.
Just in case it is of interest: The device I took Launcher2.apk and other packages from is a Moto G, stock 4.3 firmware.
Thanks in advance
Okay, what I learned since I investigated more on nine-patch images:
The main error is probably to think that the repeat/stretch/keep meta data of nine-patches are always encoded in the border pixels of the image files. This is not true.
As a matter of fact, there are two nine-patch formats, apparently called source form and compiled form, the former having the well-known special borders in which pixels specify the patches (of which you can have more than nine, indeed). This is most likely called source form, because the pixels show off in image editors (however, under some circumstances they may not; see below).
According to the apktool wiki the second — compiled — form has this meta information encoded in a special (private) PNG chunk; the same page claims those chunks are called npTc, and my attempt to verify this with basic Linux utilities could confirm this:
$ strings search_frame.9.png
IHDR
TnpTc
yIDATX
[...]
Also TweakPNG shows this chunk.
So, the answer to my actual question is: I thought those 1 pixel high/wide images were nine-patches in source form, while they actually were in the compiled crunched format.
Since there doesn't seem to be an official specification, and this was part of the question, I'm just starting a collection of information here.
Tools that convert from one form to the other
aapt (coming with the Android sdk) has, among others, two subcommands,
s[inglecrunch] compiles a single bordered nine-patch image to the chunked/crunched format (use command line options -i and -o for input and output file, respectively),
c[runch] takes a resource directory (option -S) and the name of an output directory (option -C), traverses the whole source directory and creates target subdirectories as appropriate.
(Be warned: if you forget to create the root of the target directory tree beforehand, aapt doesn't error out, but is busy with $whatever, taking a whole CPU core/thread's attention and power, so effectively showing that it's busy, while it does at least not what the user expects. (Just for the sake of completeness: I'm running SDK 19.0.1))
apktool is a custom java application that is able to unpack whole *.apk files, converting *.xml files to plain text files and *.9.png files to their source format.
To put everything (potentially modified) back into an *.apk archive, you'd need to manually extract some files from the original package, which most zip/unzip utilities should be able to do, but without conversion. For the process of repackaging, apktool apparently makes use of aapt, of which it has a version bundled.
This bundled aapt is probably extracted from an older SDK (pre 19), as it shows off the same flaws (the above mentioned tight busy loop, and several segfaults where a simple if would prevent such nasty behaviour (e. g. it segfaults when you don't give the -C option to the c[runch] subcommand)), while it lacks support for the s[ingleCrunch] subcommand.
xUltimate-d9pc (this seems to be a source-to-crunched-format converter, but I didn't really test it.)
WebLaF (also untested; it seems to have sources, where one could get more info.)
Formats of nine-patches
source form
Most people will already know that the source form of a nine-patch does include the normal pixel data of the image, plus an extra border. I will try to illustrate with a simple ASCII representation (and hope your font allows to recognize what it means):
-------##--#####--##-------
-......XXXXXXXXXXXXX......-
-...XXX.............XXX...-
-..X...................X..-
-.X.....................X.- Legend
-.X.....................X.-
#X.......................X- (top and left borders)
#X.......................X- # denotes a "stretch"/"repeat" mark
-X.......XXXXXXXXX.......X- - denotes a "keep" mark
-X.......X.......X.......X#
#X.......X.......X.......X# (bottom and right borders)
#X.......X.......X.......X# # marks the content area (aka fill area)
-X.......X.......X.......X# - marks ... umm... what is it called?
-X.......XXXXXXXXX.......X-
#X.......................X- (image area)
#X.......................X- . pixel in "background" color
-.X.....................X.- X pixel in foreground color
-.X.....................X.-
-..X...................X..-
-...XXX.............XXX...-
-......XXXXXXXXXXXXX......-
----------#######----------
This is some kind of double box, the outer of which has rounded corners. The size of this form of nine-patch is 27x22px, but the actual image size is 25x20px only — this is also the minimum size at which it can be shown in an app, but it can be stretched to an arbitrary size.
The repeat marks tell the framework which lines to repeat when the image is stretched, e. g. when the image is shown at an actual height of 26 pixels, lines 7, 8, 11, 12, 15, and 16 and repeat, each once, making up for the extra lines on the screen. This way it is ensured that the borders of both boxes will always remain 1 pixel thin and the rounded corners of the outer one will always have the same size/radius. while the marked regions will be adequately stretched (well if the difference of the stretched size to the original size is not a multiple of the marked lines, there will be irregularities, but on today's 160+ dpi display that doesn't probably matter much; however, less repeat/stretch markers will probably be more performant, but then again... on today's 1.6+ GHz quad core phones that doesn't matter either...)
Values for the repeat/stretch markers
When I posted the question, I wasn't sure whether there is any semantic difference between stretching and repeating, and I still am not.
According to A simple guide to 9-patch for Android UI the markers must be solid black for repetition of the row/column in question, otherwise the result will be wrong without any notice to the user except when incorrectly displaying on the screen; this may be correct for previous SDK versions (the article being from May 2011).
However, both aapt versions (in SDK 19 and the one coming with apktool 1.5.2) complain about arbitrary colors in the borders, for example:
ERROR: 9-patch image test/search_frame_.9.png malformed.
Ticks in transparent frame must be black or red.
Found at pixel #21 along top edge.
ERROR: 9-patch image test/tab_unselected_pressed_focused_holo.9.png malformed.
Must have one-pixel frame that is either transparent or white.
where the second file is a compiled/crunched nine-patch already, while the first is not.
What I read from the "black or red" message is that the border may not contain pixel values other than #00000000 (solid black, for repeat/stretch marks), #00ff0000 (solid red, maybe for the same), and #xx000000 (black with arbitrary transparancy (xx>0) for "keep" marks, maybe also #xxFF0000, but I didn't test that).
What I'm still not sure about is whether red and black have distinct semantics, or if red is just an alternative for image editors that use a black background, where it's not easy to visually distinguish between #00000000 and #01000000, for example).
compiled/crunched form
The SDK contains two classes android.graphics.NinePatch and android.graphics.NinePatch_Delegate, which make use of calls to native libraries, so the sources don't give us much. I don't have the NDK installed and I even don't know if it supplies sources for the relevant libraries.
The best that I've found was the answer to Android: compiling 9-patch files to be used outside of the drawable folder?

Puzzled Over Android App Graphic Source Path

I've had an app developed and have the responsibility of maintaining it, which means learning the Eclipse ADT environment. Nearly 20 years in web dev gives me some comfort, but this is certainly a new experience.
In one of the screens shown in the Graphical Layout window, a graphic source is indicated in the Properties panel as:
Src #drawable/ordo_search
ordo_search, obviously being the name of the PNG graphic, drawable appearing to be the folder.
But there are 4 folders holding graphics for this app, all beginning with the word drawable. They are:
drawable
drawable-hdpi
drawable-large-mdpi
drawable-sw600dp-hdpi
By altering this particular image and seeing the change come up in the Graphical Layout, I've determined that this graphic resides in the one called drawable-sw600dp-hdpi. In other areas of the app, I've determined in the same way that graphics are being pulled from any of the 4 folders, but in all cases the properties source paths all read the same: #drawable
Somewhere that #drawable attribute is being told an absolute path to where that graphic is, and that's what I need to find: where would I find and edit the path to that, or any, graphic?
Obviously I'm just getting to know the environment, so bear with me if you would.
It's not possible to get the path
This path will differ from device to device due to different dpi's of devices, it can point to any of the 4 folders you defined. If you want the drawable image you can get it via code by using getResources().getDrawable(R.drawable.yourdrawablename);
This will return your drawable and you can use it to display in a ImageView or where ever you want.

To create Nine patch drawable in Android?

I want to set a specific background image for all my buttons.
So, I changed my PNG file into a Ninepatch drawable using the "draw9patch" tool(by specifying the line of strecth).
Then, I applied this as background to my button using
"myBtn.setBackgroundResource(R.drawable.new_png);"
Now, the background appears for the button, but the lines of stretch are also visible on the android screen, wherever I'd specified them in the tool.
Can you help? Is there something wrong in how I'm using the tool?
Ninepatch png files must be named with a special naming convention: for instance in your example, new_png.9.png. When you refer to the drawable in your code, you exclude the '.9.png', so your code would not need to change, only the image file name needs to change.

Categories

Resources