Welcome to follow my GitHub and follow my csdn.
Winter is coming, the snow is snowing, so cold.
Our application can also have some winter effect, teach you to do a snowy animation effect, reference.
Main
(1) Hide status bar
, full screen display picture.
(2) Draw multiple points to achieve the movement effect.
(3) Recycle points, avoid duplicate creation.
I like to talk with comments, please pay more attention to the comments in the code.
Github
1. Snowflake class
The properties of snowflakes include: random amount, position, increment, size, angle, brush.
In the process of painting, the use angle moves the point position, each rate is different.
When the snowflake moves out of the screen, it is reused and is re-dropped at the top of the screen.
Algorithm reference.
/** * Snowflake class, move, move out of the screen will reset position. * <p/> * Created by Wangchenlong on 16/1/24. * * Public class snowflake { //Snowflake Angle Private Static Final floatAnge_range =0.1F//Angle range Private Static Final floatHalf_angle_range = Ange_range/2F//General angle Private Static Final floatHALF_PI = (float) Math.PI/2F//semi-pi Private Static Final floatAngle_seed = -F//Angle random seed Private Static Final floatAngle_divisor =10000F//The denominator of the angle //Snow movement speed Private Static Final floatIncrement_lower =2FPrivate Static Final floatIncrement_upper =4F//size of snowflakes Private Static Final floatFlake_size_lower =7FPrivate Static Final floatFlake_size_upper = -FPrivate FinalRandomgenerator Mrandom;//Random controller Private FinalPoint Mposition;//Snowflake location Private floatMAngle;//Angle Private Final floatMincrement;//Speed of snowflakes Private Final floatMflakesize;//size of snowflakes Private FinalPaint Mpaint;//Brushes Private Snowflake(Randomgenerator random, point position,floatAnglefloatIncrementfloatFlakesize, Paint paint) {mrandom = random; Mposition = position; Mincrement = increment; Mflakesize = flakesize; Mpaint = paint; MAngle = angle; } Public StaticSnowflakeCreate(intWidthintHeight, paint paint) {randomgenerator random =NewRandomgenerator ();intx = random.getrandom (width);inty = random.getrandom (height); Point position =NewPoint (x, y);floatAngle = Random.getrandom (angle_seed)/angle_seed * ange_range + half_pi-half_angle_range;floatIncrement = Random.getrandom (Increment_lower, Increment_upper);floatFlakesize = Random.getrandom (Flake_size_lower, Flake_size_upper);return NewSnowflake (random, position, angle, increment, flakesize, paint); }//Draw Snowflakes Public void Draw(Canvas canvas) {intwidth = Canvas.getwidth ();intHeight = canvas.getheight (); Move (width, height); Canvas.drawcircle (mposition.x, MPOSITION.Y, Mflakesize, Mpaint); }//Moving snowflakes Private void Move(intWidthintHeight) {Doublex = mposition.x + (mincrement * Math.Cos (mAngle));Doubley = mposition.y + (mincrement * Math.sin (mAngle)); MAngle + = Mrandom.getrandom (-angle_seed, angle_seed)/angle_divisor;//Random shakingMposition.set ((int) x, (int) y);//Remove screen and start again if(!isinside (width, height)) {Reset (width); } }//Determine if the Private Boolean Isinside(intWidthintHeight) {intx = mposition.x;inty = mposition.y;returnX >=-mflakesize-1&& x + mflakesize <= width && y >=-mflakesize-1&& y-mflakesize < height; }//Reset Snowflakes Private void Reset(intwidth) {mposition.x = Mrandom.getrandom (width); MPOSITION.Y = (int) (-mflakesize-1);// TopMAngle = Mrandom.getrandom (angle_seed)/angle_seed * ange_range + half_pi-half_angle_range; }}
Random number generator with interval random and upper bound random.
/** * Random generator * <p/> * Created by Wangchenlong on 16/1/24. * * Public class randomgenerator { Private Static FinalRandom random =NewRandom ();//Interval random Public float Getrandom(floatLowerfloatUpper) {floatmin = math.min (lower, upper);floatmax = Math.max (lower, upper);returnGetrandom (max-min) + min; }//upper bound random Public float Getrandom(floatUpper) {returnRandom.nextfloat () * UPPER; }//upper bound random Public int Getrandom(intUpper) {returnRandom.nextint (upper); }}
2. Snowflake View
Snowflake View, delay time redraw, draw num_snowflakes snowflakes.
Initialization is done in onsizechanged, and is plotted in OnDraw.
/** * Snowflake view, delay time redraw, draw num_snowflakes snowflakes * <p/> * Created by Wangchenlong on 16/1/24. */ Public class snowview extends View { Private Static Final intNum_snowflakes = Max;//Snowflake quantity Private Static Final intDELAY =5;//Delay PrivateSnowflake[] Msnowflakes;//Snowflake Public Snowview(Context context) {Super(context); } Public Snowview(context context, AttributeSet attrs) {Super(context, attrs); } Public Snowview(context context, AttributeSet attrs,intDEFSTYLEATTR) {Super(Context, attrs, defstyleattr); }@TargetApi( +) Public Snowview(context context, AttributeSet attrs,intDefstyleattr,intDefstyleres) {Super(Context, Attrs, defstyleattr, defstyleres); }@Override protected void onsizechanged(intWintHintOLDW,intOLDH) {Super. onsizechanged (W, H, OLDW, OLDH);if(w! = OLDW | | h! = OLDH) {Initsnow (W, h); } }Private void Initsnow(intWidthintHeight) {Paint paint =NewPaint (Paint.anti_alias_flag);//anti-aliasingPaint.setcolor (Color.White);//White snowflakesPaint.setstyle (Paint.Style.FILL);//fill;Msnowflakes =NewSnowflake[num_snowflakes]; for(inti =0; i < Num_snowflakes; ++i) {Msnowflakes[i] = snowflake.create (width, height, paint); } }@Override protected void OnDraw(Canvas canvas) {Super. OnDraw (canvas); for(Snowflake s:msnowflakes) {S.draw (canvas); }//Redraw once at a time, animation effectGetHandler (). postdelayed (runnable, DELAY); }//Redraw Threads PrivateRunnable Runnable =NewRunnable () {@Override Public void Run() {invalidate (); } };}
Use the getHandler().postDelayed(runnable, DELAY);
Refresh page.
3. Full-screen layout
Full Screen layout
<?xml version= "1.0" encoding= "Utf-8"?><android.support.design.widget.CollapsingToolbarLayoutxmlns:android="http// Schemas.android.com/apk/res/android "android:layout_width=" Match_parent "android: Layout_height="Match_parent"> <framelayoutandroid:layout_width="Match_parent"android:layout_height ="Match_parent"> <ImageViewandroid:layout_width="Match_parent"android:layout_height ="Match_parent"android:contentdescription="@null"Android:scaletype ="Centercrop"android:src="@drawable/christmas"/> <me.chunyu.spike.wcl_snowfall_demo.views.SnowViewandroid:layout_width="Match_ Parent "android:layout_height=" match_parent "/> </framelayout></android.support.design.widget.CollapsingToolbarLayout>
status bar
The default is not to be transparent, need to use CollapsingToolbarLayout
,
Replace the style of the status bar, otherwise it will leave a certain height, even if transparency is not filled.
Style
<?xml version="1.0" encoding="utf-8"?><resources> <style name="AppTheme.NoStatusBar"> <item name="android:windowTranslucentStatus">true</item> </style></resources>
You can add something interesting to your app in the winter.
OK, that ' s all! Enjoy it!
Animation effect--snow in the sky