android下播放gif图片功能似乎并不常用,很多时候还是以展示静态图片为主,可能是由于gif图体积比较大吧。不过像表情动画什么的,可能还是需要gif图的。不过每家做法也不尽相同,以前看过微视的动态图做法,他们不是播放gif图,而是轮播一组png图,控制好播放速度,以达到动画效果。不知道微信的动态表情是怎么弄的,没分析过。
本文的做法大体流程为,首先解析gif动画帧,然后将其绘制到底图,最后使用ImageView显示底图。大体代码如下:
// 图像图层>>支持png/jpg/gif等格式
public class ImageLayer
{
private Context context = null;
// 图像
private int bitmapType = 0, resId = 0, gifDuration = 0, playingTime = 0;
private Rect bmpRect = null;
private Bitmap bitmap = null;
private BitmapFactory.Options options = null;
private Movie gifMovie = null;
private Bitmap cacheBitmap = null;
private Canvas cacheCanvas = null;
private Canvas baseCanvas = null;
private Paint clearPaint = null;
private static final int BITMAP_TYPE_NOR = 0;
private static final int BITMAP_TYPE_GIF = 1;
private static final int FRAME_INTERVAL = 40;
public ImageLayer(Context _context)
{
context = _context;
// 图像
resId = R.drawable.ic_launcher;
bmpRect = new Rect();
cacheCanvas = new Canvas();
baseCanvas = new Canvas();
clearPaint = new Paint();
options = new BitmapFactory.Options();
options.inScaled = false;
bitmap = BitmapFactory.decodeResource(context.getResources(), resId, options);
}
public void drawLayer(Bitmap parentBmp)
{
// 清理canvas
clearPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
baseCanvas.drawPaint(clearPaint);
clearPaint.setXfermode(new PorterDuffXfermode(Mode.SRC));
baseCanvas.setBitmap(parentBmp);
// 图像
if (bitmapType == BITMAP_TYPE_NOR)
{
// png/jpg
baseCanvas.drawBitmap(bitmap, null, bmpRect, null);
}
else if (bitmapType == BITMAP_TYPE_GIF)
{
// gif
playingTime += FRAME_INTERVAL;
if (playingTime > gifDuration)
{
playingTime = 0;
}
cacheBitmap.eraseColor(Color.parseColor("#00000000"));
gifMovie.setTime(playingTime);
gifMovie.draw(cacheCanvas, 0, 0);
baseCanvas.drawBitmap(cacheBitmap, null, bmpRect, null);
}
}
// 加载图像资源
public void loadImage(int _resId, int posX, int posY, int width, int height)
{
resId = _resId;
int bmpWidth = 0;
int bmpHeight = 0;
// 加载资源
InputStream is = context.getResources().openRawResource(resId);
gifMovie = Movie.decodeStream(is);
if (gifMovie != null)
{
// gif图
bitmapType = BITMAP_TYPE_GIF;
Bitmap tmpBmp = BitmapFactory.decodeStream(is);
bmpWidth = tmpBmp.getWidth();
bmpHeight = tmpBmp.getHeight();
tmpBmp.recycle();
if (cacheBitmap != null)
{
cacheBitmap.recycle();
}
cacheBitmap = Bitmap.createBitmap(bmpWidth, bmpHeight, Config.ARGB_8888);
cacheCanvas.setBitmap(cacheBitmap);
gifMovie.setTime(0);
gifDuration = gifMovie.duration();
}
else
{
// png/jpg图
bitmapType = BITMAP_TYPE_NOR;
if (bitmap != null)
{
bitmap.recycle();
}
bitmap = BitmapFactory.decodeResource(context.getResources(), resId, options);
bmpWidth = bitmap.getWidth();
bmpHeight = bitmap.getHeight();
}
// 计算位置(这里需要做边界判断的)
bmpRect.left = posX;
bmpRect.right = posX + width;
bmpRect.top = posY;
bmpRect.bottom = posY + height;
}
}
布局资源文件代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.my.testgifimageview.MainActivity$PlaceholderFragment" >
<ImageView
android:id="@+id/testImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="@drawable/ic_launcher"
android:contentDescription="@string/app_name"/>
</RelativeLayout>
调用部分代码如下(这里仅作测试,应用时上述代码还需要进一步重构):
public class MainActivity extends Activity implements Runnable
{
private Bitmap baseBmp = null;
private ImageLayer imageLayer = null;
private ImageView testGifImageView = null;
private Thread thread = null;
@SuppressLint("HandlerLeak")
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
// 显示绘制结果
imageLayer.drawLayer(baseBmp);
testGifImageView.setImageBitmap(baseBmp);
}
};
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建底图
DisplayMetrics dm = getResources().getDisplayMetrics();
baseBmp = Bitmap.createBitmap(dm.widthPixels, dm.heightPixels, Config.ARGB_8888);
// 创建与绘制待显示图层
imageLayer = new ImageLayer(this);
imageLayer.loadImage(R.drawable.theme, 0, 0, dm.widthPixels, dm.widthPixels);
imageLayer.drawLayer(baseBmp);
// 显示绘制结果
testGifImageView = (ImageView)findViewById(R.id.testImageView);
testGifImageView.setImageBitmap(baseBmp);
// 创建播放线程
thread = new Thread(this);
thread.start();
}
@Override
public void run()
{
// 注意:这里要添加控制条件,以结束线程
while (true)
{
try
{
Thread.sleep(40);
handler.sendEmptyMessage(0);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
}
效果图如下所示:
完整工程下载链接如下: http://download.csdn.net/detail/u013085897/9157313