利用SurfaceView实现墨迹天气雪花效果

来源:互联网 发布:淘宝买家退货发空包裹 编辑:程序博客网 时间:2024/05/01 22:19

先看看效果图吧(小雪花的图片不是特别好,见谅)!


分析: 雪花太多, 用动画实现比较复杂, 可以借助SurfaceView控件, 为啥用SurfaceView呢, 它和View的区别: SurfeceView是在一个新启的单独的线程中绘制界面(双缓冲),不会阻碍UI线程, 而View必须在主线程即UI线程中更新界面,可能会导致UI线程的阻塞.SurfaceView在处理touch事件时会创建一个队列eventquene

什么时候用view,什么时候用SurfaceView? 如果是主动的更新界面, 需要一个单独的线程重绘状态,避免UI线程阻塞,这时用View就不方便了, 可以使用SurfaceView.

废话不多说,直接上代码: 

import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.PixelFormat;import android.graphics.RectF;import android.util.AttributeSet;import android.util.Log;import android.view.KeyEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.ViewGroup;import com.zchz.app.test.Snow;import java.util.ArrayList;import java.util.Random;/** * 作者:Dch on 2017/3/31 10:41 * 描述:仿墨迹天气雪花效果 */public class SnowingSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {    private int snow_count = 5;    Bitmap bitmap_snows[] = new Bitmap[5];//雪花图片    Bitmap bitmap_bg;//雪地背景    Thread thread;    private boolean isRunning = true;//图片是否在移动    private float screenWidth;    private float screenHeight;    private static Random random = new Random();    private ArrayList<Snow> snowArrayList1 = new ArrayList<>();    private ArrayList<Snow> snowArrayList2 = new ArrayList<>();    private ArrayList<Snow> snowArrayList3 = new ArrayList<>();    private ArrayList<Snow> snowArrayList4 = new ArrayList<>();    private ArrayList<Snow> snowArrayList5 = new ArrayList<>();    private SurfaceHolder holder;    public SnowingSurfaceView(Context context) {        super(context);        this.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));        holder = getHolder();        holder.addCallback(this);        //设置顶层绘制surfaceview透明        holder.setFormat(PixelFormat.RGBA_8888);        initViewSize(context);        initSnowImage();        addRandowSnow();    }    /**     * 初始化雪花,加载到集合中     */    private void addRandowSnow() {        for (int i = 0; i < snow_count; i++) {            snowArrayList1.add(new Snow(bitmap_snows[0],                    random.nextFloat() * screenWidth,                    random.nextFloat() * screenHeight,                    8f,                    1 - random.nextFloat() * 2            ));            snowArrayList2.add(new Snow(bitmap_snows[1],                    random.nextFloat() * screenWidth,                    random.nextFloat() * screenHeight,                    6f,                    1 - random.nextFloat() * 2            ));            snowArrayList3.add(new Snow(bitmap_snows[2],                    random.nextFloat() * screenWidth,                    random.nextFloat() * screenHeight,                    4f,                    1 - random.nextFloat() * 2            ));            snowArrayList4.add(new Snow(bitmap_snows[3],                    random.nextFloat() * screenWidth,                    random.nextFloat() * screenHeight,                    3f,                    1 - random.nextFloat() * 2            ));            snowArrayList5.add(new Snow(bitmap_snows[4],                    random.nextFloat() * screenWidth,                    random.nextFloat() * screenHeight,                    2f,                    1 - random.nextFloat() * 2            ));        }    }    /**     * 加载雪花图片到内存中     */    private void initSnowImage() {        BitmapFactory.Options options = new BitmapFactory.Options();        options.inSampleSize = 8; /*图片长宽方向缩小倍数*/        bitmap_snows[0] = BitmapFactory.decodeResource(getResources(), R.drawable.snow,options);        bitmap_snows[1] = BitmapFactory.decodeResource(getResources(), R.drawable.snow2,options);        bitmap_snows[2] = BitmapFactory.decodeResource(getResources(), R.drawable.snow,options);        bitmap_snows[3] = BitmapFactory.decodeResource(getResources(), R.drawable.snow2,options);        bitmap_snows[4] = BitmapFactory.decodeResource(getResources(), R.drawable.snow,options);        bitmap_bg = BitmapFactory.decodeResource(getResources(), R.drawable.snow_bg);    }    private void initViewSize(Context context) {        this.screenWidth = context.getResources().getDisplayMetrics().widthPixels;        this.screenHeight = context.getResources().getDisplayMetrics().heightPixels;        Log.e("屏幕宽高", screenWidth + "--" + screenHeight);    }    public SnowingSurfaceView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    public void run() {        while (isRunning) {            Canvas canvas = null;            try {                //第一步 锁定画布                canvas = holder.lockCanvas();                if (canvas != null) {                    //画雪花                    drawSnow(canvas);                    Snow snow = null;                    for (int i = 0;i<snow_count;i++){                        snow = snowArrayList1.get(i);                        snowDrop(snow);                    }                    for (int i = 0;i<snow_count;i++){                        snow = snowArrayList2.get(i);                        snowDrop(snow);                    }                    for (int i = 0;i<snow_count;i++){                        snow = snowArrayList3.get(i);                        snowDrop(snow);                    }                    for (int i = 0;i<snow_count;i++){                        snow = snowArrayList4.get(i);                        snowDrop(snow);                    }                    for (int i = 0;i<snow_count;i++){                        snow = snowArrayList5.get(i);                        snowDrop(snow);                    }                }                Thread.sleep(20);            } catch (Exception e) {            } finally {                if (canvas != null) {                    holder.unlockCanvasAndPost(canvas);                }            }        }    }    private void snowDrop(Snow snow) {        if (snow.x > screenWidth || snow.x < 0 || snow.y > screenHeight){            snow.x = random.nextFloat()*screenWidth;            snow.y = 0;        }        snow.x += snow.offSet; // 下落水平偏移量        snow.y += snow.speed;    }    private void drawSnow(Canvas canvas) {        Paint paint = new Paint();        paint.setAntiAlias(true); //行锯齿        paint.setFilterBitmap(true);//防止画布抖动        RectF rectF = new RectF(0, 0, screenWidth, screenHeight);        canvas.drawBitmap(bitmap_bg, null, rectF, paint);        Snow snow = null;        for (int i = 0; i < snow_count; i++) {            snow = snowArrayList1.get(i);            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);            snow = snowArrayList2.get(i);            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);            snow = snowArrayList3.get(i);            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);            snow = snowArrayList4.get(i);            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);            snow = snowArrayList5.get(i);            canvas.drawBitmap(snow.bitmap, snow.x, snow.y, paint);        }    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        thread = new Thread(this);        thread.start();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        isRunning = false;    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK){            isRunning = true;        }        return super.onKeyDown(keyCode, event);    }}
Activtity中:
 @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        UIUtils.setStatusbarTrans(this);        SnowingSurfaceView snowingSurfaceView = new SnowingSurfaceView(this);        setContentView(snowingSurfaceView);}

Snow.java

/** * 作者:Dch on 2017/3/31 10:56 * 描述: * 邮箱: */public class Snow {    /**     * 雪花图片     */    public Bitmap bitmap;    /**     * 雪花开始飘落的横坐标     */    public float x;    /**     * 雪花开始飘落的纵坐标     */    public float y;    /**     * 雪花下落的速度     */    public float speed;    /**     * 雪花飘落的偏移值     */    public float offSet;    public Snow(Bitmap bitmap, float x, float y, float speed, float offSet) {        this.bitmap = bitmap;        this.x = x;        this.y = y;        this.speed = speed;        this.offSet = offSet;    }    public Snow() {    }}


                                             
1 0
原创粉丝点击