先看看效果图吧(小雪花的图片不是特别好,见谅)!
分析: 雪花太多, 用动画实现比较复杂, 可以借助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() { } }