一般来说动态图片使用gif,但是gif图片的缺点是有白边,因此apng格式动态图片是更好的选择
由于Android原生并不支持apng图片,可以使用第三方支持框架 https://github.com/aellerton/japng_android
使用方法也简单
播放apng
Drawable d = PngAndroid.readDrawable(this, R.drawable.rotating_logo);
ImageView iv = (ImageView)findViewById(R.id.view_render_image);
iv.setImageDrawable(drawable);
if (drawable instanceof AnimationDrawable) {
((AnimationDrawable)drawable).start();
}
停止播放
((AnimationDrawable)drawable).stop();
这是我使用的APNG工具类,导入japng框架后可以使用该工具类
/**
* Created by TonyYang on 2017/1/17.
* APNG工具类
* 支持同时播放多个apng
*/
public class APNGUtil {
private String TAG = "APNGUtil";
private static APNGUtil instance;
private Map<Integer, Drawable> drawableMap = new HashMap<>();
public static APNGUtil getInstance() {
if (instance == null) {
instance = new APNGUtil();
}
return instance;
}
/**
* 设置apng到imageview对象
*
* @param drawable
* @param imageView
*/
private void setDrawable(Drawable drawable, ImageView imageView) {
imageView.setImageDrawable(drawable);
if (drawable instanceof AnimationDrawable) {
Log.i(TAG, "AnimationDrawable start");
((AnimationDrawable) drawable).start();
} else {
Log.i(TAG, "drawable no instanceof AnimationDrawable");
}
if (drawableMap.get(imageView.getId()) != null) {
Log.i(TAG, "drawablemap already has drawable >>" + imageView.getId());
drawableMap.get(imageView.getId()).setCallback(null);
drawableMap.remove(imageView.getId());
}
drawableMap.put(imageView.getId(), drawable);
Log.i(TAG, "add ! drawablemap size>>" + drawableMap.size());
}
/**
* 播放apng图片
*
* @param context
* @param path apng图片路径
* @param imageView 播放容器
*/
public void start(Context context, String path, ImageView imageView) {
try {
if (path.contains("file://")) {
Log.i(TAG, "start by file path");
setDrawable(PngAndroid.readDrawable(context, new FileInputStream(new File(path))), imageView);
} else {
Log.i(TAG, "start by assert path");
setDrawable(PngAndroid.readDrawable(context, context.getAssets().open(path)), imageView);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (PngException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 播放apng图片
*
* @param context
* @param id apng图片资源id
* @param imageView 播放容器
*/
public void start(Context context, int id, ImageView imageView) {
try {
Log.i(TAG, "start by res id");
setDrawable(PngAndroid.readDrawable(context, FormatTools.getInstance().Drawable2InputStream(context.getResources().getDrawable(id))), imageView);
} catch (PngException e) {
e.printStackTrace();
}
}
/**
* 播放apng图片
*
* @param context
* @param stream apng图片数据流
* @param imageView 播放容器
*/
public void start(Context context, InputStream stream, ImageView imageView) {
try {
Log.i(TAG, "start by inputStream");
setDrawable(PngAndroid.readDrawable(context, stream), imageView);
} catch (PngException e) {
e.printStackTrace();
}
}
/**
* 停止播放apng
*
* @param imageView 停止对象
*/
public void stop(ImageView imageView) {
if (drawableMap.get(imageView.getId()) != null) {
if (drawableMap.get(imageView.getId()) instanceof AnimationDrawable) {
Log.i(TAG, "AnimationDrawable stop");
((AnimationDrawable) drawableMap.get(imageView.getId())).stop();
}
drawableMap.get(imageView.getId()).setCallback(null);
drawableMap.remove(imageView.getId());
Log.i(TAG, "delete ! drawablemap size>>" + drawableMap.size());
}
}
public void clear() {
for (Map.Entry<Integer, Drawable> entry : drawableMap.entrySet())
entry.getValue().setCallback(null);
drawableMap.clear();
}
}
由于框架作者并未提供Maven,Jcenter等仓库链接,需要自己将框架clone下来作为module导入到项目中使用。
这里提供已经打包为aar的框架,将aar包放到libs文件夹,使用 compile(name: 'Japng', ext: 'aar') 导入框架