之前有个需求是在进入首页首先展示一个动画效果的界面,然后点击之后安装assets下的APK,实现方法有很多种,前辈说用View简单方便,但是为了提升自己接触了surfaceview这个方式,一般游戏开发动画界面会用到此方式,初次接触,绝对制作流程和方式大同小异,不多说,直接贴代码,高手勿喷...
我只用到了两个一个画线的,一个画图的,还有画按钮的:
定义一个画线的类:
public class Line extends Actor{
float mDuration;
float mStartX;
float mStartY;
float mEndX;
float mEndY;
int mColor;
Paint mPaint;
float angle;
float mLen;
float mTimeTotal=0;
float tdx;
float tdy;
public Line(float duration,int color,float startX,float startY,float endX,float endY)
{
this.mStartX=startX;
this.mStartY=startY;
this.mEndX=endX;
this.mEndY=endY;
this.mColor=color;
this.mDuration=duration;
this.mPaint=new Paint();
mPaint.setColor(color);
mPaint.setStrokeWidth(5);
mPaint.setDither(true); //获取跟清晰的图像采样
mPaint.setAntiAlias(true);//抗锯齿
mLen=(float)Math.sqrt((double)((endX-startX)*(endX-startX)+(endY-startY)*(endY-startY)));
tdx=endX-startX;
tdy=endY-startY;
}
public void draw(Canvas canvas,long span)
{
mTimeTotal+=(span/600f/500f);
float percent=mTimeTotal/mDuration;
if(percent>=1f)
{
percent=1f;
}
else {
}
percent=Interpolation.swingOut.apply(percent);
float dx=tdx*percent;
float dy=tdy*percent;
float toX=mStartX+dx;
float toY=mStartY+dy;
canvas.drawLine(mStartX, mStartY, toX, toY, mPaint);
}
}
一个画图的类:
public class CircleImage extends Actor {
float mX;
float mY;
float mWidth;
float mHeight;
float mDuration;
Bitmap mImage;
RectF mRect;
float mTimeTotal=0;
Paint mPaint;
public CircleImage(Bitmap img,float duration,float x,float y,float width,float height )
{
this.mX=x;
this.mY=y;
this.mHeight=height;
this.mWidth=width;
this.mDuration=duration;
this.mImage=img;
this.mRect=new RectF(x, y, x+width, y+height);
mPaint=new Paint();
mPaint.setDither(true); //获取跟清晰的图像采样
mPaint.setAntiAlias(true);//抗锯齿
}
@Override
public void draw(Canvas canvas,longspan)
{
mTimeTotal+=(span/600f/500f);
float percent=mTimeTotal/mDuration;
if(percent>=1)
{
percent=1;
}
mPaint.setAlpha((int)(255*percent));
canvas.drawBitmap(mImage, null, mRect, mPaint);
}
}
按钮的:
public class MButton extends Actor {
float mX;
float mY;
float mWidth;
float mHeight;
float mDuration;
Bitmap mImage;
RectF mRect;
float mTimeTotal=0;
Paint mPaint;
float mFromScale=1f;
float mToScale=1.5f;
float mCenterX;
float mCenterY;
public MButton(Bitmap img,float duration,float x,float y,float width,float height )
{
this.mX=x;
this.mY=y;
this.mHeight=height;
this.mWidth=width;
this.mDuration=duration;
this.mImage=img;
this.mRect=new RectF(x , y , x+width , y+height );
mPaint=new Paint();
//mPaint.setDither(true); //获取跟清晰的图像采样
mPaint.setAntiAlias(true);//抗锯齿
this.mCenterX=x+width/2f;
this.mCenterY=y+height/2f;
}
@Override
public void draw(Canvas canvas,longspan)
{
mTimeTotal+=(span/1300f/1000f);
float percent=mTimeTotal/mDuration;
if(percent>=1)
{
mTimeTotal=0;
}
float sw=mWidth*mFromScale+ 130f*(mToScale-mFromScale)*percent;
float sh=mHeight*mFromScale+130f*(mToScale-mFromScale)*percent;
float alpha=(percent>=1)?0:1f-percent;
mPaint.setAlpha((int)(255f*alpha));
mX=mCenterX-(sw/2);
mY=mCenterY-(sh/2);
mRect.set(mX,mY,mX+sw,mY+sh);
canvas.drawBitmap(mImage, null, mRect, mPaint);
}
}
然后就是在surfaceview里引用:
//引入相关类
//继承自SurfaceView的子类
public class MSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
Bitmap[] bitmapArray = new Bitmap[6]; // 各种颜色形状的小球图片引用
String fps = "FPS:N/A"; // 用于显示帧速率的字符串,调试使用
Timer timer = new Timer();
Handler handler;
Runnable runnable;
//适配比例
float w = 0;
float h = 0;
DrawThread dt; // 后台屏幕绘制线程
Bitmap bmpBack; // 背景图片对象
Bitmap bmpWood; // 起始图片对象
//引用的图片
Bitmap mBitmapA;
Bitmap mBitmapB;
Bitmap mBitmapC;
Bitmap mBitmapD;
Bitmap mBitmapE;
Bitmap mBitmapF;
Bitmap mBitmapG;
Line mLineA;
Line mLineB;
Line mLineC;
Line mLineD;
CircleImage circleImageA;
CircleImage circleImageB;
CircleImage circleImageC;
CircleImage circleImageD;
CircleImage circleImageE;
MButton mButton;
MButtonS buttonS;
private int mNumber = 0;
public MSurfaceView(Context activity) {
super(activity); // 调用父类构造器
getHolder().addCallback(this);
initBitmaps(getResources()); // 初始化图片
dt = new DrawThread(this, getHolder()); // 初始化重绘线程
}
// 方法:初始化图片
public void initBitmaps(Resources r) {
bmpBack = BitmapFactory.decodeResource(r, R.drawable.ico_background);// 背景
bmpWood = BitmapFactory.decodeResource(r, R.drawable.ico_5);
mBitmapA = BitmapFactory.decodeResource(r, R.drawable.ico_1);
mBitmapB = BitmapFactory.decodeResource(r, R.drawable.ico_2);
mBitmapC = BitmapFactory.decodeResource(r, R.drawable.ico_3);
mBitmapD = BitmapFactory.decodeResource(r, R.drawable.ico_4);
mBitmapE = BitmapFactory.decodeResource(r, R.drawable.ico_6);
mBitmapF = BitmapFactory.decodeResource(r, R.drawable.ico_7);
mBitmapG = BitmapFactory.decodeResource(r, R.drawable.ico_7);
}
// 方法:绘制程序中所需要的图片等信息
public void doDraw(final Canvas canvas, final long span) {
RectF rectF = new RectF(0, 0, (float) this.getWidth(), this.getHeight());
canvas.drawBitmap(bmpBack, null, rectF, null); // 绘制背景图片
canvas.drawBitmap(mBitmapE, null, new RectF(
83 * w, 1044 * h, 554 * w,116 * h), null);
canvas.drawBitmap(bmpWood, null, new RectF(
this.getWidth()/ 2 - 234/ 2 * w , 732 * h,
this.getWidth() / 2 + 234 / 2 * w, 968 * h), null);
mLineA.draw(canvas, span);
circleImageA.draw(canvas, span);
mLineB.draw(canvas, span);
circleImageB.draw(canvas, span);
mLineC.draw(canvas, span);
circleImageC.draw(canvas, span);
mLineD.draw(canvas, span);
circleImageD.draw(canvas, span);
mButton.draw(canvas, span);
buttonS.draw(canvas, span);
circleImageE.draw(canvas, span);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {// 重写surfaceChanged方法
}
@Override
public void surfaceCreated(SurfaceHolder holder) {// 从写surfaceCreated方法
final int mLs = this.getWidth();
w = this.getWidth() / 720f;
h= this.getHeight()/1280f;
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
if (mNumber > 8) {
return;
}
switch (mNumber) {
case 0:
mLineA = new Line(1000f, Color.WHITE, 264 * w, 752 * h, 168 * w, 664 * h);// 第一条线
break;
case 1:
circleImageA = new CircleImage(mBitmapA, 1000f, 31 * w, 440 * h, 234 * w, 234 * h);// 第一个圆图
break;
case 2:
mLineB = new Line(1000f, Color.WHITE, 148 * w, 442 * h, 190 * w, 342 * h);// 第2条线
break;
case 3:
circleImageB = new CircleImage(mBitmapB, 1000f, 113 * w, 117 * h, 234 * w,234 * h);// 第2个圆图
break;
case 4:
mLineC = new Line(1000f, Color.WHITE, 315 * w, 312 * h, 388 * w, 385 * h);// 第3条线
break;
case 5:
circleImageC = new CircleImage(mBitmapC, 1000f, 353 * w, 350 * h, 234 * w,234 * h);// 第3个圆图
break;
case 6:
mLineD = new Line(1000f, Color.WHITE, 470 * w, 352 * h, 512 * w, 260 * h);// 第4条线
break;
case 7:
circleImageD = new CircleImage(mBitmapD, 1000f, 453 * w, 43 * h, 234 * w, 234 * h);// 第4个圆图
break;
case 8:
circleImageE = new CircleImage(mBitmapE, 1000f, mLs/2 - 277 * w, 1044 * h, 554 * w,116 * h);// 最下边按钮
mButton = new MButton(mBitmapF, 1000f, mLs/2 - 277 * w, 1044 * h, 554 * w,116 * h);
buttonS = new MButtonS(mBitmapE, 1000f, mLs/2 - 277 * w, 1044 * h, 554 * w,116 * h);
break;
default:
break;
}
mNumber++;
handler.postDelayed(runnable, 500);
}
};
handler.post(runnable);
if (!dt.isAlive()) { // 如果DrawThread没有启动,就启动这个线程
dt.start();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {// 重写surfaceDestroyed方法
dt.flag = false; // 停止线程的执行
dt = null; // 将dt指向的对象声明为空
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@SuppressLint("NewApi")
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://按下的监听
if(event.getX() * w > 83 * w && event.getX() * w <637 * w && event.getY() * h>1044 * h && event.getY() * h <1160 * h){
Log.i("s", "在此做监听事件");//在此做点击事件
//此处做点击button需要做的操作
}
break;
case MotionEvent.ACTION_UP://抬起手指的监听
if(event.getX() * w > 83 * w && event.getX() * w <637 * w && event.getY() * h>1044 * h && event.getY() * h <1160 * h){
Log.i("s", "在此做监听事件");//在此做点击事件
//此处做点击button需要做的操作
}
break;
default:
break;
}
return super.onTouchEvent(event);
}
}
图和线直接调用,需要呈现不同的效果可以根据实际情况代码修改!
项目地址:http://download.csdn.net/detail/hello___sunshine/8364659