Skip to content Skip to sidebar Skip to footer

Building A 9 Patch Drawable At Runtime

I am successfully building a 9patch drawable at runtime on Android 3.0+ using the excellent gist provided by Brian Griffey (found here). Essentially I load the raw (no patches) gra

Solution 1:

It's working for me after I updated the code. I think the color size made it unhappy for some reason(Based on the comments in the android source code each patch has a color hint, setting fewer than the number of sections in this case 9 appears to cause problems). I haven't tested with your image yet.

public static NinePatch createFixedNinePatch(Resources res, Bitmap bitmap, int top, int left, int bottom, int right, String srcName){
    ByteBuffer buffer = getByteBufferFixed(top, left, bottom, right);
    NinePatch patch = new NinePatch(bitmap, buffer.array(), srcName);
    return patch;
}

public static ByteBuffer getByteBufferFixed(int top, int left, int bottom, int right) {
    //Docs check the NinePatchChunkFile
    ByteBuffer buffer = ByteBuffer.allocate(84).order(ByteOrder.nativeOrder());
    //was translated
    buffer.put((byte)0x01);
    //divx size
    buffer.put((byte)0x02);
    //divy size
    buffer.put((byte)0x02);
    //color size
    buffer.put(( byte)0x09);

    //skip
    buffer.putInt(0);
    buffer.putInt(0);

    //padding
    buffer.putInt(0);
    buffer.putInt(0);
    buffer.putInt(0);
    buffer.putInt(0);

    //skip 4 bytes
    buffer.putInt(0);

    buffer.putInt(left);
    buffer.putInt(right);
    buffer.putInt(top);
    buffer.putInt(bottom);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    buffer.putInt(NO_COLOR);
    return buffer;
}

Solution 2:

Putting together all I've spotted so far, and honing it a bit:

  • There doesn't seem to be a difference in the Res_png_9patch structure (which the byte chunk goes into) between android versions (see http://code.metager.de/source/xref/android), so that doesn't look like the cause.

  • Other answers about nine patch drawables suggest that each region (especially stretchable ones) should be at least 2x2 pixels (if not 3x3), but outside of that smaller is better.

  • However, the way some of the byte chunk is allocated looks like it could be updated. Try setting the 4th byte to 9 (the number of patches, I think), adding 7 more NO_COLORs to the the end and moving its size up to 56 + (7 x 4) = 84 bytes


Solution 3:

Looks like working with 9patches is described in depth on SO already - Create a NinePatch/NinePatchDrawable in runtime


Solution 4:

Not really an answer to the question, but a useful workaround...

I've always found working with 9-patch files at runtime to be hairy. I have been successfully able to use FrameLayouts and automatic resizing of text to accomplish my desired effects. If your app will just be using this 9-patch, and not specifically allowing the user to download it as an image (an android 9-patch image generator, so to speak), I would advise you to look into that.


Post a Comment for "Building A 9 Patch Drawable At Runtime"