Android自定义View缓冲,Android自定义View(3)画两个好玩的数据加载进度缓冲控件

1、仿58同城数据加载缓冲控件动画效果

先看下效果图:

e8b3d2ffe60d

58city.gif

#######1.1 实现步骤拆解

(1)自定义一个ShapeView继承自View,按顺序分别重绘三角形、圆形和正方形,如此不断重复。

(2)自定义一个ViewGroup,创建一个ShapeView加进布局当中,并往布局中再添加一个TextView以显示文字。onLayout分别摆放好ShapeView和TextView。

(3)使用属性动画实现ShapeView的上下移动和旋转

#######1.2 实现分析

2.1 自定义一个ShapeView

自定义一个ShapeView实现三种形状切换效果的原理也很简单。圆形通过画布的canvas.drawCircle()方法来绘制,正方形通过画布的canvas.drawRect()方法来绘制。等边三角形的绘制稍复杂,可通过绘制路径来实现: canvas.drawPath(),等边三角形路径的三个顶点坐标通过计算得出,以下是分析图 :

e8b3d2ffe60d

triangle.png

如上图,控件ShapeView的宽高可通过getMeasureHeight()或getMeasureWidth()获得,这里测量时已确保ShapeView的宽高相等。因此,三角形边长S即为控件宽或高。

然后,如上图,三角形的三个顶点A 、B 、C即可通过勾股定理算出。

三角形路径设置代码如下:

Path trianglePath = new Path();

trianglePath.moveTo(getWidth() / 2f, 0);

trianglePath.lineTo(0, (float) (Math.sqrt(3) * getHeight() / 2)); // 等边三角形

trianglePath.lineTo(getWidth(), (float) (Math.sqrt(3) * getHeight() / 2));

trianglePath.close();

确定好三个形状的绘制方法后,就可以循环地延时一秒钟,不断地改变当前所要绘制的图形形状,调用 invalidate()方法实现图形的重绘。三种图形绘制方法如下 :

@Override

protected void onDraw(Canvas canvas) {

switch (mShape) { // 当前所要绘制的形状

case circle: // 圆

canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, getHeight() / 2f, circlePaint);

break;

case rect: // 正方形

canvas.drawRect(0, 0, getWidth(), getHeight(), rectPaint);

break;

case triangle: // 三角形

canvas.drawPath(trianglePath, trianglePaint);

break;

}

}

2.2 自定义一个布局ShapeChangeLoadingViewGroup。

第二步骤就是自定义一个布局ShapeChangeLoadingViewGroup,继承自ViewGroup。再创建ShapeView和一个TextView,TextView用于显示文字“拼命加载中...”。这个步骤的主要内容在于布局,将TextView放在ViewGroup的最底部,ShapeView放在上面。ShapeChangeLoadingViewGroup的布局部分代码如下 :

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

int shapeLeft = getWidth() / 2 - mShapeView.getMeasuredWidth() / 2;

int shapeTop = (int) (mShapeView.getMeasuredHeight() * 3.5);

int shapeRight = shapeLeft + mShapeView.getMeasuredWidth();

int shapeBottom = shapeTop + mShapeView.getMeasuredHeight();

mShapeView.layout(shapeLeft, shapeTop, shapeRight, shapeBottom);

int textLeft = 0;

int textTop = getHeight() - mLoadTextView.getMeasuredHeight();

int textRight = getWidth();

int textBottom = getHeight();

mLoadTextView.layout(textLeft, textTop, textRight, textBottom);

setAnimator();

}

2.3 使用属性动画让ShapeView动起来

第三部就是实现ShapeView上下移动以及旋转的效果,这里分别使用了属性动画的translationY 和 rotation 两个属性实现。代码如下 :

translationObjectAnimator = ObjectAnimator.ofFloat(mShapeView,

"translationY", -distance, 0, -distance); //实现上下平移

translationObjectAnimator.setDuration(1500);

translationObjectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());

translationObjectAnimator.setRepeatCount(-1); // -1 无限循环

rotationObjectAnimator = ObjectAnimator.ofFloat(mShapeView,

"rotation", 0f, 360f); // 实现360度旋转

rotationObjectAnimator.setDuration(1500);

rotationObjectAnimator.setRepeatCount(-1); // -1 无限循环

rotationObjectAnimator.start();

translationObjectAnimator.start();

最后效果实现了,但有一点要优化。对外提供一个接口,将属性动画资源释放 :

public void release(){ //优化,释放属性动画资源

if (translationObjectAnimator != null){

translationObjectAnimator.end();

translationObjectAnimator.removeAllListeners();

translationObjectAnimator.cancel();

translationObjectAnimator = null;

}

if (rotationObjectAnimator != null){

rotationObjectAnimator.end();

rotationObjectAnimator.removeAllListeners();

rotationObjectAnimator.cancel();

rotationObjectAnimator = null;

}

if (mShapeView != null) mShapeView.setRepeat(false);

}

2、另一个加载控件

效果看图 :

e8b3d2ffe60d

loadingView.gif

实现步骤 :

(1) 自定义一个CircleView继承自View,画一个圆,对外提供可改变颜色的接口。

(2) 自定义一个LoadingView继承自ViewGroup,创建三个CircleView,分别摆放在LoadingView的左、中、右的位置。

(3) 利用属性动画实现左右两个CircleView往中间方向来回移动,中间的CircleView保持不动。

(4) 监听属性动画的回调,实现每移动一次,三个CircleView颜色互换一次,达到变色的效果。

这部分实现比较简单,实现原理和上面第一个控件相似,这里不再详细讲述。看源码:https://github.com/EthanLee-88/LoadingView

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值