今天我们来简单学习一下android怎么实现一个正弦动画。
基本思路:
其实很简单,首先我们先实现一个静态的正弦曲线,然后改变正弦函数的相位,通知view进行刷新就可以了。
代码如下:
package com.example.customview.view;
import com.example.customview.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class SinView extends View {
private int height;
private int width;
private Path path;
private Paint paint;
private float waveHeight;
private int lineColor;//线的颜色
private int backColor;//背景色
private float amplitude;//振幅
private float frequency;//频率
private float startAngle = (float) (Math.PI/4);
private int i =0;
public SinView(Context context) {
this(context,null);
}
public SinView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context,attrs);
}
public SinView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
private void initView(Context context,AttributeSet attrs){
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.SinView);
amplitude = ta.getDimension(R.styleable.SinView_amplitude,100);
frequency = ta.getFloat(R.styleable.SinView_frequency,100);
lineColor = ta.getColor(R.styleable.SinView_lineColor,Color.GREEN);
backColor = ta.getColor(R.styleable.SinView_backColor,Color.WHITE);
paint = new Paint();
paint.setColor(lineColor);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
paint.setAntiAlias(true);
path = new Path();
ta.recycle();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
if(height == 0){
height = getMeasuredHeight();
waveHeight = Math.min(height, amplitude)-20;
Log.e("KFJKFJ", "高度"+waveHeight+"getMeasuredHeight()"+getMeasuredHeight()+"amplitude"+amplitude);
}
if(width == 0){
width = getMeasuredWidth();
}
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawColor(backColor);
for(i =0;i<width;i+=5){
float y = (float) (waveHeight/2 + waveHeight/2*Math.sin(i*(2*Math.PI/frequency)+startAngle))+10;
if(i==0){
//设置path的起点
path.moveTo(0,y);
}else{
//连线
path.lineTo(i,y);
}
}
postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
i = 0;
path.reset();
startAngle+=(Math.PI/4);
postInvalidate();
}
}, 200);
canvas.drawPath(path, paint);
}
}
attrs.xml的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
</declare-styleable>
<declare-styleable name="SinView">
<attr name="amplitude" format="dimension|reference" />
<attr name="lineColor" format="color|reference" />
<attr name="backColor" format="color|reference" />
<attr name="frequency" format="float" />
</declare-styleable>
</resources>
使用如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<com.example.customview.view.SinView
android:layout_width="200dp"
android:layout_height="300dp"
app:amplitude="400dp"
app:backColor="#0000ff"
app:frequency="300"
app:lineColor="#00ff00"
android:paddingTop="10dp"
android:paddingBottom="10dp"
/>
</LinearLayout>
效果如图: