SurfaceView

wangsys發表於2021-09-09
package com.example.keweize.surfaceviewwelcome.views;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.example.keweize.surfaceviewwelcome.R;

/**
 * Created by keweize on 2016/10/25.
 */
public class DynamicSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private Context context;

    private SurfaceHolder mHolder;
    private Bitmap bitmap;
    private int viewWidth, viewHeight, imgWidth, imgHeight;

    //圖片在水平位置的偏移量
    private float imgOffset = 0;
    //動畫執行緒
    Thread mDynamicBgThread;
    //執行緒是否開啟
    private boolean isRunable = false;

    //畫筆
    private Paint mPaint;

    //方向標識,標識當前背景圖偏移的方向
    private boolean moToRight = true;

    //動畫效果為30偵/秒
    private static final long DRAW_INTERVAL = 1000/30;
    //每次偏移的偏移量(暫時預設為10)
    private static float offset = 20;

    public DynamicSurfaceView(Context context) {
        this(context, null);
    }

    public DynamicSurfaceView(Context context, AttributeSet attrs) {
        this(context, null, 0);
    }

    public DynamicSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        mHolder = getHolder();
        mHolder.addCallback(this);
        //初始化畫筆
        mPaint = new Paint();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (bitmap == null){
            //獲得空間寬高
            viewWidth = MeasureSpec.getSize(widthMeasureSpec);
            viewHeight = MeasureSpec.getSize(heightMeasureSpec);
            //初始化背景圖(背景圖壓縮至跟view一樣的高度)
            initBitmap();
        }
    }

    private void initBitmap(){

        bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.bg1);

        float scaleNum = (float) viewHeight / (float) bitmap.getHeight();
        Matrix matrix = new Matrix();
        matrix.postScale(scaleNum, scaleNum);   //長和寬放大縮小的比例

        //得到與view控制元件相同高度的bitmap物件
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        imgWidth = bitmap.getWidth();
        imgHeight = bitmap.getHeight();

        //因為偏移量如果固定的話,在解析度高的手機上會走得很慢,在解析度低的手機會跑得很快,所以這裡直接動態設定單次偏移量(每個輪迴20s走完)
        offset = (float) (imgWidth - viewWidth) / ((float) 20 * (float) 30);
        Log.i("DynamicSurfaceView", "offset is " + offset);
        Log.i("DynamicSurfaceView", " afterCompress: bitmap 's width is" + bitmap.getWidth() + "  |  height is " + bitmap.getHeight());
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        isRunable = true;
        mDynamicBgThread = new Thread(new DynamicBgThread());
        mDynamicBgThread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isRunable = false;
    }

    //寫一個程式來動態繪製背景
    private class DynamicBgThread implements Runnable{

        @Override
        public void run() {
            long deltaTime = 0;
            long tickTime = 0;
            tickTime = System.currentTimeMillis();
            while (isRunable) {
                Canvas canvas = null;
                try {
                    synchronized (mHolder) {
                        canvas = mHolder.lockCanvas();
                        drawBackground(canvas);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (null != mHolder) {
                        mHolder.unlockCanvasAndPost(canvas);
                    }
                }

                deltaTime = System.currentTimeMillis() - tickTime;
                if(deltaTime  0){
                imgOffset -= offset;
            }else {
                moToRight = true;
            }
        }
    }

}

原文連結:http://www.apkbus.com/blog-880881-68585.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3244/viewspace-2813781/,如需轉載,請註明出處,否則將追究法律責任。