这个冬天,老家一直没有下雨, 正好圣诞节,就想着制作一个下雪的特效。
圣诞祝福:平安夜,舞翩阡。雪花飘,飞满天。心与心,永相伴。
圣诞节是传统的宗教节日,对于基 督徒,那是庆祝耶稣的诞生,纪念耶稣和发扬基督精神。现在整个西方社会都在过圣诞节,像许多宗教节日一样,它已经越来越民俗化了。
尽管如此,圣诞节依然倍受尊重。人们在圣诞快乐中怀有对耶稣的敬仰,欢乐的节庆里含有庄严肃穆的神念。欢度圣诞佳节的人都不拒绝耶稣的教诲,要仁爱、善良、诚实、忍耐、感恩……在信神的国度,不是基 督徒的人们,也都知道人应该感恩,心存谢意。对需要帮助的人给予关爱;对他人的帮助给予感谢。这是西方社会价值观的一部份,而不是说圣诞夜就只是一家坐在壁炉前,共进有火鸡或烤鹅的圣诞大餐或是冬季里开的一个最热闹的大派对。
Android实现雪花特效自定义view
public class myRunnable implements Runnable {@Overridepublic void run() {while (true){Canvas canvas =null;try {synchronized (holder){canvas = holder.lockCanvas();//清除画布canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);for (Snowflake snowflake :list){snowflake.draw(canvas);snowflake.update();}}}catch (Exception e){e.printStackTrace();}finally {if (canvas!=null){holder.unlockCanvasAndPost(canvas);}}}}}
这样的话,可以让所有的雪花图片动起来
这步相对来说简单一些,其实就是将bitmap绘制到画布上面
public void reset(){size = randomizer.randomInt(sizeMinInPx, sizeMaxInPx, true);if (image!=null){if (bitmap==null){bitmap = Bitmap.createScaledBitmap(image, size, size, false);}}float speed = (float)(size - sizeMinInPx) / (sizeMaxInPx - sizeMinInPx) * (speedMax - speedMin) + speedMin;double angle = Math.toRadians(randomizer.randomDouble(angleMax) * randomizer.randomSignum());speedX = speed* Math.sin(angle);speedY = speed* Math.cos(angle);alpha = randomizer.randomInt(alphaMin, alphaMax, false);paint.setAlpha(alpha);positionX = randomizer.randomDouble(parentWidth);this.positionY=randomizer.randomDouble(parentHeight);if (!alreadyFalling){this.positionY = this.positionY-parentHeight-size;}}
实现manifest加载视图即可
界面类SnowfallView
public class SnowfallView extends SurfaceView implements SurfaceHolder.Callback {private int DEFAULT_SNOWFLAKES_NUM = 200;private int DEFAULT_SNOWFLAKE_ALPHA_MIN = 150;private int DEFAULT_SNOWFLAKE_ALPHA_MAX = 250;private int DEFAULT_SNOWFLAKE_ANGLE_MAX = 10;private int DEFAULT_SNOWFLAKE_SIZE_MIN_IN_DP = 2;private int DEFAULT_SNOWFLAKE_SIZE_MAX_IN_DP = 8;private int DEFAULT_SNOWFLAKE_SPEED_MIN = 2;private int DEFAULT_SNOWFLAKE_SPEED_MAX = 8;private boolean DEFAULT_SNOWFLAKES_FADING_ENABLED = false;private boolean DEFAULT_SNOWFLAKES_ALREADY_FALLING = false;private int snowflakesNum;private Bitmap snowflakeImage;private int snowflakeAlphaMin;private int snowflakeAlphaMax;private int snowflakeAngleMax;private int snowflakeSizeMinInPx;private int snowflakeSizeMaxInPx;private int snowflakeSpeedMin;private int snowflakeSpeedMax;private boolean snowflakesFadingEnabled;private boolean snowflakesAlreadyFalling;//雪花类集合private ArrayList list =new ArrayList<>();private SnowfallView.myRunnable myRunnable = new myRunnable();private Thread myThread;private SurfaceHolder holder;public SnowfallView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init(context,attrs);}private void init(Context context, AttributeSet attributeSet) {TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.SnowfallView);snowflakesNum = typedArray.getInt(R.styleable.SnowfallView_snowflakesNum, DEFAULT_SNOWFLAKES_NUM);snowflakeImage = drawable2Bitmap(typedArray.getDrawable(R.styleable.SnowfallView_snowflakeImage));snowflakeAlphaMin = typedArray.getInt(R.styleable.SnowfallView_snowflakeAlphaMin, DEFAULT_SNOWFLAKE_ALPHA_MIN);snowflakeAlphaMax = typedArray.getInt(R.styleable.SnowfallView_snowflakeAlphaMax, DEFAULT_SNOWFLAKE_ALPHA_MAX);snowflakeAngleMax = typedArray.getInt(R.styleable.SnowfallView_snowflakeAngleMax, DEFAULT_SNOWFLAKE_ANGLE_MAX);snowflakeSizeMinInPx = typedArray.getDimensionPixelSize(R.styleable.SnowfallView_snowflakeSizeMin, dp2Px(DEFAULT_SNOWFLAKE_SIZE_MIN_IN_DP));snowflakeSizeMaxInPx = typedArray.getDimensionPixelSize(R.styleable.SnowfallView_snowflakeSizeMax, dp2Px(DEFAULT_SNOWFLAKE_SIZE_MAX_IN_DP));snowflakeSpeedMin = typedArray.getInt(R.styleable.SnowfallView_snowflakeSpeedMin, DEFAULT_SNOWFLAKE_SPEED_MIN);snowflakeSpeedMax = typedArray.getInt(R.styleable.SnowfallView_snowflakeSpeedMax, DEFAULT_SNOWFLAKE_SPEED_MAX);snowflakesFadingEnabled = typedArray.getBoolean(R.styleable.SnowfallView_snowflakesFadingEnabled, DEFAULT_SNOWFLAKES_FADING_ENABLED);snowflakesAlreadyFalling = typedArray.getBoolean(R.styleable.SnowfallView_snowflakesAlreadyFalling, DEFAULT_SNOWFLAKES_ALREADY_FALLING);typedArray.recycle();holder = this.getHolder();holder.addCallback(this);//设置背景为透明setZOrderOnTop(true);holder.setFormat(PixelFormat.TRANSPARENT);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);//获取雪花集合for (int i=0;ilist.add(new Snowflake(w, h, snowflakeImage, snowflakeAlphaMin, snowflakeAlphaMax, snowflakeAngleMax, snowflakeSizeMinInPx, snowflakeSizeMaxInPx, snowflakeSpeedMin, snowflakeSpeedMax, snowflakesFadingEnabled, snowflakesAlreadyFalling));}}@Overrideprotected void onVisibilityChanged(@NonNull View changedView, int visibility) {super.onVisibilityChanged(changedView, visibility);if (changedView==this&&visibility==GONE){//初始化雪花类try {for (Snowflake snowflake :list){snowflake.reset();}}catch (Exception e){e.printStackTrace();}}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (isInEditMode()){return;}}/*** dp转px* @param dp* @return*/private int dp2Px(int dp){return (int) (dp*getResources().getDisplayMetrics().density);}/*** drawble转Bitmap* @param drawable* @return*/private Bitmap drawable2Bitmap(Drawable drawable){Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());drawable.draw(canvas);return bitmap;}@Overridepublic void surfaceCreated(SurfaceHolder surfaceHolder) {if (myThread==null){myThread = new Thread(myRunnable);}if(!myThread.isAlive()){myThread.start();}}@Overridepublic void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {}@Overridepublic void surfaceDestroyed(SurfaceHolder surfaceHolder) {if (myThread!=null){myThread.interrupt();}}public class myRunnable implements Runnable {@Overridepublic void run() {while (true){Canvas canvas =null;try {synchronized (holder){canvas = holder.lockCanvas();//清除画布canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);for (Snowflake snowflake :list){snowflake.draw(canvas);snowflake.update();}}}catch (Exception e){e.printStackTrace();}finally {if (canvas!=null){holder.unlockCanvasAndPost(canvas);}}}}}
}
雪花类Snowflake
public class Snowflake {private int parentWidth;private int parentHeight;private int alphaMin;private int alphaMax;private int angleMax;private int sizeMinInPx;private int sizeMaxInPx;private int speedMin;private int speedMax;private Bitmap image;private boolean fadingEnabled;private boolean alreadyFalling;private int size = 0 ;private int alpha = 255;private Bitmap bitmap = null;private double speedX= 0.0;private double speedY = 0.0;private double positionX = 0.0;private double positionY = 0.0;private final Randomizer randomizer;private Paint paint;public Snowflake(int parentWidth, int parentHeight, Bitmap image,int alphaMin,int alphaMax,int angleMax,int sizeMinInPx,int sizeMaxInPx,int speedMin,int speedMax,boolean fadingEnabled,boolean alreadyFalling ){this.parentWidth = parentWidth;this.parentHeight = parentHeight;this.alphaMin = alphaMin;this.alphaMax = alphaMax;this.angleMax = angleMax;this.sizeMinInPx = sizeMinInPx;this.sizeMaxInPx = sizeMaxInPx;this.speedMin = speedMin;this.speedMax = speedMax;this.image = image;this.fadingEnabled=fadingEnabled;this.alreadyFalling=alreadyFalling;randomizer = new Randomizer();initPaint();reset();}/*** 初始化画笔*/private void initPaint() {paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setColor(Color.rgb(255,255,255));paint.setStyle(Paint.Style.FILL);}public void reset(double positionY){size = randomizer.randomInt(sizeMinInPx, sizeMaxInPx, true);if (image!=null){if (bitmap==null){bitmap = Bitmap.createScaledBitmap(image, size, size, false);}}float speed = (float)(size - sizeMinInPx) / (sizeMaxInPx - sizeMinInPx) * (speedMax - speedMin) + speedMin;double angle = Math.toRadians(randomizer.randomDouble(alphaMax) * randomizer.randomSignum());if (angle<-1||angle>1){angle = 0;}speedX = speed* Math.sin(angle);speedY = speed* Math.cos(angle);alpha = randomizer.randomInt(alphaMin, alphaMax, false);paint.setAlpha(alpha);positionX = randomizer.randomDouble(parentWidth);this.positionY = positionY;}public void reset(){size = randomizer.randomInt(sizeMinInPx, sizeMaxInPx, true);if (image!=null){if (bitmap==null){bitmap = Bitmap.createScaledBitmap(image, size, size, false);}}float speed = (float)(size - sizeMinInPx) / (sizeMaxInPx - sizeMinInPx) * (speedMax - speedMin) + speedMin;double angle = Math.toRadians(randomizer.randomDouble(angleMax) * randomizer.randomSignum());speedX = speed* Math.sin(angle);speedY = speed* Math.cos(angle);alpha = randomizer.randomInt(alphaMin, alphaMax, false);paint.setAlpha(alpha);positionX = randomizer.randomDouble(parentWidth);this.positionY=randomizer.randomDouble(parentHeight);if (!alreadyFalling){this.positionY = this.positionY-parentHeight-size;}}public void update(){positionX = positionX+speedX;positionY = positionY+speedY;if (positionY>parentHeight){positionY = -(double)size;reset(positionY);}if (fadingEnabled){paint.setAlpha((int) (alpha * ((float) (parentHeight - positionY) / parentHeight)));}}public void draw(Canvas canvas){if (bitmap!=null){canvas.drawBitmap(bitmap,(float)positionX,(float)positionY,paint);}else {canvas.drawCircle((float)positionX,(float)positionY,(float)size,paint);}}
}