SuferfaceView --- View的孪生兄弟

android提供了view进行绘图处理,View可以满足大部分的绘图需求。View通过刷新来重绘视图,android通过VSYNC信号来进行屏幕的重绘,刷新的时间为16ms,如果在16ms内完成了绘图的操作,用户将不会感到卡顿现象,如果执行的逻辑过多,特别是在需要不断的重绘界面时,就会发生阻塞主线程的现象。从而导致卡顿现象,这种情况,我们自定的view的Log中经常会看到如下的警告。
“Skipped 47 frames! The application may be doing to much work on its main thread”

这些警告是因为在绘制的过程中,处理的逻辑太多导致的。
View主要适用于主动更新的情况下,而SurfaceView主要适用与被动的更新,列如频繁的刷新。
View在主线程中对画面进行刷新,而SurfaceView通常会在子线程进行页面的刷新。
View在绘图的时候没有使用双缓冲机制,而SurfaceView在底层实现机制中就已经实现了双缓冲机制。
总结一句话,如果你的自定义的View需要频繁的刷新,或者刷新的数据量比较大的时候,就可以考虑使用SurfaceView代替View。
SurfaceView的使用
SurfaceView的使用虽然比View复杂,但是SurfaceView在使用时,有一套使用的模板代码,大部分的绘图操作都可以使用这个模板代码来使用。
package xiaoxu.picture;

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;

/**
* Created by Administrator on 2016/4/3.
*/

public class MySufView extends SurfaceView implements Runnable,SurfaceHolder.Callback {

private SurfaceHolder holder; 
private Boolean mIsDrawing;//子线程标志位。
private Canvas mCanvas; //用于绘图的canvas
private Path mPath;


public MySufView(Context context, AttributeSet attrs) {
    super(context, attrs);

    initView();
}


//View的创建
@Override
public void surfaceCreated(SurfaceHolder holder) {

    mIsDrawing = true;
    new Thread(this).start();
}

private void initView() {

    holder = getHolder();//对SurfaceHolder进行初始化
    holder.addCallback(this);//并注册一个SurfaceHolder的回调方法
    setFocusable(true);
    setFocusableInTouchMode(true);
    setKeepScreenOn(true);
    mPath = new Path();
}

//View改变
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

//View销毁
@Override
public void surfaceDestroyed(SurfaceHolder holder) {

    mIsDrawing = false;
}

@Override
public void run() {

    long start = System.currentTimeMillis();

    while (mIsDrawing){

        draw1();

    }

    long end = System.currentTimeMillis();

    if(end - start < 100){

        try {
            Thread.sleep(100-(end - start));

        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

}

private void draw1() {

    try {

        Paint paint = new Paint();

        mCanvas = holder.lockCanvas(); //获取当前的canvas对象,需要注意的是,我们获取的仍然是上次的canvas对象,如果需要
                                        //之前的图都将保留,如果需要擦除,可以在绘制之前,调用canvas.color()来执行清屏
        mCanvas.drawColor(Color.WHITE);
        if(mPath != null){
            mCanvas.drawPath(mPath,paint);
        }
    }catch (Exception e){

    }finally {

        holder.unlockCanvasAndPost(mCanvas);//最后要将画布内容提交,要将这个方法放入到final中,保证内容每次都可以提交。
    }

}
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()){

        case MotionEvent.ACTION_DOWN:
            mPath.moveTo(event.getX(),event.getY());
            break;

        case MotionEvent.ACTION_MOVE:

            mPath.lineTo(event.getX(),event.getY());
            break;
    }
    return true;
}

}
详细如下
http://blog.csdn.net/luoshengyang/article/details/8661317/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值