Android开发——网络加载点9图
开发需求:有一个进场动画背景图,会根据不同的活动显示不同的背景,但是你面的内容大小不确定,而且需要灵活的显示且不能变形。
思路一:如果我们把所需的背景图片都切好放本地,根据需求来指定选择。问题:如果图片需要修改,需要增加,则会造成无法及时体现。
思路二:承接思路一,我们可以使用网络加载来灵活显示,这样减少了代码逻辑,也能及时更新切不需要发版。很多时候我们用的可能会由于内容过多而造成变形,此时我们就会想到用点9图。
一、我的都知道点9图格式是(xxx.9.png)这种格式,如果我们直接这样上传到服务器,然后客户端进行加载显示其实是不会有自适应效果的,所以我们这需要先将点就图处理成正常的使用格式:
我们使用Android SDK的build-tools下到工具来处理,打开命令行来处理吧,如下:
1、点9图转换:找到转化工具路径(这个路径是我本人的电脑SDK安装路径)
C:\Users\87250\AppData\Local\Android\Sdk\build-tools\28.0.3>
//单张图片转换,命令:aapt s -i 点9图路径 -o 转换后的图片输出路径
aapt s -i D:\entershow_shengdan.9.png -o D:\entershow_shengdan2.png
//图片文件的批量转换,命令:aapt c -v -S 文件夹路径 -C 转换后的图片文件夹的输出路径
aapt c -v -S D:\res -C D:\res\9out
由上面的步骤转化后我们就可以拿到转化后的点9图了,这样就可以上传到服务器然后我们进行加载了。
2、我们一般加载都是用Glide,这里就用glide演示代码吧,此外,我们不一定是处理ImageView,也可以处理用来加载跟布局的背景,我这边主要是处理父布局的,因为需要内容自适应填充切样式灵活,话不多说直接贴一个我些的工具类代码吧
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.NinePatch;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.os.Build;
import android.view.View;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* author :
* time :
* desc :
* version:
*/
public class LoadDian9TuUtil {
public static void loadDian9Tu(Context context, View imageView, String imgUrl) {
if (context == null) {
return;
}
if (context instanceof Activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (((Activity) context).isDestroyed()) {
return;
}
}
}
Glide.with(context)
.asFile()
.load(imgUrl)
.into(new CustomTarget<File>() {
@Override
public void onResourceReady(@NonNull File resource, @Nullable Transition<? super File> transition) {
try {
FileInputStream is = new FileInputStream(resource);
setNinePathImage(context, imageView, BitmapFactory.decodeStream(is));
is.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
public static void setNinePathImage(Context context, View imageView, Bitmap bitmap) {
if (bitmap == null)
return;
byte[] chunk = bitmap.getNinePatchChunk();
if (NinePatch.isNinePatchChunk(chunk)) {
NinePatchDrawable patchy = new NinePatchDrawable(context.getResources(), bitmap, chunk, NinePatchChunk.deserialize(chunk).mPaddings, null);
imageView.setBackground(patchy);
}
}
}
代码其实很简单,不需要过多过多的注释。
最后贴一个 NinePatchChunk 这个处理类
import android.graphics.Rect;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class NinePatchChunk {
public static final int NO_COLOR = 0x00000001;
public static final int TRANSPARENT_COLOR = 0x00000000;
public final Rect mPaddings = new Rect();
public int mDivX[];
public int mDivY[];
public int mColor[];
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 RuntimeException("invalid nine-patch: " + length);
}
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()];
checkDivCount(chunk.mDivX.length);
checkDivCount(chunk.mDivY.length);
// 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;
}
}
最后:不生产代码,但我们也可以做一个实用的搬运工~谢谢