美文网首页Android Class
模仿饿了么loading自定义

模仿饿了么loading自定义

作者: 那个唐僧 | 来源:发表于2017-01-10 13:26 被阅读199次

    类似于这样的加载等待的loading效果

    模拟器运行图片

    其实很简单,其实并不难.

    思路:

    既然要实现这个效果,那肯定第一个念头就是自定义View.

    package com.ccstest.views;
    
    import android.animation.Animator;
    import android.animation.ValueAnimator;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.PixelFormat;
    import android.graphics.RectF;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.animation.OvershootInterpolator;
    
    import com.ccstest.R;
    
    /**
     * Created by scc on 2017/1/9.
     */
    public class Loading1View extends View {
        //logt
        private static final String TAG = "Loading1View";
        //画笔初始化
        private Paint mPaint;
        //属性动画
        private ValueAnimator mAnimator;
        //当前Y轴偏移,开始X轴坐标,开始Y轴坐标,结束Y轴坐标
        private int currentY, startX, startY, endY;
        //当前需要显示的图片的下标
        private int currentIndex;
        //当前图片的位图对象
        private Bitmap currentBitmap;
        //这里我是直接初始化好的位图对象
        Bitmap b = drawableToBitmap(getResources().getDrawable(R.drawable.gold));
        Bitmap b1 = drawableToBitmap(getResources().getDrawable(R.drawable.goldingots));
        Bitmap b2 = drawableToBitmap(getResources().getDrawable(R.drawable.goldsupplier));
        //装进数组中,也可以使用集合,都行的
        final Bitmap[] bs = new Bitmap[]{b, b1, b2};
    
        //构造方法
        public Loading1View(Context context) {
            this(context, null);
        }
    
        public Loading1View(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public Loading1View(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
    
        }
    
        /**
         * 初始化画笔
         */
        private void init() {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(Color.parseColor("#1B7BEF"));
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setStrokeWidth(8);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //getWidth是当前自定义View的宽度,除以2是获得中心点的X坐标
            startX = getWidth() / 2;
            //getHeight是当前自定义View的高度,除以2是获得中心点的Y坐标
            endY = getHeight() / 2;
            //动画开始的Y轴的值为view中心的Y轴的坐标的六分之五
            startY = endY * 5 / 6;
            //初始化属性动画
            if (currentY == 0) {
                setAnimator();
            } else {
                //画位图,一参位图对象,二参位图x坐标,三参位图y坐标,四参画笔
                canvas.drawBitmap(setBitmapSize(bs[currentIndex]), startX - 60, currentY, mPaint);
                //画下方阴影
                drawShader(canvas);
            }
        }
    
        /**
         * 属性动画
         */
        public void setAnimator() {
            mAnimator = ValueAnimator.ofInt(startY, endY);
            mAnimator.setDuration(1000);
            mAnimator.setRepeatCount(-1);
            mAnimator.setInterpolator(new OvershootInterpolator());
            mAnimator.setRepeatMode(ValueAnimator.RESTART);
            mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    currentY = (int) valueAnimator.getAnimatedValue();
                    invalidate();
                }
            });
            /**
             * 在动画开始时currentIndex初始值为0;
             * 获得currentBitmap对象
             * 在循环的过程中,currentIndex++,如果为3,重置为0,咱只有三张图片
             */
            mAnimator.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animator) {
                    currentIndex = 0;
                    currentBitmap = bs[currentIndex];
                }
    
                @Override
                public void onAnimationEnd(Animator animator) {
    
                }
    
                @Override
                public void onAnimationCancel(Animator animator) {
    
                }
    
                @Override
                public void onAnimationRepeat(Animator animator) {
                    currentIndex++;
                    if (currentIndex == 3) {
                        currentIndex = 0;
                    }
                    currentBitmap = bs[currentIndex];
                }
            });
            mAnimator.start();
        }
    
        /**
         * 绘制阴影部分,由椭圆来支持,根据高度比来底部阴影的大小
         */
        private void drawShader(Canvas canvas) {
            // 计算差值高度
            int dx = endY - startY;
            // 计算当前点的高度差值
            int dx1 = currentY - startY;
            float ratio = (float) (dx1 * 1.0 / dx);
            if (ratio <= 0.3) {// 当高度比例小于0.3,所在比较高的时候就不进行绘制影子
                return;
            }
            int ovalRadius = (int) (60 * ratio);
            // 设置倒影的颜色
            mPaint.setColor(Color.parseColor("#1B7BEF"));
            // 绘制椭圆
            RectF rectF = new RectF(startX - ovalRadius, endY + 125, startX + ovalRadius, endY + 140);
            canvas.drawOval(rectF, mPaint);
        }
    
        /**
         * drawable转换为Bitmap
         * @param drawable
         * @return
         */
        public Bitmap drawableToBitmap(Drawable drawable) // drawable 转换成bitmap
        {
            int width = drawable.getIntrinsicWidth();// 取drawable的长宽
            int height = drawable.getIntrinsicHeight();
            Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;// 取drawable的颜色格式
            Bitmap bitmap = Bitmap.createBitmap(width, height, config);// 建立对应bitmap
            Canvas canvas = new Canvas(bitmap);// 建立对应bitmap的画布
            drawable.setBounds(0, 0, width, height);
            drawable.draw(canvas);// 把drawable内容画到画布中
            return bitmap;
        }
    
        /**
         * 设置bitMap的大小
         * @param bitMap
         * @return
         */
        public Bitmap setBitmapSize(Bitmap bitMap) {
            int width = bitMap.getWidth();
            int height = bitMap.getHeight();
            // 设置想要的大小
            int newWidth = 120;
            int newHeight = 120;
            // 计算缩放比例
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            // 取得想要缩放的matrix参数
            Matrix matrix = new Matrix();
            matrix.postScale(scaleWidth, scaleHeight);
            // 得到新的图片
            return Bitmap.createBitmap(bitMap, 0, 0, width, height, matrix,
                    true);
        }
    
    }
    
    

    首先是字段的声明和构造方法的初始化.
    属性动画的值是以Y轴上下变化的,以变化的这个值为基准来不断的绘制bitmap,然后在属性动画的重复方法中去设置图片即可,循环往复,交替实现
    同时也是根据属性动画的Y轴上下变化的值来绘制底下的阴影部分的大小的.代码中都有注释,思路理通顺,一切OK..

    相关文章

      网友评论

        本文标题:模仿饿了么loading自定义

        本文链接:https://www.haomeiwen.com/subject/zyskbttx.html