• SurfaceView概述和基本使用


    Android屏幕刷新一遍时间间隔为16ms,如果view能够在16ms内完成所需要执行的绘图换作,那么在视觉上,界面就是流畅的,否则就会出现卡顿现象,在很多情况下,这些逻辑处理又是必须的,为了解决这个问题,Android 引用了surfaceView,在二个方面改进了View的绘图操作:

    使用双缓冲技术

    自带画布,支持在子线程中更新画布内容

    view和surfaceView使用场景:

    当界面需要被动更新时,用view较好,比如,与手势交互的场景,因为画面的更新是依赖ontouch来完成,所以可以直接使用invalidate函数,在这种一次touch和下一次touch时间长的话,就不会产生影响

    当界面需要主动刷新,使用surfaceView比较好,比如视频播放摄像头等

    基本用法:

    surfaceView派生View

    package com.loaderman.customviewdemo;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.SurfaceView;
    
    
    public class ViewGesturePath extends SurfaceView {
        private Paint mPaint;
        private Path mPath;
        public ViewGesturePath(Context context) {
            super(context);
            init();
        }
        public ViewGesturePath(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
        public ViewGesturePath(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        private void init(){
            setWillNotDraw(false);
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(5);
            mPaint.setColor(Color.RED);
    
            mPath = new Path();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            int x = (int)event.getX();
            int y = (int)event.getY();
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                mPath.moveTo(x,y);
                return true;
            }else if (event.getAction() == MotionEvent.ACTION_MOVE){
                mPath.lineTo(x,y);
            }
            postInvalidate();
    
    
            return super.onTouchEvent(event);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawPath(mPath,mPaint);
    
        }
    }
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:background="#ffffff"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/holo_red_dark"
            android:text="捕捉手势轨迹,画吧,少年"/>
        <com.loaderman.customviewdemo.ViewGesturePath
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    效果:

    正确用法:

    package com.loaderman.customviewdemo;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    
    public class SurfaceViewGesturePath extends SurfaceView {
        private Paint mPaint;
        private Path mPath;
    
        public SurfaceViewGesturePath(Context context) {
            super(context);
            init();
        }
    
        public SurfaceViewGesturePath(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public SurfaceViewGesturePath(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        private void init() {
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeWidth(5);
            mPaint.setColor(Color.RED);
    
            mPath = new Path();
    
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
    
            int x = (int) event.getX();
            int y = (int) event.getY();
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                mPath.moveTo(x, y);
                return true;
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                mPath.lineTo(x, y);
            }
            drawCanvas();
    
            return super.onTouchEvent(event);
        }
    
        private void drawCanvas() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    SurfaceHolder surfaceHolder = getHolder();
                    Canvas canvas = surfaceHolder.lockCanvas();//使用缓冲Canvas绘图
    
                    canvas.drawPath(mPath, mPaint);
    
                    surfaceHolder.unlockCanvasAndPost(canvas);
                }
            }).start();
        }
    }

    效果同上

  • 相关阅读:
    web移动端开发经验总结
    《前端JavaScript面试技巧》笔记一
    《SEO在网页制作中的应用》视频笔记
    web前端开发笔记(2)
    OAuth2.0理解和用法
    基于hdfs文件创建hive表
    kafka 配置事项
    centos7时间同步
    lambda架构
    hbase hadoop版本
  • 原文地址:https://www.cnblogs.com/loaderman/p/10231916.html
Copyright © 2020-2023  润新知