当前位置:首页>> Android应用之SurfaceView

Android应用之SurfaceView

发布时间:2011-11-26作者:智汇小新

    文章介绍了SurfaceView的用法。网上介绍SurfaceView的用法有很多,写法也层出不同,例如继承SurfaceView类,或者继承SurfaceHolder.Callback类等,这个可以根据功能实际需要自己选择,我这里就直接在普通的用户界面调用SurfaceHolder的lockCanvas和unlockCanvasAndPost。

    先来看看程序运行的截图:

截图1主要演示了直接把正弦波绘画在SurfaceView上

 

对比上面的左右两图,右图用.lockCanvas(null),而左图用.lockCanvas(new Rect(oldX, 0, oldX + length,
    getWindowManager().getDefaultDisplay().getHeight())),对比一下两个效果,由于左图是按指定Rect绘画,所以效率会比右图的全控件绘画高些,并且在清屏之后(canvas.drawColor(Color.BLACK))不会留有上次绘画的残留。

 

接下来贴出main.xml的源码:

view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" android:layout_height="fill_parent" 
    android:orientation="vertical"> 
 
    <LinearLayout android:id="@+id/LinearLayout01" 
        android:layout_width="wrap_content" android:layout_height="wrap_content"> 
        <Button android:id="@+id/Button01" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:text="简单绘画"></Button> 
        <Button android:id="@+id/Button02" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:text="定时器绘画"></Button> 
    </LinearLayout> 
    <SurfaceView android:id="@+id/SurfaceView01" 
        android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView> 
</LinearLayout> 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent" android:layout_height="fill_parent"
 android:orientation="vertical">

 <LinearLayout android:id="@+id/LinearLayout01"
  android:layout_width="wrap_content" android:layout_height="wrap_content">
  <Button android:id="@+id/Button01" android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:text="简单绘画"></Button>
  <Button android:id="@+id/Button02" android:layout_width="wrap_content"
   android:layout_height="wrap_content" android:text="定时器绘画"></Button>
 </LinearLayout>
 <SurfaceView android:id="@+id/SurfaceView01"
  android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView>
</LinearLayout>
 

接下来贴出程序源码:

view plaincopy to clipboardprint?
package com.testSurfaceView;  
 
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.util.Log;  
import android.view.SurfaceHolder;  
import android.view.SurfaceView;  
import android.view.View;  
import android.widget.Button;  
 
public class testSurfaceView extends Activity {  
    /** Called when the activity is first created. */ 
    Button btnSimpleDraw, btnTimerDraw;  
    SurfaceView sfv;  
    SurfaceHolder sfh;  
 
    private Timer mTimer;  
    private MyTimerTask mTimerTask;  
    int Y_axis[],//保存正弦波的Y轴上的点  
    centerY,//中心线  
    oldX,oldY,//上一个XY点   
    currentX;//当前绘制到的X轴上的点  
 
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
 
        btnSimpleDraw = (Button) this.findViewById(R.id.Button01);  
        btnTimerDraw = (Button) this.findViewById(R.id.Button02);  
        btnSimpleDraw.setOnClickListener(new ClickEvent());  
        btnTimerDraw.setOnClickListener(new ClickEvent());  
        sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01);  
        sfh = sfv.getHolder();  
 
        //动态绘制正弦波的定时器  
        mTimer = new Timer();  
        mTimerTask = new MyTimerTask();  
 
        // 初始化y轴数据  
        centerY = (getWindowManager().getDefaultDisplay().getHeight() - sfv  
                .getTop()) / 2;  
        Y_axis = new int[getWindowManager().getDefaultDisplay().getWidth()];  
        for (int i = 1; i < Y_axis.length; i++) {// 计算正弦波  
            Y_axis[i - 1] = centerY  
                    - (int) (100 * Math.sin(i * 2 * Math.PI / 180));  
        }  
    }  
 
    class ClickEvent implements View.OnClickListener {  
 
        @Override 
        public void onClick(View v) {  
 
            if (v == btnSimpleDraw) {  
                SimpleDraw(Y_axis.length-1);//直接绘制正弦波  
              
            } else if (v == btnTimerDraw) {  
                oldY = centerY;  
                mTimer.schedule(mTimerTask, 0, 5);//动态绘制正弦波  
            }  
 
        }  
 
    }  
 
    class MyTimerTask extends TimerTask {  
        @Override 
        public void run() {  
 
            SimpleDraw(currentX);  
            currentX++;//往前进  
            if (currentX == Y_axis.length - 1) {//如果到了终点,则清屏重来  
                ClearDraw();  
                currentX = 0;  
                oldY = centerY;  
            }  
        }  
 
    }  
      
    /* 
     * 绘制指定区域 
     */ 
    void SimpleDraw(int length) {  
        if (length == 0)  
            oldX = 0;  
        Canvas canvas = sfh.lockCanvas(new Rect(oldX, 0, oldX + length,  
                getWindowManager().getDefaultDisplay().getHeight()));// 关键:获取画布  
        Log.i("Canvas:",  
                String.valueOf(oldX) + "," + String.valueOf(oldX + length));  
 
        Paint mPaint = new Paint();  
        mPaint.setColor(Color.GREEN);// 画笔为绿色  
        mPaint.setStrokeWidth(2);// 设置画笔粗细  
 
        int y;  
        for (int i = oldX + 1; i < length; i++) {// 绘画正弦波  
            y = Y_axis[i - 1];  
            canvas.drawLine(oldX, oldY, i, y, mPaint);  
            oldX = i;  
            oldY = y;  
        }  
        sfh.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像  
    }  
 
    void ClearDraw() {  
        Canvas canvas = sfh.lockCanvas(null);  
        canvas.drawColor(Color.BLACK);// 清除画布  
        sfh.unlockCanvasAndPost(canvas);  
 
    }  


