本来想写写有点意思的东西的,哈哈,上篇文章说的,以后再写吧。今天先介绍一下一个水波加载动画,效果图如下:
做的比较简单,真机效果比这个好很多,这个截图做的gif,有点蛋疼。
说说思路吧:
1. 首先画正弦曲线,这里取的是正弦周期的前3/4个周期,这样看起来比其他的周期变化很好点;
2. 画了正弦曲线以后,就要让正弦曲线动起来,怎么动起来?乍一看觉得很困难的样子,其实我们想想移动正弦曲线,不过是某个位置的Y轴值变化了,那么我们只要给sin(x)中添加一个变量就行,即sin(x + offset),offset的值按时间规律来变化,那么最后表现出来的效果就有移动的感觉。
3. 关于正弦曲线振幅不能设置的太高,因为我们的屏幕本来就很小,如果振幅很大就表现的很不真实,我这里取的是30,看起来效果还不错。
4. 最后就是y轴方向的改变了。要不停的提升,这里写死了,如果想用,就直接写个方法,去设置就行,比如你要设置百分比之类的。
最后上代码:
package com.zdl.wavedemo; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.View; /** * Created by zhoudailiang on 2015/7/14. */ public class WaveView extends View { private Paint paint; private Path mPath; private float offset = 0.0f; // 控制正弦曲线的变化 private MyThread thread; private final float amplidute = 30; // 振幅 private float gradualY; // Y方向的渐变量 private float gradualX; // X方向的渐变量 private boolean isMoving = true; // 可以移动 public WaveView(Context context) { super(context); init(); } public WaveView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { // 初始化画笔 paint = new Paint(); paint.setAntiAlias(true); paint.setColor(Color.BLUE); paint.setStrokeWidth(2); // 初始化变量 gradualX = 0.02f; // 初始化路径 mPath = new Path(); // 初始化线程 thread = new MyThread(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); gradualY = getMeasuredHeight(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getMeasuredWidth(); int height = getMeasuredHeight(); mPath.reset(); for (float i = 0; i < width; i += 0.5) { float tmp = (float) (1.5 * Math.PI * i / width); float y = amplidute * (float)Math.sin(tmp + offset) + gradualY; if (i == 0) { mPath.moveTo(0f, y); } else { mPath.lineTo(i, y); } } mPath.lineTo(width, height); mPath.lineTo(0, height); mPath.close(); canvas.drawPath(mPath, paint); // 启动线程开始更新 if (!thread.isAlive() && isMoving) { thread.start(); } } class MyThread extends Thread { public void run() { while (isMoving) { offset = offset + gradualX > 2 * Math.PI ? 0 : offset + gradualX; gradualY -= 0.5; if (gradualY < -amplidute) { isMoving = false; break; } try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } postInvalidate(); } } } }
代码如上,很简单。其实这里还可以通过另一种方式实现,下篇文章进行介绍。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-08 02:17:11