学徒浅析Android开发:第十四讲——Frame动画的滚屏操作

        上一讲中,小编给大家介绍了Tween动画,今天小编给大家介绍一下Frame动画的制作,Frame动画就是换图(切帧),将若干张图片组成图组按一定的次序依次显示。这种图组可以是将一张图分割成若干张也可以是若干张完整的图。通过线程控制图片的切换,从而实现动画,今天带给大家的DEMO中有一个动画,我将向大家展示滚屏动画的实现方法。


package com.example.scrollview;
/**
 * @author Arthur Lee
 * @date 08/22/2014
 * */
import android.os.Bundle;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity
{

    GameView gameView;
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);       
        requestWindowFeature(Window.FEATURE_NO_TITLE); 
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        gameView = new GameView(this);
        setContentView(gameView);
    }

    @Override public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

package com.example.scrollview;
/**
 * @author Arthur Lee
 * @date 08/22/2014
 * */
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends SurfaceView implements SurfaceHolder.Callback
{

    MainActivity mainActivity;
    Bitmap backgroundBitmap;//缩放前的背景图
    Bitmap background;//缩放后的背景图
    Bitmap[] backgrounds;//背景图切片数组
    int length;//背景图切片数组,由当前屏幕宽度决定其值
    Paint paint;
    int pictureW = 10,pictureH = 540;
    int screenW,screenH;//获取屏幕宽高
    int backGroundIX = 0;//核心图的x坐标
    int i = 0;//核心图的索引
    TutoriolThread thread;
    BackGroundThread bgThread;
    public GameView(MainActivity mainActivity)
    {
        super(mainActivity);
        // TODO Auto-generated constructor stub
        getHolder().addCallback(this);//注册接口       
        this.mainActivity = mainActivity;
        this.thread = new TutoriolThread(getHolder(), this);
        this.bgThread = new BackGroundThread(this);
        
        
    }

    public void initPicture(){
        paint = new Paint();
        paint.setColor(Color.BLACK);
        
        backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.beeground);//获取背景图
        background = Bitmap.createScaledBitmap(backgroundBitmap, screenW, screenH, true);//对背景图进行缩放,以适应当前屏幕的大小。
        length = screenW/10+((screenW%10==0)?0:1);//获取切片数目
        pictureH = screenH;
        pictureW = 10;
        backgrounds = new Bitmap[length];//背景图切片数组
        for(int i=0;i<backgrounds.length;i++){
            backgrounds[i] = Bitmap.createBitmap(background, pictureW*i, 0, pictureW, pictureH);
        }
        //释放无用图片占据的空间。
        backgroundBitmap = null;
        background = null;
    }
    
    public void drawPicture(Canvas canvas){
        int backGroundIX=this.backGroundIX;
        int i=this.i;
        
        //解决i左侧的问题
        if(backGroundIX>0){
            int n=(backGroundIX/pictureW)+((backGroundIX%pictureW==0)?0:1);//计算i左面有几幅图
            for(int j=1;j<=n;j++){
                canvas.drawBitmap(
                  backgrounds[(i-j+length)%length], 
                  backGroundIX-pictureW*j, 
                  0, 
                  paint
                 );
            }
        }

        //解决i自己
        canvas.drawBitmap(backgrounds[i], backGroundIX, 0, paint);
        
        //解决i右侧的问题
        if(backGroundIX<screenW-pictureW){
            int k=screenW-(backGroundIX+pictureW);
            int n=(k/pictureW)+((k%pictureW==0)?0:1);//计算i右面有几幅图
            for(int j=1;j<=n;j++){
                canvas.drawBitmap(
                        backgrounds[(i+j)%length], 
                        backGroundIX+pictureW*j, 
                        0, 
                        paint
                );
            }
        }   
    }
    @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        // TODO Auto-generated method stub
        
    }

    @Override public void surfaceCreated(SurfaceHolder holder)
    {
        // TODO Auto-generated method stub
        screenW = getWidth();
        screenH = getHeight();
        //初始化图片
        initPicture();
        //启动刷帧线程
        this.thread.setFlag(true);
        this.thread.start();
        //启动滚屏线程
        this.bgThread.setFlag(true);
        this.bgThread.start();
        initPicture();
        
    }

    @Override public void surfaceDestroyed(SurfaceHolder holder)
    {
        // TODO Auto-generated method stub
        boolean retry = true;
        this.thread.setFlag(false);
        this.bgThread.setFlag(false);
        while (retry) {
            try {
                thread.join();
                bgThread.join();
                retry = false;
            } 
            catch (InterruptedException e) {//不断地循环,直到刷帧线程结束
            }
        }
    }

    //刷阵线程
    class TutoriolThread extends Thread{
        private SurfaceHolder surfaceHolder;
        private GameView gameView;
        private boolean flag = false;
        public TutoriolThread(SurfaceHolder surfaceHolder, GameView gameView) {//构造器
            this.surfaceHolder = surfaceHolder;
            this.gameView = gameView;
        }
        public void setFlag(boolean flag) {//设置循环标记位
            this.flag = flag;
        }
        @Override
        public void run() {
            Canvas c;
            while (this.flag) {
                c = null;
                try {
                    // 锁定整个画布,在内存要求比较高的情况下,建议参数不要为null
                    c = this.surfaceHolder.lockCanvas(null);
                    synchronized (this.surfaceHolder) {
                        gameView.drawPicture(c);//绘制
                        //移动切图坐标,每次只移动一位
                        if(gameView.i == length)
                            gameView.i = 0;
                        else
                            gameView.i++;
                    }
                } finally {
                    if (c != null) {
                        //更新屏幕显示内容
                        this.surfaceHolder.unlockCanvasAndPost(c);
                    }
                }
                try{
                    Thread.sleep(100);
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}

package com.example.scrollview;
/**
 * @author Arthur Lee
 * @date 08/22/2014
 * */

public class BackGroundThread extends Thread
{
    private int sleepSpan = 500;//睡眠的毫秒数
    private int span = 1;//图片移动的步长
    private boolean flag = true;//循环标志位
    GameView gameView;//GameView的引用     
    public BackGroundThread(GameView gameView){//构造器
        this.gameView = gameView;
    }
    public void setFlag(boolean flag){//设置标记位
        this.flag = flag;
    }
    public void run(){
        while(flag){
                gameView.backGroundIX -= span;
                if(gameView.backGroundIX <-gameView.pictureW){
                    gameView.backGroundIX+=gameView.pictureW;
                }
            }try{
                Thread.sleep(sleepSpan);//睡眠
            }catch(Exception e){//捕获异常
                e.printStackTrace();//打印异常信息
            }
        }
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值