package com.testSurfaceView;

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.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;

public class testSurfaceView extends Activity {
 /** Called when the activity is first created. */
 Button btnSimpleDraw, btnTimerDraw;
 SurfaceView sfv;
 SurfaceHolder sfh;

 private Timer mTimer;
 private MyTimerTask mTimerTask;
 int Y_axis[],//保存正弦波的Y轴上的点
 centerY,//中心线
 oldX,oldY,//上一个XY点
 currentX;//当前绘制到的X轴上的点

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  btnSimpleDraw = (Button) this.findViewById(R.id.Button01);
  btnTimerDraw = (Button) this.findViewById(R.id.Button02);
  btnSimpleDraw.setOnClickListener(new ClickEvent());
  btnTimerDraw.setOnClickListener(new ClickEvent());
  sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01);
  sfh = sfv.getHolder();

  //动态绘制正弦波的定时器
  mTimer = new Timer();
  mTimerTask = new MyTimerTask();

  // 初始化y轴数据
  centerY = (getWindowManager().getDefaultDisplay().getHeight() - sfv
    .getTop()) / 2;
  Y_axis = new int[getWindowManager().getDefaultDisplay().getWidth()];
  for (int i = 1; i < Y_axis.length; i++) {// 计算正弦波
   Y_axis[i - 1] = centerY
     - (int) (100 * Math.sin(i * 2 * Math.PI / 180));
  }
 }

 class ClickEvent implements View.OnClickListener {

  @Override
  public void onClick(View v) {

   if (v == btnSimpleDraw) {
    SimpleDraw(Y_axis.length-1);//直接绘制正弦波
   
   } else if (v == btnTimerDraw) {
    oldY = centerY;
    mTimer.schedule(mTimerTask, 0, 5);//动态绘制正弦波
   }

  }

 }

 class MyTimerTask extends TimerTask {
  @Override
  public void run() {

   SimpleDraw(currentX);
   currentX++;//往前进
   if (currentX == Y_axis.length - 1) {//如果到了终点,则清屏重来
    ClearDraw();
    currentX = 0;
    oldY = centerY;
   }
  }

 }
 
 /*
  * 绘制指定区域
  */
 void SimpleDraw(int length) {
  if (length == 0)
   oldX = 0;
  Canvas canvas = sfh.lockCanvas(new Rect(oldX, 0, oldX + length,
    getWindowManager().getDefaultDisplay().getHeight()));// 关键:获取画布
  Log.i("Canvas:",
    String.valueOf(oldX) + "," + String.valueOf(oldX + length));

  Paint mPaint = new Paint();
  mPaint.setColor(Color.GREEN);// 画笔为绿色
  mPaint.setStrokeWidth(2);// 设置画笔粗细

  int y;
  for (int i = oldX + 1; i < length; i++) {// 绘画正弦波
   y = Y_axis[i - 1];
   canvas.drawLine(oldX, oldY, i, y, mPaint);
   oldX = i;
   oldY = y;
  }
  sfh.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像
 }

 void ClearDraw() {
  Canvas canvas = sfh.lockCanvas(null);
  canvas.drawColor(Color.BLACK);// 清除画布
  sfh.unlockCanvasAndPost(canvas);

 }
}

注意一下 for (int i = oldX + 1; i < length; i++) {// 绘画正弦波 这句,在.lockCanvas()指定Rect内减少循环画线的次数,可以提高绘图效率。

 

公司简介

宜科(天津)电子有限公司是中国工业自动化的领军企业,于2003年在天津投资成立,销售和服务网络覆盖全国。作为中国本土工业自动化产品的提供商和智能制造解决方案的供应商,宜科在汽车、汽车零部件、工程机械、机器人、食品制药、印刷包装、纺织机械、物流设备、电子制造等诸多领域占据领先地位。宜科为智慧工厂的整体规划实施提供自系统层、控制层、网络层到执行层自上而下的全系列服务,产品及解决方案涵盖但不局限于云平台、MES制造执行系统、工业现场总线、工业以太网、工业无线通讯、机器人及智能设备组成的自动化生产线、自动化电气控制系统集成、智能物流仓储系统等,以实现真正智能化的生产制造,从而带来生产力和生产效率的大幅提升,以及对生产灵活性和生产复杂性的管理能力的大幅提升。多年来,宜科以创新的技术、卓越的解决方案和产品坚持不懈地为中国制造业的发展提供全面支持,并以出众的品质和令人信赖的可靠性、领先的技术成就、不懈的创新追求,在业界独树一帜。帮助中国制造业转型升级,加速智能制造进程,成为中国工业4.0智慧工厂解决方案当之无愧的践行者。

更多详情>>

联系我们

  • 联系人:章清涛
  • 热线:18611695135
  • 电话:
  • 传真:
  • 邮箱:18210150532@139.com

Copyright © 2015 ilinki.net Inc. All rights reserved. 智汇工业版权所有

电话:010-62314658 邮箱:service@ilinki.net

主办单位:智汇万联(北京)信息技术有限公司

京ICP备15030148号-1