SurfaceView 的一般绘制View用法(一)

来源:互联网 发布:打印机没有usb端口选择 编辑:程序博客网 时间:2024/06/07 11:27

前段时间写了不少关于自定义View相关的文章 , 最近两个项目同时开工,忙成狗了,这不是不写博客的理由哈,今晚写一篇关于SurfaceView相关的博客 ,

还是和以前一样,今天写一个基本用法 ,下一篇写一篇常用的用法 ,这个是一个简单的绘制动态的View, 以前一直是继承View, 但是有时动态比较多的话 ,比如上一篇吃豆豆的View,因为绘制的频率颇高,用SurfaceView是比较好的 , 不然画面看起来会有点卡顿的现象,

先看一个SurfaceView写的一个progressBar的图


图片是看不出SurfaceView的有点,但是频繁绘制图片的话,比如说绘制股票走势图,心跳图,性能的有事就明显不一样了,直接看代码

今天只是一个简答的实现, 代码比较简单,

1:需要继承SurfaceView , SurfaceHolder.callBack,和线程的Runnable

2 :线程里面写一个死循环,不停的绘制 ,

3 :View创建的时候,开始绘制 ,View销毁的时候,停止绘制,增加一个Boolean类型的控制值
4:绘制的时候,需要锁住holder . 

5:然后就是在该停止的时候加一个判断 ,不要做无用的绘制,消耗内存

看代码,注释比较详细

=================================================================

package com.reeman.demo.viewcustom;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {    SurfaceHolder mHolder;    Canvas mCanvas;    private boolean mIsDrawing;    public MySurfaceView(Context context) {        this(context, null);    }    public MySurfaceView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initView();    }    Paint mPaint;    private void initView() {        mHolder = getHolder();        mHolder.addCallback(this);        //使用键盘可以获取焦点        setFocusable(true);        //触摸可以获取焦点        setFocusableInTouchMode(true);        //博爱吃屏幕常亮        this.setKeepScreenOn(true);        //paint初始化        mPaint = new Paint();        mPaint.setColor(Color.RED);        mPaint.setAntiAlias(true);        mPaint.setStyle(Paint.Style.FILL);    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        mIsDrawing = true;        new Thread(this).start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        mIsDrawing = false;    }    @Override    public void run() {        while (mIsDrawing) {            draw();        }    }    private void draw() {        try {            mCanvas = mHolder.lockCanvas();            drawSomeThing(mCanvas);        } catch (Exception e) {        } finally {            if (mCanvas != null) {                mHolder.unlockCanvasAndPost(mCanvas);            }        }    }    public int current_progress = 50;    public void setProgress(int progress) {        this.current_progress = progress;        invalidate();        //绘制完成之后,停止绘制。        if (progress < 100) {            mIsDrawing = true;        } else {            mIsDrawing = false;        }    }    int width = 800;    int height = 50;    private void drawSomeThing(Canvas canvas) {        Log.i("main", "=======" + System.currentTimeMillis());        int left = getWidth() / 2 - width / 2;        int top = getHeight() / 2 - height / 2;        int bottom = getHeight() / 2 + height / 2;        int right = left + (width * current_progress / 100);        canvas.drawRect(left, top, right, bottom, mPaint);    }}



布局代码=======================

    <com.reeman.demo.viewcustom.MySurfaceView        android:id="@+id/surface"        android:layout_width="match_parent"        android:layout_height="100dp"        android:layout_centerInParent="true" />

====================================================

package com.reeman.demo.viewcustom;import android.os.Bundle;import android.os.Handler;import android.support.v7.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {    private MySurfaceView surface;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        surface = (MySurfaceView) findViewById(R.id.surface);        inti();    }    int i = 0;    boolean isRun = true;    private void inti() {        new Thread() {            @Override            public void run() {                super.run();                while (isRun) {                    try {                        Thread.sleep(50);                    } catch (Exception e) {                    }                    i++;                    handler.post(new Runnable() {                        @Override                        public void run() {                            surface.setProgress(i);                            if (i > 99) {                                isRun = false;                            }                        }                    });                }            }        }.start();    }    private Handler handler = new Handler();}


使用起来和其他的自定义View,看起来没有什么差别 ,唯一的不同就是,开了线程去绘制 , 效率可以大大提升 , 内存消耗 和在主线程绘制,明显有区别 , 

下一章写一个实例,股票走势图,或者和MediaPlayer结合使用的 。

大家晚安 









原创粉丝点击