关于SurfaceView

SurfaceView 是在子线程中更新画面的组件, View是 在 UI 的主线程中更新画面, 适合于做动画.
使用SurfaceView 通常要实现 SurfaceHolder.Callback接口,SurfaceView 类的生命周期有3个回调函数,分别为:
public abstract  void surfaceCreated(SurfaceHolder holder) 在SurfaceView 创建时调用
public abstract  void surfaceChanged(SurfaceHolder  holder,  int  format,  int width,  int height) 在SurfaceView 改变时调用
public  abstract  void surfaceDestroyed(SurfaceHolder  holder)在SurfaceView 销毁前调用

此外, 还有一个重要方法:
protected void  onDraw(Canvas c)  用来绘制SurfaceView 画面, 每一次SurfaceView  中画面改变都是调用此方法.
通常实现动画效果原理是:
新建一个线程类,每隔一段时间调用SurfaceView 的onDraw(), 在onDraw() 方法中的画面也有一个线程类在时刻改变,这样后一个线程类实现了onDraw() 画面中显示内容的变化, 前一个线程类 时刻刷新画面,这样就形成了动画.
具体代码请参见  SufaceView_3_7 工程, 讲解一下两个线程类
public class OnDrawThread extends Thread {
MySurfaceView msv; // 得到MySurfaceView的引用
SurfaceHolder sh; // SurfaceHolder引用
public OnDrawThread(MySurfaceView msv) {
  super();
  this.msv = msv; // 构造方法中,将msv引用指向调用了该类的MySurfaceView的对象
  sh = msv.getHolder();
}
@Override
public void run() {
  super.run();
  Canvas canvas = null; 
  while (true) {   // 这个循环用于时刻刷新界面
   try {
    canvas = sh.lockCanvas(null); // 将canvas的引用指向surfaceView的canvas的对象
    synchronized (this.sh) { // 绘制过程,可能带来同步方面的问题,加锁
     if (canvas != null) {
      msv.onDraw(canvas);    // 这里调用onDraw(),时刻刷新画面
     }
    }
   } finally {
    try {
     if (sh != null) {
      sh.unlockCanvasAndPost(canvas); // 绘制完后解锁
     }
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
try {
    Thread.sleep(Constant.ONDRAWSPEED); // 休息1秒钟
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
}
}
----------------------------------
//该类是控制duke图片运动的类
public class PicRunThread extends Thread{
MySurfaceView msv;         //MySurfaceView的引用
private float picX=0;   //图片x坐标
private float picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT;   //图片y坐标
boolean yRunFlag=false;  //y方向上的运动标记,false时y=y+speed,true时y=y-speed
int picAlphaNum=0;     //图片变暗效果中画笔的alpha值
public PicRunThread(MySurfaceView msv) {
  super();
  this.msv = msv;   //将该线程类的引用指向调用其的MySurfaceView的对象
}

@Override
public void run() {
  super.run();
  while(true){             //这个循环用于显示内容变化,实现重复显示,  如果没有则画面只显示一遍
   //控制duke图片的运动
   while(this.picX<Constant.SCREENWIDTH){   //当图片的左边完全超过屏幕的右边时,循环结束
    msv.setPicX(picX);
    msv.setPicY(picY);
    picX=picX+Constant.PICXSPEED;
    if(yRunFlag){//应该向上运动,自减
     picY=picY-Constant.PICYSPEED;
    }else{//应该向下运动,自加
     picY=picY+Constant.PICYSPEED;
    }
    if(picY<=0){         //到达屏幕上沿
     yRunFlag=false;
    }else if(picY>Constant.SCREENHEIGHT-Constant.PICHEIGHT){  //到达屏幕下沿
yRunFlag=true;
    }
    try{
     Thread.sleep(Constant.PICRUNSPEED);
    }catch(Exception e){e.printStackTrace();}
   }
   //图片变暗效果演示
   msv.picAlphaFlag=true;       //开启图片变暗效果
   for(picAlphaNum=100;picAlphaNum<=200;picAlphaNum++){
    if(picAlphaNum==200){
     msv.picAlphaFlag=false;     //当图片变暗效果结束,标记重置
     picX=0;   //图片x坐标
     picY=Constant.SCREENHEIGHT-Constant.PICHEIGHT;   //图片y坐标
     System.out.println(msv.picAlphaFlag+"picX:"+picX+"picY:"+picY);
    }
    msv.setPicAlphaNum(picAlphaNum);
    try{
     Thread.sleep(Constant.PICALPHASPEED);
    }catch(Exception e){e.printStackTrace();}
   }
  }
}
}

 

效果图示意如下:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值