博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android鬼点子 又来了一个LoadingBar
阅读量:5995 次
发布时间:2019-06-20

本文共 6430 字,大约阅读时间需要 21 分钟。

设计师在外国的一个网站上挑了一个Loading的效果图,尝试实现之后,虽然和原图有点不太一样,但是效果还是不错的。难点就是粘连效果的实现,贝塞尔曲线的点点们简直要把我折磨死了。 先上效果图:

然后是源码,就是一个简单VIew,可以直接放在xml中使用。

package top.greendami.greendami;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.View;/** * Created by GreendaMi on 2017/3/17. */public class PPView extends View {    String TAG = "PPView";    //动画开关    boolean isLoading = true;    Context mContext;    private int mWidth = 100;    private int mheight = 100;    public int mColor;    public Paint mPaint = new Paint();    float time = 0;    //小球与中间打球的最远距离    float distance = 100;    public PPView(Context context) {        super(context);        mContext = context;    }    public PPView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        mContext = context;        mColor = context.getResources().getColor(R.color.colorPrimary);        init();    }    private void init() {        mPaint.setAntiAlias(true);        mPaint.setColor(mColor);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);        //宽度至少是高度的4倍        if (widthSpecSize < 4 * heightSpecSize) {            widthSpecSize = 4 * heightSpecSize;        }        mWidth = widthSpecSize;        mheight = heightSpecSize;        distance = 1.2f * mheight;        setMeasuredDimension(widthSpecSize, heightSpecSize);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (isLoading) {            //大圆半径            float bigR = mheight * 0.32f + mheight * 0.03f * Math.abs((float) Math.sin(Math.toRadians(time)));            float smallR = mheight * 0.22f + mheight * 0.03f * Math.abs((float) Math.cos(Math.toRadians(time)));            float bigx = (getWidth()) / 2;            //画中间大圆            canvas.drawCircle(bigx, mheight / 2, bigR, mPaint);            float smalx = getSmallCenterX();            //画小圆            canvas.drawCircle(smalx, mheight / 2, smallR, mPaint);            //画链接            //小球在右侧            if (smalx > bigx) {                Path path = new Path();                //上面的贝塞尔曲线的第一个点,在大圆身上                float x1 = bigx + bigR * (float) Math.cos(Math.toRadians(time));                float y1 = mheight / 2 - bigR * (float) Math.sin(Math.toRadians(time));                if (y1 > mheight / 2 - smallR) {                    y1 = mheight / 2 - smallR;                    x1 = bigx + (float) (Math.sqrt(bigR * bigR - smallR * smallR));                }                //上面的贝塞尔曲线的第三个点,在小圆身上                float x2 = smalx - smallR * (float) Math.cos(Math.toRadians(time));                float y2 = mheight / 2 - smallR * (float) Math.sin(Math.toRadians(time));                if (y2 > mheight / 2 - smallR * 0.8) {                    y2 = mheight / 2 - smallR * 0.8f;                    x2 = smalx - smallR * (float) (Math.sqrt(1-0.64f));                }                //下面的贝塞尔曲线的第三个点,在小圆身上                float x3 = smalx - smallR * (float) Math.cos(Math.toRadians(time));                float y3 = mheight / 2 + smallR * (float) Math.sin(Math.toRadians(time));                if (y3 < mheight / 2 + smallR * 0.8) {                    y3 = mheight / 2 + smallR * 0.8f;                    x3 = smalx - smallR * (float) (Math.sqrt(1-0.64f));                }                //下面的贝塞尔曲线的第一个点,在大圆身上                float x4 = bigx + bigR * (float) Math.cos(Math.toRadians(time));                float y4 = mheight / 2 + bigR * (float) Math.sin(Math.toRadians(time));                if (y4 < mheight / 2 + smallR) {                    y4 = mheight / 2 + smallR;                    x4 = bigx + (float) (Math.sqrt(bigR * bigR - smallR * smallR));                }                path.moveTo(x1, y1);                path.quadTo((bigx + smalx) / 2, mheight / 2, x2, y2);                // 绘制贝赛尔曲线(Path)                path.lineTo(x3, y3);                path.quadTo((bigx + smalx) / 2, mheight / 2, x4, y4);                canvas.drawPath(path, mPaint);            }            //小球在左侧            if (smalx < bigx) {                Path path = new Path();                float x1 = bigx + bigR * (float) Math.cos(Math.toRadians(time));                float y1 = mheight / 2 - bigR * (float) Math.sin(Math.toRadians(time));                if (y1 > mheight / 2 - smallR) {                    y1 = mheight / 2 - smallR;                    x1 = bigx - (float) (Math.sqrt(bigR * bigR - smallR * smallR));                }                float x2 = smalx - smallR * (float) Math.cos(Math.toRadians(time));                float y2 = mheight / 2 - smallR * (float) Math.sin(Math.toRadians(time));                if (y2 > mheight / 2 - smallR * 0.8) {                    y2 = mheight / 2 - smallR * 0.8f;                    x2 = smalx + smallR * (float) (Math.sqrt(1-0.64f));                }                float x3 = smalx - smallR * (float) Math.cos(Math.toRadians(time));                float y3 = mheight / 2 + smallR * (float) Math.sin(Math.toRadians(time));                if (y3 < mheight / 2 + smallR * 0.8) {                    y3 = mheight / 2 + smallR * 0.8f;                    x3 = smalx + smallR * (float) (Math.sqrt(1-0.64f));                }                float x4 = bigx + bigR * (float) Math.cos(Math.toRadians(time));                float y4 = mheight / 2 + bigR * (float) Math.sin(Math.toRadians(time));                if (y4 < mheight / 2 + smallR) {                    y4 = mheight / 2 + smallR;                    x4 = bigx - (float) (Math.sqrt(bigR * bigR - smallR * smallR));                }                path.moveTo(x1, y1);                path.quadTo((bigx + smalx) / 2, mheight / 2, x2, y2);                // 绘制贝赛尔曲线(Path)                path.lineTo(x3, y3);                path.quadTo((bigx + smalx) / 2, mheight / 2, x4, y4);                canvas.drawPath(path, mPaint);            }            postInvalidate();        }    }    //计算小球的X坐标    private float getSmallCenterX() {        //此处控制速度        time = time + 2.5f;        return mWidth / 2 + distance * (float) Math.cos(Math.toRadians(time));    }}复制代码

“精心”画了一张图,对代码做了说明。

在代码中使用

复制代码

转载地址:http://ghqlx.baihongyu.com/

你可能感兴趣的文章
ionic3+angular4+cordova 项目实例
查看>>
(转)设计模式——观察者模式
查看>>
Jar包冲突解决方法
查看>>
彻底搞清楚Java并发 (一) 基础
查看>>
SQL疑难杂症【3】链接服务器提示"无法启动分布式事物"
查看>>
Windows Mobile和Wince(Windows Embedded CE)下如何封装Native DLL提供给.NET Compact Framework进行调用...
查看>>
数据库相关
查看>>
HDU Count the string (KMP)
查看>>
C#中的泛型
查看>>
编程之美4:求数组中的最大值和最小值
查看>>
ios7新增基础类库以及OC新特性
查看>>
[LeetCode] Maximal Square
查看>>
代码设置TSQLCONNECTION参数
查看>>
BROKER服务器同客户端和应用服务器三者之间传递消息的格式定义
查看>>
【转】20个Cydia常见错误问题解决方法汇总
查看>>
使用jQuery和Bootstrap实现多层、自适应模态窗口
查看>>
C#中如何选择使用T[]或List<T>
查看>>
iOS开发-数据存储NSCoder
查看>>
SQL Server 存储过程【转】
查看>>
localstorage和sessionstorage上手使用记录
查看>>