21天学习android开发教程之SurfaceView

 更新时间:2016年02月04日 17:13:55   投稿:lijiao  
21天学习android开发教程之SurfaceView,SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,操作相对简单,感兴趣的小伙伴们可以参考一下

上一篇文章介绍了MediaPlayer相关内容,这次用两篇文章来介绍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的源码:

<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 android:id="@+id/Button02" android:layout_width="wrap_content" 
            android:layout_height="wrap_content" android:text="定时器绘画">
    
    <surfaceview android:id="@+id/SurfaceView01" 
        android:layout_width="fill_parent" android:layout_height="fill_parent">

接下来贴出程序源码:

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);

    }
}

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。

相关文章

  • Android编程实现变化的双重选择框功能示例

    Android编程实现变化的双重选择框功能示例

    这篇文章主要介绍了Android编程实现变化的双重选择框功能,结合实例形式分析了Android双重选择框功能的样式布局与功能实现技巧,需要的朋友可以参考下
    2017-10-10
  • Android选中突出背景效果的底部导航栏功能

    Android选中突出背景效果的底部导航栏功能

    这篇文章主要介绍了Android选中突出背景效果的底部导航栏功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Android调用系统默认浏览器访问的方法

    Android调用系统默认浏览器访问的方法

    这篇文章主要介绍了Android调用系统默认浏览器访问的方法的相关资料,需要的朋友可以参考下
    2016-03-03
  • Android XML数据解析要点介绍

    Android XML数据解析要点介绍

    这篇文章主要为大家介绍了Android XML数据解析要点介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Android 中okhttp自定义Interceptor(缓存拦截器)

    Android 中okhttp自定义Interceptor(缓存拦截器)

    这篇文章主要介绍了Android 中okhttp自定义Interceptor(缓存拦截器)的相关资料,需要的朋友可以参考下
    2017-03-03
  • Kotlin自定义View系列教程之标尺控件(选择身高、体重等)的实现

    Kotlin自定义View系列教程之标尺控件(选择身高、体重等)的实现

    这篇文章主要给大家介绍了关于Kotlin自定义View系列教程之标尺控件(选择身高、体重等)实现的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-07-07
  • Android 使用XML做动画UI的深入解析

    Android 使用XML做动画UI的深入解析

    在Android应用程序,使用动画效果,能带给用户更好的感觉。做动画可以通过XML或Android代码。本教程中,介绍使用XML来做动画。在这里,介绍基本的动画,如淡入,淡出,旋转等,需要的朋友可以参考下
    2013-07-07
  • 详解Android中接口回调、方法回调

    详解Android中接口回调、方法回调

    在Android开发中我们很多地方都用到了方法的回调,回调就是把方法的定义和功能导入实现分开的一种机制,目的是为了解耦他的本质是基于观察者设计模式,即观察者设计模式的的简化版。本文主要对Android中接口回调、方法回调进行详细介绍,下面跟着小编一起来看下吧
    2017-01-01
  • android使用PullToRefresh实现下拉刷新和上拉加载

    android使用PullToRefresh实现下拉刷新和上拉加载

    本篇文章主要介绍了android使用PullToRefresh实现下拉刷新和上拉加载,具有一定的参考价值,有兴趣的可以了解一下。
    2016-12-12
  • 一行代码教你解决Scrollview和TextInput焦点获取问题

    一行代码教你解决Scrollview和TextInput焦点获取问题

    这篇文章主要为大家介绍了一行代码教你解决Scrollview和TextInput焦点获取问题,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论