android打造独一无二的loading动画效果

来源:互联网 发布:网络电视不能看回放 编辑:程序博客网 时间:2024/05/22 03:08

请尊重他人的劳动成果,转载请注明出处:
http://blog.csdn.net/sw950729/article/details/52239548

最近改代码改的都醉了,前几天写了个图片加载框架,点了闪退,找半天没找到问题在哪- - 看来又要花心思重写了。好了。来说正文了。
上周花了一周的时间写了几个自定义view。有loading。有刷新,还有一些别的,因为最近在写个框架,所以耽误了。这个后期肯定会补上。先来看看,今天我们loading的效果:
这里写图片描述

其实这个不是很难,我居然花了两天半++。因为今天电脑太卡了。后面就只用文字表达,不上图片了。
首先我们看这个效果,这5个小圆是在一个大圆上,至于怎么获取这五个圆的位置,这是难点之一,到时候你们自己看代码理解,先上一些必用的定义:

 private static final String TAG = "SWLoadView";    private Paint paint;    private Path path;    //大圆的半径    private int bigRadius = 150;    //小圆的半径    private int smallRadius = 30;    //移动圆的半径    private int radius = 20;    //存放圆的圆心    private ArrayList<Circle> circlelist = new ArrayList<>();    //移动的圆的圆心    private ArrayList<Circle> offSetcircle1 = new ArrayList<>();    private ArrayList<Circle> offSetcircle2 = new ArrayList<>();    private ArrayList<Circle> offSetcircle3 = new ArrayList<>();    private ArrayList<Circle> offSetcircle4 = new ArrayList<>();    private ArrayList<Circle> offSetcircle5 = new ArrayList<>();    private int width = 0;    private int height = 0;    //移动速度    private int speed;    private int count1 = 0;    private int count2 = 0;    private int count3 = 0;    private int count4 = 0;    private int count5 = 0;    private int count6 = 0;    private int count7 = 0;    private int count8 = 0;    private int count9 = 0;    private int count10 = 0;

我们需要五个圆的圆心,以及动态滚动的球的轨迹,因为是5条线,所以这边我用了5个list来存放。代码如下:

 //依次放入五个圆心的坐标        Circle circle1 = new Circle();        Circle circle2 = new Circle();        Circle circle3 = new Circle();        Circle circle4 = new Circle();        Circle circle5 = new Circle();        circle1.circleX = (width / 2 + Math.abs((float) (bigRadius * Math.cos(60))));        circle1.circleY = (height / 2 - Math.abs((float) (bigRadius * Math.sin(60))));        circle2.circleX = (width / 2 + Math.abs((float) (bigRadius * Math.sin(120))));        circle2.circleY = (height / 2 + Math.abs((float) (bigRadius * Math.cos(120))));        circle3.circleX = (width / 2 - Math.abs((float) (bigRadius * Math.cos(180))));        circle3.circleY = (height / 2 + Math.abs((float) (bigRadius * Math.sin(180))));        circle4.circleX = (width / 2 - Math.abs((float) (bigRadius * Math.sin(240))));        circle4.circleY = (height / 2 - Math.abs((float) (bigRadius * Math.cos(240))));        circle5.circleX = (width / 2 + Math.abs((float) (bigRadius * Math.cos(300))));        circle5.circleY = (height / 2 - Math.abs((float) (bigRadius * Math.sin(300))));        circlelist.add(circle1);        circlelist.add(circle2);        circlelist.add(circle3);        circlelist.add(circle4);        circlelist.add(circle5);        speed = (int) (circlelist.get(1).circleX - circlelist.get(2).circleX + 0.5);        speed = speed / 20;        for (int i = 0; i < speed; i++) {            Circle circle = new Circle();            circle.circleX = circlelist.get(0).circleX * (speed - i - 1) / speed + circlelist.get(1).circleX * (i + 1) / speed;            circle.circleY = circlelist.get(0).circleY * (speed - i - 1) / speed + circlelist.get(1).circleY * (i + 1) / speed;            offSetcircle1.add(circle);        }        for (int i = 0; i < speed; i++) {            Circle circle = new Circle();            circle.circleX = circlelist.get(1).circleX * (speed - i - 1) / speed + circlelist.get(2).circleX * (i + 1) / speed;            circle.circleY = circlelist.get(1).circleY * (speed - i - 1) / speed + circlelist.get(2).circleY * (i + 1) / speed;            offSetcircle2.add(circle);        }        for (int i = 0; i < speed; i++) {            Circle circle = new Circle();            circle.circleX = circlelist.get(2).circleX * (speed - i - 1) / speed + circlelist.get(3).circleX * (i + 1) / speed;            circle.circleY = circlelist.get(2).circleY * (speed - i - 1) / speed + circlelist.get(3).circleY * (i + 1) / speed;            offSetcircle3.add(circle);        }        for (int i = 0; i < speed; i++) {            Circle circle = new Circle();            circle.circleX = circlelist.get(3).circleX * (speed - i - 1) / speed + circlelist.get(4).circleX * (i + 1) / speed;            circle.circleY = circlelist.get(3).circleY * (speed - i - 1) / speed + circlelist.get(4).circleY * (i + 1) / speed;            offSetcircle4.add(circle);        }        for (int i = 0; i < speed; i++) {            Circle circle = new Circle();            circle.circleX = circlelist.get(4).circleX * (speed - i - 1) / speed + circlelist.get(0).circleX * (i + 1) / speed;            circle.circleY = circlelist.get(4).circleY * (speed - i - 1) / speed + circlelist.get(0).circleY * (i + 1) / speed;            offSetcircle5.add(circle);        }

