今天我们来简单学习一下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>
效果如图: