Android 自定义View中invalidate()的自动清屏含义以及屏幕刷新

invalidate()含义
invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。
对于屏幕刷新有以下集中情况可以考虑:
1.不使用多线程和双缓冲
这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用 View的onDraw()方法。
我们自定义View可以随意的滑动的图标,代码示例如下

public class BallView extends View {
    private Bitmap mBall;
    private Paint mPaint;
    private float mTouchX = 0;
    private float mTouchY = 0;

    public BallView(Context context) {
        super(context);
    }

    public BallView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mBall = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        mPaint = new Paint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBall,mTouchX,mTouchY,mPaint);
    }

    /**
     * 手指摸哪里,小球跟着去哪里
     * 触摸事件
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mTouchX = event.getX();
        mTouchY = event.getY();
        //重新绘制
        invalidate();
        //true,消费事件,false,不消费,默认false
        return true;
    }

}

布局文件中使用

  <com.wq.myviewdemo.BallView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"/>

效果图如下所示
在这里插入图片描述

2.使用多线程和不使用双缓冲
这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.
这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量, 你可以直接调用View对象中的invalidate()方法 )。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。
3.使用多线程和双缓冲
Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值