Building a 9 patch drawable at runtime

后端 未结 4 1149
伪装坚强ぢ
伪装坚强ぢ 2020-12-08 23:10

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 (

相关标签:
4条回答
  • 2020-12-08 23:19

    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;
    }
    
    0 讨论(0)
  • 2020-12-08 23:28

    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

    0 讨论(0)
  • 2020-12-08 23:35

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

    0 讨论(0)
  • 2020-12-08 23:35

    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.

    0 讨论(0)
提交回复
热议问题