每一款软件打开的时候都有欢迎页面,就算不是欢迎页面也有logo之类的东西。
今天介绍一下在《Android应用案例开发大全》这本书中常用到的欢迎界面的设计。
用到了SurfaceView视图。它是View的继承类。这个视图里面内嵌了一个专门用于绘制Surface。你可以控制这个Surface的格式和尺寸。它和View最本质的区别在于,surfaceView是在一个新起的线程中重新绘制画面的,而View必须在UI主线程中更新新画面,那么在UI主线程中更新新画面,可能会引发问题,比附你更新时间长,如果你按屏幕触摸等,可能出现问题。下面这张图可以说一下Surface的大概意思:
所以在要有等待效果的欢迎界面的时候,要用到SurfaceView视图。
怎么实现这种视图呢?
首先继承SurfaceView并实现SurfaceHolder.Callback接口
使用接口的原因:因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始(Surface—表面,这个概念在 图形编程中常常被提到。基本上我们可以把它当作显存的一个映射,写入到Surface 的内容 可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。
需要重写的方法
(1)public void surfaceChanged(SurfaceHolder holder,int format,int width,int height){}
//在surface的大小发生改变时激发
(2)public void surfaceCreated(SurfaceHolder holder){}
//在创建时激发,一般在这里调用画图的线程。
(3)public void surfaceDestroyed(SurfaceHolder holder) {}
//销毁时激发,一般在这里将画图的线程停止、释放。
整个过程:继承SurfaceView并实现SurfaceHolder.Callback接口 ---->
SurfaceView.getHolder()获得SurfaceHolder对象 ---->
SurfaceHolder.addCallback(callback)添加回调函数---->
SurfaceHolder.lockCanvas()获得Canvas对象并锁定画布---->
Canvas绘画 ---->
SurfaceHolder.unlockCanvasAndPost(Canvas canvas)结束锁定画图,并提交改变,将图形显示。
这里用到了一个类SurfaceHolder,可以把它当成surface的控制器,用来操纵surface。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。
几个需要注意的方法:
(1)、abstract void addCallback(SurfaceHolder.Callback callback);
// 给SurfaceView当前的持有者一个回调对象。
(2)、abstract Canvas lockCanvas();
// 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
(3)、abstract Canvas lockCanvas(Rect dirty);
// 锁定画布的某个区域进行画图等..因为画完图后,会调用下面的unlockCanvasAndPost来改变显示内容。
// 相对部分内存要求比较高的游戏来说,可以不用重画dirty外的其它区域的像素,可以提高速度。
(4)、abstract void unlockCanvasAndPost(Canvas canvas);
// 结束锁定画图,并提交改变。
<span style="font-size:14px;">public class MySurfaceView extends SurfaceView
implements SurfaceHolder.Callback //实现生命周期回调接口
{
RootActivity activity;
Paint paint;//画笔
int currentAlpha=0;//当前的不透明值
int screenWidth;//屏幕宽度
int screenHeight;//屏幕高度
int sleepSpan=50;//动画的时延ms
Bitmap[] logos=new Bitmap[2];//logo图片数组
Bitmap currentLogo;//当前logo图片引用
int currentX;
int currentY;
public MySurfaceView(RootActivity activity) {
super(activity);
this.activity = activity;
this.getHolder().addCallback(this);//设置生命周期回调接口的实现者
paint = new Paint();//创建画笔
paint.setAntiAlias(true);//打开抗锯齿
//加载图片
logos[0]=BitmapFactory.decodeResource(activity.getResources(), R.drawable.dukea);
logos[1]=BitmapFactory.decodeResource(activity.getResources(), R.drawable.dukeb);
}
public void onDraw(Canvas canvas){
//绘制黑填充矩形清背景
paint.setColor(Color.RED);//设置画笔颜色
paint.setAlpha(255);
canvas.drawRect(0, 0, screenWidth, screenHeight, paint);
//进行平面贴图
if(currentLogo==null)return;
paint.setAlpha(currentAlpha);
canvas.drawBitmap(currentLogo, currentX, currentY, paint);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder holder) {//创建时被调用
new Thread()
{
public void run()
{
for(Bitmap bm:logos)
{
currentLogo=bm;
//计算图片位置
currentX=screenWidth/2-bm.getWidth()/2;
currentY=screenHeight/2-bm.getHeight()/2;
for(int i=255;i>-10;i=i-10)
{//动态更改图片的透明度值并不断重绘
currentAlpha=i;
if(currentAlpha<0)
{
currentAlpha=0;
}
SurfaceHolder myholder=MySurfaceView.this.getHolder();
Canvas canvas = myholder.lockCanvas();//获取画布
try{
synchronized(myholder){
onDraw(canvas);//绘制
}
}
catch(Exception e){
e.printStackTrace();
}
finally{
if(canvas != null){
myholder.unlockCanvasAndPost(canvas);
}
}
try
{
if(i==255)
{//若是新图片,多等待一会
Thread.sleep(1000);
}
Thread.sleep(sleepSpan);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
activity.hd.sendEmptyMessage(0);
}
}.start();
}
public void surfaceDestroyed(SurfaceHolder arg0) {//销毁时被调用
}
}</span>
有点简陋哈,这个代码,不过已经能实现一个简单的欢迎界面,最后发送Message实现跳转。
然后那个屏幕的长宽我给删了,因为要适应不同的手机屏幕大小,大家还是自动获取这个值,
我用的是这种方法:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
System.out.println("heigth : " + dm.heightPixels);
System.out.println("width : " + dm.widthPixels);
是在主Activity中调用了方法,再对这个视图对象,设置其中的成员变量来搞定的。