zoukankan      html  css  js  c++  java
  • Android 利用SurfaceView进行图形绘制

    SurfaceView使用介绍

      SurfaceView是View的一个特殊子类,它的目的是另外提供一个线程进行绘制操作。

      要使用SurfaceView进行绘制,步骤如下:

      1.用SurfaceView进行绘制,首先要创建一个类,继承 SurfaceView,同时这个类应该实现SurfaceHolder.Callback接口。

      这个接口中的三个回调函数(surfaceChanged(SurfaceHolder holder, int format, int width, int height),surfaceCreated(SurfaceHolder holder),surfaceDestroyed(SurfaceHolder holder))分别对应Surface何时更改、创建和销毁。

      2.对Surface对象的操作是通过SurfaceHolder来进行的。所以,在你的SurfaceView类初始化的时候,你需要调用 getHolder()来获得SurfaceHolder对象,然后用addCallback()加上回调接口(因为你的类实现了相应的接口,所以此处传入this即可)。

      3.在你的SurfaceView类中应该建立一个线程类,处理绘制操作。为此,要向这个线程类传递上面获得的SurfaceHolder对象。

      4.绘制:在线程类的run()方法中进行绘制操作,通过lockCanvas()方法获得Canvas对象,然后就可以用这个对象进行绘制,绘制完成后调用unlockCanvasAndPost(),传入Canvas对象,这时Surface将会按Canvas进行绘制。

      注意:每次利用SurfaceHolder获得画布时,前一次的内容将会保留。

    代码示例

    复制代码
    package com.example.hellosurfaceview;
    
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    public class MySurfaceView extends SurfaceView implements
            SurfaceHolder.Callback
    {
    
        private DrawThread mThread = null;
    
        public MySurfaceView(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
            init();
        }
    
        public MySurfaceView(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            init();
        }
    
        public MySurfaceView(Context context)
        {
            super(context);
            init();
        }
    
        private void init()
        {
            Log.d(AppConstants.LOG_TAG, "init");
    
            SurfaceHolder holder = getHolder();
            holder.addCallback(this);
    
            mThread = new DrawThread(holder);
    
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh)
        {
            Log.d(AppConstants.LOG_TAG, "onSizeChanged");
            super.onSizeChanged(w, h, oldw, oldh);
    
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder)
        {
            Log.d(AppConstants.LOG_TAG, "surfaceCreated");
            mThread.setRun(true);
            mThread.start();
    
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height)
        {
            Log.d(AppConstants.LOG_TAG, "surfaceChanged");
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder)
        {
            Log.d(AppConstants.LOG_TAG, "surfaceDestroyed");
            mThread.setRun(false);
    
        }
    
        /**
         * 绘制线程类
         * 
         */
        public class DrawThread extends Thread
        {
            private SurfaceHolder mHolder = null;
            private boolean isRun = false;
    
            public DrawThread(SurfaceHolder holder)
            {
                Log.d(AppConstants.LOG_TAG, "DrawThread Constructor");
                mHolder = holder;
    
            }
    
            public void setRun(boolean isRun)
            {
                Log.d(AppConstants.LOG_TAG, "DrawThread setRun: " + isRun);
                this.isRun = isRun;
            }
    
            @Override
            public void run()
            {
                Log.d(AppConstants.LOG_TAG, "DrawThread run");
                int count = 0;
    
                while (isRun)
                {
                    Canvas canvas = null;
                    synchronized (mHolder)
                    {
                        try
                        {
                            Log.d(AppConstants.LOG_TAG, "Drawing-------------");
                            canvas = mHolder.lockCanvas();
                            canvas.drawColor(Color.WHITE);
                            Paint p = new Paint();
                            p.setColor(Color.BLACK);
    
                            Rect r = new Rect(100, 50, 300, 250);
                            canvas.drawRect(r, p);
                            canvas.drawText("这是第" + (count++) + "秒", 100, 310, p);
    
                            Thread.sleep(1000);// 睡眠时间为1秒
    
                        }
                        catch (Exception e)
                        {
                            Log.d(AppConstants.LOG_TAG, "throw Exception in run");
                            e.printStackTrace();
    
                        }
                        finally
                        {
                            if (null != canvas)
                            {
                                mHolder.unlockCanvasAndPost(canvas);
                            }
                        }
    
                    }
    
                }
            }
    
        }
    
    }
    复制代码

    参考资料

      官方文档:

      API Guides:Canvas and Drawables

      http://developer.android.com/guide/topics/graphics/2d-graphics.html

      SurfaceView:

      http://developer.android.com/reference/android/view/SurfaceView.html

      SurfaceHolder:

      http://developer.android.com/reference/android/view/SurfaceHolder.html

      博客:

      Android之SurfaceView学习(一):

      http://www.cnblogs.com/xuling/archive/2011/06/06/android.html

      剖析 SurfaceView:

      http://blog.csdn.net/xiaominghimi/article/details/6090575

  • 相关阅读:
    sqlserver备份后无法还原的解决方法
    Silverlight如何与JS相互调用
    【转】体验 Silverlight 5 3D开发之环境搭配篇
    C#实现邮箱搬家功能(1):Pop3协议介绍
    【转】针对大数据量表的优化查询
    Centos7Docker安装Redis
    Centos7.*Consul安装配置
    Centos7Docker安装nacos
    Centos7Docker安装neo4j
    Spring框架根据传入参数动态的修改注解属性的值
  • 原文地址:https://www.cnblogs.com/xgjblog/p/6144464.html
Copyright © 2011-2022 走看看