zoukankan      html  css  js  c++  java
  • SurfaceView的一个小应用:开发示波器

    SurfaceView与普通View还有一个重要区别:View的绘图必须在UI线程中进行,但SurfaceView不存在这个问题,因为它是由SurfaceHolder来完成的。所以对于View组件,如果绘图时间过长,会阻塞UI主线程,而SurfaceHolder则会启动新的线程去更新SurfaceView的绘制,不会阻塞UI线程。

    下面的程序是通过SurfaceView绘制正玄曲线和余玄曲线的示例,代码如下:

    Activity:

    package com.home.showwave;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    import android.app.Activity;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.os.Bundle;
    import android.view.SurfaceHolder;
    import android.view.SurfaceHolder.Callback;
    import android.view.SurfaceView;
    import android.view.View;
    
    public class ShowWaveActivity extends Activity {
    	private SurfaceHolder holder;
    	private SurfaceView surface;
    	private Paint paint;
    	private final int HEIGHT = 320;
    	// 要绘制的曲线的水平宽度
    	private final int WIDTH = 500;
    	// 离屏幕左边界的起始距离
    	private final int X_OFFSET = 5;
    	// 初始化X坐标
    	private int cx = X_OFFSET;
    	// 实际的Y轴的位置
    	private int centerY = HEIGHT / 2;
    	private Timer timer = new Timer();
    	private TimerTask task = null;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_show_wave);
    		// 获得SurfaceView对象
    		surface = (SurfaceView) findViewById(R.id.activity_show_wave_sv);
    		// 初始化SurfaceHolder对象
    		holder = surface.getHolder();
    		paint = new Paint();
    		paint.setColor(Color.GREEN);
    		paint.setStrokeWidth(3);
    
    	}
    
    	public void click(final View v) {
    		drawBackGround(holder);
    		cx = X_OFFSET;
    		if (task != null) {
    			task.cancel();
    		}
    		task = new TimerTask() {
    
    			@Override
    			public void run() {
    				// 根据是正玄还是余玄和X坐标确定Y坐标
    				int cy = v.getId() == R.id.activity_show_wave_btn_sin ? centerY
    						- (int) (100 * Math.sin((cx - 5) * 2 * Math.PI / 150))
    						: centerY
    								- (int) (100 * Math.cos((cx - 5) * 2 * Math.PI
    										/ 150));
    				Canvas canvas = holder.lockCanvas(new Rect(cx, cy - 2, cx + 2,
    						cy + 2));
    				// 根据X,Y坐标画点
    				canvas.drawPoint(cx, cy, paint);
    				cx++;
    				// 超过指定宽度,线程取消,停止画曲线
    				if (cx > WIDTH) {
    					task.cancel();
    					task = null;
    				}
    				// 提交修改
    				holder.unlockCanvasAndPost(canvas);
    			}
    		};
    		timer.schedule(task, 0, 30);
    		holder.addCallback(new Callback() {
    
    			@Override
    			public void surfaceChanged(SurfaceHolder holder, int format,
    					int width, int height) {
    				drawBackGround(holder);
    			}
    
    			@Override
    			public void surfaceCreated(SurfaceHolder holder) {
    
    			}
    
    			@Override
    			public void surfaceDestroyed(SurfaceHolder holder) {
    				timer.cancel();
    			}
    		});
    	}
    
    	private void drawBackGround(SurfaceHolder holder) {
    		Canvas canvas = holder.lockCanvas();
    		// 绘制白色背景
    		canvas.drawColor(Color.WHITE);
    		Paint p = new Paint();
    		p.setColor(Color.BLACK);
    		p.setStrokeWidth(2);
    		// 绘制坐标轴
    		canvas.drawLine(X_OFFSET, centerY, WIDTH, centerY, p);
    		canvas.drawLine(X_OFFSET, 40, X_OFFSET, HEIGHT, p);
    		holder.unlockCanvasAndPost(canvas);
    		holder.lockCanvas(new Rect(0, 0, 0, 0));
    		holder.unlockCanvasAndPost(canvas);
    	}
    }
    


    布局XML:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        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_horizontal"
            android:orientation="horizontal" >
    
            <Button
                android:id="@+id/activity_show_wave_btn_sin"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click"
                android:text="正玄曲线" />
    
            <Button
                android:id="@+id/activity_show_wave_btn_cos"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="click"
                android:text="余玄曲线" />
        </LinearLayout>
    
        <SurfaceView
            android:id="@+id/activity_show_wave_sv"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>


     

  • 相关阅读:
    香港2013迷你制汇节即将启幕
    neuroph轻量级神经网络框架
    java如何实现python的urllib.quote(str,safe='/')
    python 的日志logging模块
    Python 代码使用pdb调试技巧
    python中reload(module)的用法,以及错误提示
    Notepad++如何取消打开最近的历史文件
    机器学习--入门答疑
    计算机的启动过程
    缓存设计
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3184802.html
Copyright © 2011-2022 走看看