最近看到网上有同志在讲drawBitmap的时候,提到分段画,感觉很有意思便研究了下。大家也可以阅读原博客android中使用自定义View让图片像画卷一样被展开显示,还是博主文采好,起名字就看得出来。在基础上改进了一下,自定义的view可以定制自己的图片,可以等比例压缩图片如果图片尺寸太大的情况下,上图先。
现在上代码,注释比较详细。
public class DrawBitmapView extends ImageView {
private Bitmap bitmap;
//每次刷新比上一次多显示图片的比例
private float step = 0.01f;
//已经显示图片的比例
private float currentScale = 0.0f;
//显示图片的区域
private RectF dst;
private Rect src;
private int width;
private int height;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1)
invalidate();
}
};
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//因为这里默认wrap_content时候也是match_parent,没有特别处理,因此这一步可以不必要写,只是出于习惯做法
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
public void initView() {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 2;
//这里是获取定制的drawable
Drawable drawable = getDrawable();
//将drawable压缩成bitmap
bitmap = drawableToBitmap(drawable);
dst = new RectF();
dst.left = 0;
dst.top = 0;
dst.bottom = bitmap.getHeight();
src = new Rect();
src.left = 0;
src.top = 0;
src.bottom = bitmap.getHeight();
}
public DrawBitmapViewSingle(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
/**
* 默认从左到右显示
*/
@Override
protected void onDraw(Canvas canvas) {
//将bitmap等比例压缩
bitmap = zoomBitmap(bitmap, getWidth(), getWidth());
currentScale = currentScale + step > 1 ? 1 : currentScale + step;
dst.right = bitmap.getWidth() * currentScale;
src.right = (int) (bitmap.getWidth() * currentScale);
/*
* drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint);
* Rect src: 是对图片进行裁截,若是空null则显示整个图片
* RectF dst:是图片在Canvas画布中显示的区域,
* 大于src则把src的裁截区放大,
* 小于src则把src的裁截区缩小。
* 当想要让图片以画卷方式展现的话,主要是设置src大小,这边是默认从左到右显示,所以每次只要修改src中right的大小就好
*/
canvas.drawBitmap(bitmap, src, dst, null);
if (currentScale >= 1) {
//当显示完图片,重置,循环显示
currentScale = 0 - step;
}
//不想让整个页面处于频繁刷新的状态,这里延迟了10ms来刷新该页面
handler.sendEmptyMessageDelayed(1, 10);
}
public static Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap = Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
//canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}
public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
float scaleWidht = ((float) w / width);
float scaleHeight = ((float) h / height);
matrix.postScale(scaleWidht, scaleHeight);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return newbmp;
}
}
因为继承的是imageview,因此设置定制图片的时候,在src属性里设置就可以。