Android 自定义View修炼-自定义加载进度动画XCLoadingImageView

时间:2023-03-09 03:02:27
Android 自定义View修炼-自定义加载进度动画XCLoadingImageView

一、概述

本自定义View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果。

支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙层进度颜色。

直接看下面的效果图吧。

二、效果图

废话不说,先来看看效果图吧~~

Android 自定义View修炼-自定义加载进度动画XCLoadingImageView

三、实现原理方案

1、自定义View-XCLoadingImageView,继承ImageVIew来实现,这样就不用自己再处理drawable和测量的工作内容。

2、根据蒙层颜色创建一个蒙层bitmap,然后根据这个bitmap来创建一个ClipDrawable,最后利用ClipDrawable的level属性

来裁剪显示区域进度,从而达到加载进度的效果。

3、最后利用属性动画技术或ClipDrawable的setLevel()方法来达到进度的效果。

四、自定义加载进度效果XCLoadingImageView的具体实现

1、初始化需要用到的数据变量以及画笔以及属性

private Paint mImagePaint;
private int mImageHeight, mImageWidth;
private boolean mIsAutoStart = false;
private int mMaskColor = Color.TRANSPARENT;
private ClipDrawable mClipDrawable;
private Drawable mMaskDrawable;
private int maskHeight;
private int mProgress;
private ObjectAnimator mAnimator;
private long mAnimDuration = 2500;
private float mScaleX, mScaleY;
private int mGravity = Gravity.BOTTOM;
private int mOrientaion = ClipDrawable.VERTICAL;
private int mMaskOrientation = MaskOrientation.BottomToTop; //Loading oriention
public static final class MaskOrientation {
public static final int LeftToRight = 1;
public static final int RightToLeft = 2;
public static final int TopToBottom = 3;
public static final int BottomToTop = 4;
} /**
* initial attributes
*/
private void initAttrs(Context context, AttributeSet attrs) {
if (attrs == null) {
return;
}
TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.XCLoadingImageView);
mMaskColor = t.getColor(R.styleable.XCLoadingImageView_mask_color, mMaskColor);
mIsAutoStart = t.getBoolean(R.styleable.XCLoadingImageView_auto_start_anim, mIsAutoStart);
setMaskColor(mMaskColor);
t.recycle();
} /**
* initial paint
*/
private void init() {
if (mImagePaint == null) {
mImagePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mImagePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
}
}

2、初始化蒙层Bitmap以及创建加载进度用的ClipDrawable

private void initMaskBitmap(int maskColor) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
Bitmap bgBmp = ((BitmapDrawable) drawable).getBitmap();
mImageWidth = drawable.getIntrinsicWidth();
mImageHeight = drawable.getIntrinsicHeight(); Bitmap fgBmp = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888);
Canvas fgCanvas = new Canvas(fgBmp);
fgCanvas.drawColor(maskColor); Bitmap bitmap = combineBitmap(bgBmp, fgBmp);
mMaskDrawable = new BitmapDrawable(null, bitmap);
mClipDrawable = new ClipDrawable(mMaskDrawable, mGravity, mOrientaion);
}

3、合并蒙层Bitmap和ImageView的src的drawable为新的Bitmap 

/**
* combine tow bitmap to one bitmap
*/
private Bitmap combineBitmap(Bitmap bg, Bitmap fg) {
Bitmap bmp = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
canvas.drawBitmap(bg, 0, 0, null);
canvas.drawBitmap(fg, 0, 0, mImagePaint);
return bmp;
}

4、重写ImageVIew的onDraw()方法来把创建的ClipDrawable绘制到Canvas上

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(mScaleX, mScaleY);
mClipDrawable.setBounds(getDrawable().getBounds());
mClipDrawable.draw(canvas);
canvas.restore();
}
 

5、弹通过属性动画或者setLevel,并调用postInvalidate()来重绘,从而达到进度刷新的效果

private void initAnim() {
stopAnim();
mAnimator = ObjectAnimator.ofInt(mClipDrawable, "level", 0, 10000);
mAnimator.setDuration(mAnimDuration);
mAnimator.setRepeatCount(ValueAnimator.INFINITE);
mAnimator.setRepeatMode(ValueAnimator.RESTART);
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
postInvalidate();
}
});
if (mIsAutoStart) {
mAnimator.start();
}
}
public void setProgress(int progress){
mProgress = progress;
mClipDrawable.setLevel(mProgress * 100);
postInvalidate();
}

五、如何使用该自定义LoadingView控件

1、使用该自定义LoadingView非常简单,和使用普通ImageView差不对哦,只需设置下方向和蒙层颜色即可

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); XCLoadingImageView imageView2 = (XCLoadingImageView) findViewById(R.id.img2);
imageView2.setMaskOrientation(XCLoadingImageView.MaskOrientation.LeftToRight);
imageView2.setProgress(50);
}
}

六、源码下载

源码下载http://www.demodashi.com/demo/13442.html

真题园网http://www.zhentiyuan.com