Android 点九图机制讲解及在聊天气泡中的应用

本文探讨了Android点九图在部分设备上padding失效的问题及其解决方案,以及动态下载点九图导致聊天气泡闪烁的处理办法。通过解析NinePatchChunk源码,详细解释了点九图的工作原理,并提供了构造NinePatchDrawable的方法。文章最后分享了如何在运行时创建点九图。
摘要由CSDN通过智能技术生成

点九图的 padding 在部分手机上面失效

这个是部分 Android 手机的 bug,解决方法见:https://stackoverflow.com/questions/11065996/ninepatchdrawable-does-not-get-padding-from-chunk

public class NinePatchChunk {

private static final String TAG = “NinePatchChunk”;

public final Rect mPaddings = new Rect();

public int mDivX[];

public int mDivY[];

public int mColor[];

private static float density = IMO.getInstance().getResources().getDisplayMetrics().density;

private static void readIntArray(final int[] data, final ByteBuffer buffer) {

for (int i = 0, n = data.length; i < n; ++i)

data[i] = buffer.getInt();

}

private static void checkDivCount(final int length) {

if (length == 0 || (length & 0x01) != 0)

throw new IllegalStateException("invalid nine-patch: " + length);

}

public static Rect getPaddingRect(final byte[] data) {

NinePatchChunk deserialize = deserialize(data);

if (deserialize == null) {

return new Rect();

}

}

public static NinePatchChunk deserialize(final byte[] data) {

final ByteBuffer byteBuffer =

ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());

if (byteBuffer.get() == 0) {

return null; // is not serialized

}

final NinePatchChunk chunk = new NinePatchChunk();

chunk.mDivX = new int[byteBuffer.get()];

chunk.mDivY = new int[byteBuffer.get()];

chunk.mColor = new int[byteBuffer.get()];

try {

checkDivCount(chunk.mDivX.length);

checkDivCount(chunk.mDivY.length);

} catch (Exception e) {

return null;

}

// skip 8 bytes

byteBuffer.getInt();

byteBuffer.getInt();

chunk.mPaddings.left = byteBuffer.getInt();

chunk.mPaddings.right = byteBuffer.getInt();

chunk.mPaddings.top = byteBuffer.getInt();

chunk.mPaddings.bottom = byteBuffer.getInt();

// skip 4 bytes

byteBuffer.getInt();

readIntArray(chunk.mDivX, byteBuffer);

readIntArray(chunk.mDivY, byteBuffer);

readIntArray(chunk.mColor, byteBuffer);

return chunk;

}

}

NinePatchDrawable patchy = new NinePatchDrawable(view.getResources(), bitmap, chunk, NinePatchChunk.getPaddingRect(chunk), null);

view.setBackground(patchy);

动态下载点九图会导致聊天气泡闪烁

  1. 这里我们采取的方案是预下载(预下载 10 个)

  2. 聊天气泡采用内存缓存,磁盘缓存,确保 RecyclerView 快速滑动的时候不会闪烁


理解点九图


以下内容参考腾讯音乐的 Android动态布局入门及NinePatchChunk解密

回顾NinePatchDrawable的构造方法第三个参数bitmap.getNinePatchChunk(),作者猜想,aapt命令其实就是在bitmap图片中,加入了NinePatchChunk的信息,那么我们是不是只要能自己构造出这个东西,就可以让任何图片按照我们想要的方式拉升了呢?

可是查了一堆官方文档,

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值