初始化不难:

    private void inital() {        paint = new Paint();        path = new Path();        paint.setStyle(Paint.Style.FILL);        paint.setColor(0xff00ced1);        paint.setAntiAlias(true);    }

ondraw方法先画5个圆,以及一个滚动的球的路径:

protected void onDraw(Canvas canvas) {        canvas.drawCircle(circlelist.get(0).circleX, circlelist.get(0).circleY, smallRadius, paint);        canvas.drawCircle(circlelist.get(1).circleX, circlelist.get(1).circleY, smallRadius, paint);        canvas.drawCircle(circlelist.get(2).circleX, circlelist.get(2).circleY, smallRadius, paint);        canvas.drawCircle(circlelist.get(3).circleX, circlelist.get(3).circleY, smallRadius, paint);        canvas.drawCircle(circlelist.get(4).circleX, circlelist.get(4).circleY, smallRadius, paint);        drawBezier(canvas);        invalidate();    }

小球的滚动路径是用贝塞尔曲线绘画的,这也是难点之二。

if (offSetcircle1.get(count1).circleX != circlelist.get(1).circleX) {            //根据角度算出四边形的四个点            float offsetX = (float) (radius * Math.sin(Math.atan((offSetcircle1.get(count1).circleY - circlelist.get(0).circleY) / (offSetcircle1.get(count1).circleX - circlelist.get(0).circleX))));            float offsetY = (float) (radius * Math.cos(Math.atan((offSetcircle1.get(count1).circleY - circlelist.get(0).circleY) / (offSetcircle1.get(count1).circleX - circlelist.get(0).circleX))));            float x1 = circlelist.get(0).circleX - offsetX;            float y1 = circlelist.get(0).circleY + offsetY;            float x2 = offSetcircle1.get(count1).circleX - offsetX;            float y2 = offSetcircle1.get(count1).circleY + offsetY;            float x3 = offSetcircle1.get(count1).circleX + offsetX;            float y3 = offSetcircle1.get(count1).circleY - offsetY;            float x4 = circlelist.get(0).circleX + offsetX;            float y4 = circlelist.get(0).circleY - offsetY;            float anchorX1 = (x2 + x4) / 2;            float anchorY1 = (y2 + y4) / 2;            float anchorX2 = (x1 + x3) / 2;            float anchorY2 = (y2 + y4) / 2;            path.reset();            path.moveTo(x1, y1);            path.quadTo(anchorX1, anchorY1, x2, y2);            path.lineTo(x3, y3);            path.quadTo(anchorX2, anchorY2, x4, y4);            path.lineTo(x1, y1);            path.close();            canvas.drawCircle(offSetcircle1.get(count1).circleX, offSetcircle1.get(count1).circleY, radius, paint);            canvas.drawPath(path, paint);            count1++;        } else if (offSetcircle1.get(count1).circleX == circlelist.get(1).circleX && offSetcircle1.get(count2).circleX != circlelist.get(1).circleX) {            //根据角度算出四边形的四个点            float offsetX = (float) (radius * Math.sin(Math.atan((offSetcircle1.get(count2).circleY - circlelist.get(1).circleY) / (offSetcircle1.get(count2).circleX - circlelist.get(1).circleX))));            float offsetY = (float) (radius * Math.cos(Math.atan((offSetcircle1.get(count2).circleY - circlelist.get(1).circleY) / (offSetcircle1.get(count2).circleX - circlelist.get(1).circleX))));            float x1 = circlelist.get(1).circleX - offsetX;            float y1 = circlelist.get(1).circleY + offsetY;            float x2 = offSetcircle1.get(count2).circleX - offsetX;            float y2 = offSetcircle1.get(count2).circleY + offsetY;            float x3 = offSetcircle1.get(count2).circleX + offsetX;            float y3 = offSetcircle1.get(count2).circleY - offsetY;            float x4 = circlelist.get(1).circleX + offsetX;            float y4 = circlelist.get(1).circleY - offsetY;            float anchorX1 = (x2 + x4) / 2;            float anchorY1 = (y2 + y4) / 2;            float anchorX2 = (x1 + x3) / 2;            float anchorY2 = (y2 + y4) / 2;            path.reset();            path.moveTo(x1, y1);            path.quadTo(anchorX1, anchorY1, x2, y2);            path.lineTo(x3, y3);            path.quadTo(anchorX2, anchorY2, x4, y4);            path.lineTo(x1, y1);            path.close();            canvas.drawCircle(offSetcircle1.get(count2).circleX, offSetcircle1.get(count2).circleY, radius, paint);            canvas.drawPath(path, paint);            count2++;        } 

这快是绘画的右下2个小球的路径,先从小球的头部从1-2,然后小球的尾部从1-2.后面的就是复制粘贴了。因为是5条线,所以是10个动画轨迹,头过去–尾过去。
代码我已经上传到csdn上了,地址:http://download.csdn.net/detail/sw950729/9606812。一开始准备上传到github上的,结果不会搞 0 0 。
最近也是无意了写了不少自定义view的动画。如果有好的动画效果或者思路可以提出来,我会抽空试着写一写~~
好了。有兴趣交流的,请看左上角的群号,欢迎进入。

0 0