zoukankan      html  css  js  c++  java
  • Android SurfaceView使用

    与View区别

    更新View任务太重会导致UI线程阻塞

    而SurfaceView不会,可以在UI线程之外更新UI

     工程代码 SurfaceViewDemo.zip

    ----------------------------------------------

    1. 使用SurfaceView 要点
    2. 创建单个图形
    3. 创建多个图形
    4. 绘制组合图形
    5. 使4中的组合图形动起来

    ----------------------------------------------

    1. 使用SurfaceView 要点

    * 通过 SurfaceHolder 控制Surface

    * 一定是在Surface创建之后开始画布操作, 一定在Surface创建之前结束画布操作

    集成 SurfaceView类,实现 SurfaceHolder.Callback 接口

    在构造函数中调用: getHolder().addCallback(this);

    框架如下:

    public class MyView extends SurfaceView implements SurfaceHolder.Callback {
        // 通过 SurfaceHolder 控制Surface
        
        public MyView(Context context) {
            super(context);
            getHolder().addCallback(this);
        }
        public void draw() {
            // 一定是在Surface创建之后开始画布操作
            Canvas canvas = getHolder().lockCanvas();
            // start
            
            // end, 一定在Surface创建之前结束画布操作
            getHolder().unlockCanvasAndPost(canvas);
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
            // Surface 改变的时候触发
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            draw();
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
        }
    }

    2. 创建单个图形

    修改如下,声明画笔 paint, 然后画一个红色的矩形

    private Paint paint = null;
    
    public MyView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        paint = new Paint();
        paint.setColor(Color.RED);
        getHolder().addCallback(this);
    }
    public void draw() {
        // 一定是在Surface创建之后开始画布操作
        Canvas canvas = getHolder().lockCanvas();
        // start
        canvas.drawColor(Color.WHITE);
        canvas.drawRect(0, 0, 100, 100, paint);
        
        // end, 一定在Surface创建之前结束画布操作
        getHolder().unlockCanvasAndPost(canvas);
    }

     

    3. 创建多个图形

    绘制两条垂直90度的直线,三个重要的步骤

    canvas.save();// 保存成可编辑状态
    canvas.rotate(90, getWidth()/2, getHeight()/2);  //画布旋转90度
    canvas.restore(); //重新恢复画布到正常状态(旋转前),否则影响后面的绘制

    public void draw() {
        // 一定是在Surface创建之后开始画布操作
        Canvas canvas = getHolder().lockCanvas();
        // start
        canvas.drawColor(Color.WHITE);
        canvas.save();// 保存成可编辑状态
        canvas.rotate(90, getWidth()/2, getHeight()/2);  //画布旋转90度
        canvas.drawLine(0, getHeight()/2, getWidth(), getHeight(), paint);
        canvas.restore(); //重新恢复画布到正常状态(旋转前)
        canvas.drawLine(0, getHeight()/2 + 100, getWidth(), getHeight()+100, paint);
        // end, 一定在Surface创建之前结束画布操作
        getHolder().unlockCanvasAndPost(canvas);
    }

     

    4. 绘制组合图形

     创建容器 Container 类: 可以添加、删除子视图, 绘制view

    创一个矩形Rec:

    创建 圆 Circle:

    在控件MyView中,添加一个容器,容器中放置一个矩形,矩形内放一个圆

    public class Container {
    
        private List<Container> children = null;
    
        public Container() {
            children = new ArrayList<Container>();
        }
    
        public void draw(Canvas canvas) {
            childrenView(canvas);
            for (Container c : children) {
                c.draw(canvas);
            }
        }
    
        public void addChirdrenView(Container c) {
            children.add(c);
        }
    
        public void removeChirdrenView(Container c) {
            children.remove(c);
        }
    
        public void childrenView(Canvas canvas) {
            // TODO Auto-generated method stub
        }
    }
    public class Rect extends Container {
    
        private Paint paint;
            
        public Rect(){
            paint = new Paint();
            paint.setColor(Color.RED);
        }
        
        @Override
        public void childrenView(Canvas canvas) {
            super.childrenView(canvas);
            canvas.drawRect(0, 0, 100, 100, paint);
        }
    }
    public class Circle extends Container {
        
        private Paint paint;
        
        public Circle(){
            paint = new Paint();
            paint.setColor(Color.BLUE);
        }
    
        @Override
        public void childrenView(Canvas canvas) {
            // 
            super.childrenView(canvas);
            canvas.drawCircle(60, 60, 50, paint);
        }
    }
    public class MyView extends SurfaceView implements SurfaceHolder.Callback {
        // 通过 SurfaceHolder 控制Surface
        
        private Container container;
        private Rect rect;
        private Circle circle;
    
        public MyView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
            container = new Container();
            rect = new Rect();
            circle = new Circle();
            rect.addChirdrenView(circle);
            container.addChirdrenView(rect);
            
            getHolder().addCallback(this);
        }
        
        @Override
        public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
            // Surface 改变的时候触发
            draw() ;
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
        }
        
        public void draw() {
            // 一定是在Surface创建之后开始画布操作
            Canvas canvas = getHolder().lockCanvas();
            // start
            canvas.drawColor(Color.WHITE);
            container.draw(canvas);
            // end, 一定在Surface创建之前结束画布操作
            getHolder().unlockCanvasAndPost(canvas);
        }
    
    }

    5. 使4中的组合图形动起来

    修改容器类Container:

    public void draw(Canvas canvas) {
        canvas.save();
        canvas.translate(getX(), getY());
        childrenView(canvas);
        for (Container c : children) {
            c.draw(canvas);
        }
        canvas.restore();
    }

    修改矩形:

    public void childrenView(Canvas canvas) {
        super.childrenView(canvas);
        canvas.drawRect(0, 0, 100, 100, paint);
        
        this.setY(this.getY()+3);
    }

    在 MyView 控件中增加timer

    private Timer timer = null;
    private TimerTask task = null;
    
    public void startTimer(){
        timer = new Timer();
        task = new TimerTask() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                draw();
            }
        };
        timer.schedule(task, 100, 100); //每100ms执行一次
    }
    
    public void stopTimer(){
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // surface 创建之后
        startTimer();
    }
    
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // surface 销毁之前
        stopTimer();
    }
    
    @Override
    protected void onDetachedFromWindow() {
        // TODO Auto-generated method stub
        stopTimer();  //不加这句,应用程序退出时会死
        super.onDetachedFromWindow();
    }

    工程代码 SurfaceViewDemo.zip

  • 相关阅读:
    asp.net jquery+ajax异步刷新1
    Android自定义组合控件:UIScrollLayout(支持界面滑动及左右菜单滑动)
    南京三星面试准备1--字符串
    如何有效的设立目标
    MySQL 主主复制
    POJ 2914 Minimum Cut 最小割算法题解
    openstack中虚拟机怎么与物理机通信
    SpringMVC+Spring+Mybatis+Mysql项目搭建
    Android面试准备 第二天 第五例 数据存储
    COCOS2D-X 3.0在MAC下创建新IOS项目:
  • 原文地址:https://www.cnblogs.com/carlo/p/4724075.html
Copyright © 2011-2022 走看看