package yifeiyuan.practice.practicedemos.wave;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
/**
*
* @author chenjing
*
*/
public class WaveView2 extends View
{
private int mViewWidth;
private int mViewHeight;
/**
* ˮλ��
*/
private float mLevelLine;
/**
* ���������
*/
private float mWaveHeight = 80;
/**
* ����
*/
private float mWaveWidth = 200;
/**
* �����ص�����ߵIJ���
*/
private float mLeftSide;
private float mMoveLen;
/**
* ˮ��ƽ���ٶ�
*/
public static final float SPEED = 1.7f;
private List<Point> mPointsList;
private Paint mPaint;
private Paint mTextPaint;
private Path mWavePath;
private boolean isMeasured = false;
private Timer timer;
private MyTimerTask mTask;
Handler updateHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// ��¼ƽ����λ��
mMoveLen += SPEED;
// ˮλ����
mLevelLine -= 0.1f;
if (mLevelLine < 0)
mLevelLine = 0;
mLeftSide += SPEED;
// ����ƽ��
for (int i = 0; i < mPointsList.size(); i++)
{
mPointsList.get(i).setX(mPointsList.get(i).getX() + SPEED);
switch (i % 4)
{
case 0:
case 2:
mPointsList.get(i).setY(mLevelLine);
break;
case 1:
mPointsList.get(i).setY(mLevelLine + mWaveHeight);
break;
case 3:
mPointsList.get(i).setY(mLevelLine - mWaveHeight);
break;
}
}
if (mMoveLen >= mWaveWidth)
{
mMoveLen = 0;
resetPoints();
}
invalidate();
}
};
/**
* ���е��x��궼��ԭ����ʼ״̬��Ҳ����һ������ǰ��״̬
*/
private void resetPoints()
{
mLeftSide = -mWaveWidth;
for (int i = 0; i < mPointsList.size(); i++)
{
mPointsList.get(i).setX(i * mWaveWidth / 4 - mWaveWidth);
}
}
public WaveView2(Context context)
{
super(context);
init();
}
public WaveView2(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
public WaveView2(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init();
}
private void init()
{
mPointsList = new ArrayList<Point>();
timer = new Timer();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.FILL);
mPaint.setColor(Color.BLUE);
mTextPaint = new Paint();
mTextPaint.setColor(Color.WHITE);
mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setTextSize(30);
mWavePath = new Path();
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus)
{
super.onWindowFocusChanged(hasWindowFocus);
start();
}
private void start()
{
if (mTask != null)
{
mTask.cancel();
mTask = null;
}
mTask = new MyTimerTask(updateHandler);
timer.schedule(mTask, 0, 10);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!isMeasured)
{
isMeasured = true;
mViewHeight = getMeasuredHeight();
mViewWidth = getMeasuredWidth();
// ˮλ�ߴ�����¿�ʼ����
mLevelLine = mViewHeight;
// ���View��ȼ��㲨�η�ֵ
mWaveHeight = mViewWidth / 2.5f;
// ���������ı�View���Ҳ����View��ֻ�ܿ����ķ�֮һ�����Σ��������ʹ��������
mWaveWidth = mViewWidth * 4;
// ������صľ���Ԥ��һ������
mLeftSide = -mWaveWidth;
// ��������ڿɼ��View����������ɼ������Σ�ע��n��ȡ��
int n = (int) Math.round(mViewWidth / mWaveWidth + 0.5);
// n��������Ҫ4n+1���㣬��������ҪԤ��һ�������������������������Ҫ4n+5����
for (int i = 0; i < (4 * n + 5); i++)
{
// ��P0��ʼ��ʼ����P4n+4���ܹ�4n+5����
float x = i * mWaveWidth / 4 - mWaveWidth;
float y = 0;
switch (i % 4)
{
case 0:
case 2:
// ���λ��ˮλ����
y = mLevelLine;
break;
case 1:
// ���²����Ŀ��Ƶ�
y = mLevelLine + mWaveHeight;
break;
case 3:
// ���ϲ����Ŀ��Ƶ�
y = mLevelLine - mWaveHeight;
break;
}
mPointsList.add(new Point(x, y));
}
}
}
@Override
protected void onDraw(Canvas canvas)
{
mWavePath.reset();
int i = 0;
mWavePath.moveTo(mPointsList.get(0).getX(), mPointsList.get(0).getY());
for (; i < mPointsList.size() - 2; i = i + 2)
{
mWavePath.quadTo(mPointsList.get(i + 1).getX(),
mPointsList.get(i + 1).getY(), mPointsList.get(i + 2)
.getX(), mPointsList.get(i + 2).getY());
}
mWavePath.lineTo(mPointsList.get(i).getX(), mViewHeight);
mWavePath.lineTo(mLeftSide, mViewHeight);
mWavePath.close();
// mPaint��Style��FILL����������Path����
canvas.drawPath(mWavePath, mPaint);
// ���ưٷֱ�
canvas.drawText("" + ((int) ((1 - mLevelLine / mViewHeight) * 100))
+ "%", mViewWidth / 2, mLevelLine + mWaveHeight
+ (mViewHeight - mLevelLine - mWaveHeight) / 2, mTextPaint);
}
class MyTimerTask extends TimerTask
{
Handler handler;
public MyTimerTask(Handler handler)
{
this.handler = handler;
}
@Override
public void run()
{
handler.sendMessage(handler.obtainMessage());
}
}
class Point
{
private float x;
private float y;
public float getX()
{
return x;
}
public void setX(float x)
{
this.x = x;
}
public float getY()
{
return y;
}
public void setY(float y)
{
this.y = y;
}
public Point(float x, float y)
{
this.x = x;
this.y = y;
}
}
}