Android Tutorial Nine patch images tutorial

Android supports a special format of PNG images that can be resized by replicating specific parts of the image.
This images also include padding information.
These images are named nine-patch images.

You can read more about this format here: Canvas and Drawables | Android Developers

For example the following three labels use the same background nine-patch image:

SS-2012-01-22_12.19.33.png


Android SDK includes a tool named draw9patch.bat that can help you with building and modifying such images. This tool is available under: <android-sdk>\Tools
You can read more about it here: Draw 9-patch | Android Developers

The following steps are required to use a nine patch image as a view background:
- Copy the image to <project folder>\Objects\res\drawable
- Set the image to be read-only (otherwise it will be deleted during compilation).
- Add the following sub to your code (requires Reflection library):
B4X:
Sub SetNinePatchDrawable(Control As View, ImageName As String)
   Dim r As Reflector
   Dim package As String
   Dim id As Int
   package = r.GetStaticField("anywheresoftware.b4a.BA", "packageName")
   id = r.GetStaticField(package & ".R$drawable", ImageName)
   r.Target = r.GetContext
   r.Target = r.RunMethod("getResources")
   Control.Background = r.RunMethod2("getDrawable", id, "java.lang.int")
End Sub

For buttons you can use this sub which creates a StateListDrawable from two nine-patch images:
B4X:
Sub SetNinePatchButton(Btn As Button, DefaultImage As String, PressedImage As String)
   Dim r As Reflector
   Dim package As String
   Dim idDefault, idPressed As Int
   package = r.GetStaticField("anywheresoftware.b4a.BA", "packageName")
   idDefault = r.GetStaticField(package & ".R$drawable", DefaultImage)
   idPressed = r.GetStaticField(package & ".R$drawable", PressedImage)
   r.Target = r.GetContext
   r.Target = r.RunMethod("getResources")
   Dim sd As StateListDrawable
   sd.Initialize
   sd.AddState(sd.State_Pressed, r.RunMethod2("getDrawable", idPressed, "java.lang.int"))
   sd.AddCatchAllState( r.RunMethod2("getDrawable", idDefault, "java.lang.int"))
   Btn.Background = sd
End Sub

Now you should use this sub to set the views backgrounds:
B4X:
Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("1")
   SetNinePatchDrawable(Label1, "label_bg")
   SetNinePatchDrawable(Label2, "label_bg")
   SetNinePatchDrawable(Label3, "label_bg")
End Sub

Tips
- Don't modify the image files located under res\drawable directly with the draw9patch tool. It removes the read-only attribute and then the image will be deleted.
- The image name is case sensitive.
- After adding a new image you should clean the project by choosing Tools - Clean Project. This causes a generated file (R.java) to be recreated and include the new resources.

An example is attached.
 

Attachments

  • NinePatchExample.zip
    7.4 KB · Views: 2,675

M. Giray Ozkan

Member
Licensed User
Longtime User
Dear @Erel

I've some trouble with spinner background. When I try to change spinner background with the bordered 9 patch image via using SetNinePatchDrawable function, I dont see any text of my spinner. (initial text or after select text)

How can I do?

Thanks

1.png 2.png 3.png 4.png
 
Top