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


    一、概述

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

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

    直接看下面的效果图吧。

    二、效果图

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

    三、实现原理方案

    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

  • 相关阅读:
    vue学习 基本简介,安装,示例,options
    python操作谷歌翻译
    Celery笔记
    nps内网穿透笔记
    初学django基础05 路由系统,django的请求与返回
    初学Django基础04 http|jsonresponse,filter模板过滤器,cvb与fvb
    计数二进制字符串
    字符串相加
    类与对象
    Arrays
  • 原文地址:https://www.cnblogs.com/JczmDeveloper/p/5037068.html
Copyright © 2020-2023  润新知