在SurfaceView中模拟正弦波
本工程主要实现在SurfaceView中模拟正弦波形,首先把正弦波的Y轴的数据存储在数组里。使用canvas.drawline划线。
有两个问题:Timer和TimerTask的使用和划线区域的锁定
(1) Timer和TimerTask调用cancel之后,Timer和TimerTask终止,但是Timer还存在,当再次使用使用Time. schedule(TimerTask task,long delay, long period)程序会报错,要解决这个错误首先要调用Timer.cancel()终止定时器,然后给Timer和TimerTask赋值为null。再次使用使用重新声明Timer和TimerTask。
(2) 划线区域的锁定最好是画那一块位置锁定那一块。这样画图效果较好,同时曲线的连接也比较好,不会出现断点。
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:text="@string/button1" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:text="@string/button2" />
</LinearLayout>
<SurfaceView
android:id="@+id/surfaceView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
主程序:
package com.example.sintest;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class Sin1Activity extends Activity {
private Button btnSimpleDraw,btnTimerDraw;
private SurfaceView sfv;
private SurfaceHolder sfd;
private Timer mTimer;
private MyTimerTask mTimerTask;
int arrayY[],oldX,oldY,centerY,currentX;
//设置TimerTask运行标志位
private boolean taskFlag = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sin1);
//获得控件的引用
btnSimpleDraw = (Button)findViewById(R.id.button1);
btnTimerDraw = (Button)findViewById(R.id.button2);
sfv = (SurfaceView)findViewById(R.id.surfaceView1);
sfd = sfv.getHolder();
//数据初始化
centerY = (getWindowManager().getDefaultDisplay().getHeight())/2;
arrayY = new int[getWindowManager().getDefaultDisplay().getWidth()];
for (int i = 0; i < arrayY.length; i++) {// 计算正弦波
arrayY[i] = centerY
- (int) (100 * Math.sin(i * 2 * Math.PI / 180));
}
btnSimpleDraw.setOnClickListener(new ButtonListener());
btnTimerDraw.setOnClickListener(new ButtonListener());
}
public void simpleDraw(int length) {
length = length - 1;
Canvas canvas = sfd.lockCanvas(new Rect(oldX, 0, oldX + length,
getWindowManager().getDefaultDisplay().getHeight()));
Paint mPaint = new Paint();
mPaint.setColor(Color.GREEN);
mPaint.setStrokeWidth(2);
int y;
for (int i = oldX + 1; i <= length; i++) {
y = arrayY[i];
canvas.drawLine(oldX, oldY, i, y, mPaint);
oldX = i;
oldY = y;
}
sfd.unlockCanvasAndPost(canvas);
}
//清屏程序
public void clearScreen() {
Canvas canvas = sfd.lockCanvas(null);
canvas.drawColor(Color.BLACK);
sfd.unlockCanvasAndPost(canvas);
}
//按键监听器类,实现按键的事件处理
class ButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == btnSimpleDraw) {
//先判断TimerTask是否运行,如果运行就取消
if (taskFlag) {
mTimer.cancel();
mTimer = null;
mTimerTask = null;
taskFlag = false;
}
//清一下屏幕
clearScreen();
//设置画图的起点
oldX = 0;
oldY = centerY;
simpleDraw(arrayY.length);
}
if (v == btnTimerDraw) {
if (taskFlag) {
mTimer.cancel();
mTimerTask = null;
mTimer = null;
}
//清屏
clearScreen();
//设置画图的起点
oldX = 0;
oldY = centerY;
currentX = 0;
taskFlag = true;
mTimer = new Timer();
mTimerTask = new MyTimerTask();
mTimer.schedule(mTimerTask, 0, 10);
}
}
}
//定时器任务类,用于实现给定时处理的任务
class MyTimerTask extends TimerTask{
@Override
public void run() {
// TODO Auto-generated method stub
simpleDraw(currentX);
currentX++;
if (currentX == arrayY.length+1) {
clearScreen();
currentX = 0;
oldX = 0;
oldY = centerY;
}
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mTimerTask.cancel();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_sin1, menu);
return true;
}
}
工程文件:http://download.csdn.net/detail/zhaoshiqing7/4550032