Analyze the implementation process of custom view-implement snowflake flying effect (Reprinted with changes), view snowflake

Source: Internet
Author: User
Tags float max getcolor

Analyze the implementation process of custom view-implement snowflake flying effect (Reprinted with changes), view snowflake

Disclaimer: the source code of this article is used to analyze the implementation process of custom view through the implementation of snowflake flying effect (with changes.

When it's okay, I like surfing the internet to check out some new things. It's a good website to stay online.

Now, haha. Pai_^

As we all know, custom Views are divided into three types. 1. They are completely customized and self-drawn. For example, the example in this article. 2. Groupview combines some native android controls into a composite control with multiple functions, such as the TitleBar of android-oldman. 3. inherit from the original Android controls and add and modify the functions as needed. For example, after the extends TextVeiw, make some changes, such as the text position and length. Compared with 2, 3, 1st custom views are inherited from the view, and then measured and drawn as needed.

The final result is: No. The above colored points are the original Snow. Of course, you can modify the parameters to change the number of snow.

1 package com. example. jwwsnow; 2 3 import java. util. arrayList; 4 import java. util. hashMap; 5 import java. util. list; 6 7 import android. content. context; 8 import android. graphics. canvas; 9 import android. graphics. color; 10 import android. graphics. paint; 11 import android. util. attributeSet; 12 import android. util. log; 13 import android. view. view; 14 15 public class SnowView extends View {16 17 Random rand Om; 18 private static final int NUM_SNOWFLAKES = 15; // Number of snowflakes 19 private static final int DELAY = 1; // screen DELAY refresh time 20 21 private SnowFlake [] snowflakes; // snowflake array. 22 23 public SnowView (Context context) {24 super (context); 25} 26 27 public SnowView (Context context, AttributeSet attrs) {28 super (context, attrs ); 29} 30 31 public SnowView (Context context, AttributeSet attrs, int defStyleAttr) {32 super (context, attrs, defStyleAttr); 33} 34 35 36 protected void resize (int width, int height) {37 random = new Random (); 38 snowflakes = new SnowFlake [NUM_SNOWFLAKES]; 39 For (int I = 0; I <NUM_SNOWFLAKES; I ++) {40 // for Loop Production of snow. 41 Paint paint = new Paint (Paint. ANTI_ALIAS_FLAG); 42 paint. setStyle (Paint. style. FILL); 43 paint. setColor (Color. rgb (random. getColor (), random. getColor (), random. getColor (); 44 // The returned object is stored in the object array. 45 snowflakes [I] = SnowFlake. create (width, height, paint); 46 Log. I ("SnowDemo", "Time:" + System. currentTimeMillis (); 47} 48} 49 50/** 51 * View start sequence onSizeChanged ()> onDraw (); 52 */53 @ Override54 protected void onSizeChanged (int w, int h, int oldw, int oldh) {55 super. onSizeChanged (w, h, oldw, oldh); 56 if (w! = Oldw | h! = Oldh) {57 resize (w, h); 58} 59 60} 61 62 @ Override63 protected void onDraw (Canvas canvas) {64 super. onDraw (canvas); 65 for (SnowFlake snowFlake: snowflakes) {66 // obtain the SnowFlake object and draw it. 67 snowFlake. draw (canvas); 68} 69 70 getHandler (). postDelayed (runnable, DELAY); // obtain the subthread and set the latency of 5 ms. The interface is drawn every 5 ms in the main thread .. 71} 72 73 private Runnable runnable = new Runnable () {74 @ Override75 public void run () {76 invalidate (); // This method clears the original view, and call veiw again. onDraw method. 77} 78}; 79}

We can see that several methods in view are rewritten:

OnSizeChanged ();
This method is executed before the onDrow method. Check whether the view size is changed. If the view size is changed, it is called by the system. Then the onDrow () method is executed.
In this example, the system calls the reSize () method by judging the size of the view, and transmits the width and heigh to the past.
In the reSize () method. Defines the snowflake object array SnowFlakes [], creates a specified number of snowflake objects through the for loop, creates a Paint object in the for loop, and sets the Paint brush. (Ps: Paint and Canvas. Painting is like the paint brush we usually use. We can choose the color, width, anti-aliasing, hollow, solid, and whether it is shadow. Canvas, Canvas, we can use the Canvas to carry the specific things we want to draw, such as rectangles, circles, and lines. The ptint and canvas must be separated because their functions are different. Canvas decides what to draw, and print decides what kind of properties to use to draw. I am confused .). Then, call the create method of the snowflake Calss to be pasted below. This method is mainly used to set some dimensions and positions. Then, the parameter states such as size and position are saved as objects in the SnowFalkes [] array for the onDraw method below to use these parameters for painting.

In the onDraw () method, for loops draw each snowflake in the array of SnowFalkes [] objects in sequence. Then, the Handler is used to re-draw the data on a regular basis in the main thread.
SnowFlake. draw (canvas); the method is actually drawn. Next I will post the code and then talk about it.
1 package com. example. jwwsnow; 2 3 import android. graphics. canvas; 4 import android. graphics. paint; 5 import android. graphics. point; 6 7 public class SnowFlake {8 9 private static final float ANGE_RANGE = 0.1f; // 10 private static final float HALF_ANGLE_RANGE = ANGE_RANGE/2f; 11 private static final float HALF_PI = (float) Math. PI/2f; 12 private static final float ANGLE_SEED = 25f; 13 private sta Tic final float ANGLE_DIVISOR = 0000f; 14 private static final float INCREMENT_LOWER = 2f; 15 private static final float INCREMENT_UPPER = 4f; 16 private static final float FLAKE_SIZE_LOWER = 7f; // minimum snowflake size 17 private static final float FLAKE_SIZE_UPPER = 20f; // maximum snowflake size 18 19 private final Random random; 20 private final Point position; 21 private float angle; 22 private final float increment; 23 private final Float flakeSize; 24 private final Paint paint; 25 26 public static SnowFlake create (int width, int height, Paint paint) {27 Random random = new Random (); 28 int x = random. getRandom (width); // get [0 ~ The integer width and height of width) are the sizes of the outer view. 29 int y = random. getRandom (height); 30 Point position = new Point (x, y); // you can specify the random position of a snowflake. 31 // set Random. getRandom (ANGLE_SEED)/ANGLE_SEED to [0 ~ 1) then * ANGE_RANGE gets [0 ~ 0.1f), and then subtract 0.05 to get [-0.05 ~ 0.05. 32 float angle = random. getRandom (ANGLE_SEED)/ANGLE_SEED * ANGE_RANGE + HALF_PI-HALF_ANGLE_RANGE; 33 // get [2f ~ 4f) random data 34 float increment = random. getRandom (INCREMENT_LOWER, INCREMENT_UPPER); 35 // get [7f ~ 20f) random data 36 float flakeSize = random. getRandom (FLAKE_SIZE_LOWER, FLAKE_SIZE_UPPER); 37 // return the snowflake object. 38 return new SnowFlake (random, position, angle, increment, flakeSize, paint); 39} 40 41 SnowFlake (Random random, Point position, float angle, float increment, float flakeSize, paint paint) {42 this. random = random; 43 this. position = position; 44 this. angle = angle; // [-0.05 ~ 0.05) 45 this. increment = increment; // [2f ~ 4f) 46 this. flakeSize = flakeSize; // [7f ~ 20f) 47 this. paint = paint; 48} 49 50 private void move (int width, int height) {51 // The offset in the x direction is small, and the offset in the y direction is large, so that the snow falls quickly. 52 double x = position. x + (increment * Math. cos (angle); // Math. cos (angle) is about 153 double y = position. y + (increment * Math. sin (angle); // Math. sin (0.05 ~ -0.05) = +-[0 ~ 8.7) 54/* 55 * set the position of the snowflake to be positive and do not run out of the screen. [0 ~ 1) * 2 * ANGLE_SEED-ANGLE_SEED equals +-(0 ~ ANGLE_SEED], +-(0 ~ 25f]. Then/else f ===+-(0 ~ 0.0025], 56 *, and then add [-0.05 ~ 0.05) Mom, it's almost dizzy. It's really hard to understand. (-0.0525 ~ 0.0525) 57 */58 59 angle + = random. getRandom (-ANGLE_SEED, ANGLE_SEED)/ANGLE_DIVISOR; 60 61 position. set (int) x, (int) y); // set the new position 62 63 if (! IsInside (width, height) {64 // If the snowflake is not in the view, reset their position. 65 reset (width); 66} 67} 68 69 private boolean isInside (int width, int height) {70 // TODO set snowflake position 71 int x = position. x; 72 int y = position. y; 73 // determine x coordinate x> snowflake size plus 1 distance from the origin (negative direction ). X <background width. You can understand y in the same way. Because of the above settings, in fact, in the x direction, Snow cannot run out of the screen, only on the y direction. 74 return x> =-flakeSize-1 & x + flakeSize <= width & y> =-flakeSize-1 & y-flakeSize 

Jump to the onSizeChange () method. As you can see, when the SnowFlake. create () method is called, the returned result is: (the Random object in it is re-encapsulated and pasted immediately)

1 return new SnowFlake(random, position, angle, increment, flakeSize, paint);

This is the parameter used to draw the SnowFlake. Then, in the reSize () method called by the onSizeChange () method, the snowflake array SnowFlakes [I] is saved.

 

Jump to the front of the above code and then say that in the onDraw () method, the for Loop will draw each snowflake in sequence. SnowFalke. draw (). That is, snowflakes [I] = SnowFlake snowFlake ();

SnowFlake then calls its own draw () method. Since each SnowFlake object saves the parameters of each SnowFlake, it is used directly in draw.

If the snowflake falls, call the move () method in the draw () method to set the position of each snowflake. When the snowflake position runs out of the screen, call the reset () method and reset the snowflake to fall from the top of the screen.

The following is the Random object encapsulation used to set Random data in the code.

1 package com. example. jwwsnow; 2 3 import java. util. arrayList; 4 import java. util. list; 5 6 public class Random {7 8 private static final java. util. random RANDOM = new java. util. random (); 9 10 public float getRandom (float lower, float upper) {11 float min = Math. min (lower, upper); // returns a smaller value of the two. 12 float max = Math. max (lower, upper); 13 return getRandom (max-min) + min; // the return value is smaller than the maximum value and greater than the smallest value. 14} 15 16 public float getRandom (float upper) {17 return RANDOM. nextFloat () * upper; // Random. nextFloat () generate [0 ~ 1) Number of. 18} 19 20 public int getRandom (int upper) {21 return RANDOM. nextInt (upper); // RANDOM generation ratio [0 ~ Upper. 22} 23 public int getColor () {24 return RANDOM. nextInt (255); // randomly generated [0 ~ 255) integer. 25 26} 27}

Then we use the xml reference to write the complete path.

 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3   xmlns:tools="http://schemas.android.com/tools" 4   android:layout_width="match_parent" 5   android:layout_height="match_parent" 6   tools:context="com.stylingandroid.snowfall.MainActivity"> 7  8   <ImageView 9     android:id="@+id/image"10     android:layout_width="match_parent"11     android:layout_height="match_parent"12     android:layout_centerInParent="true"13     android:contentDescription="@null"14     android:scaleType="fitCenter"15     android:src="@drawable/tree" />16 17   <com.example.jwwsnow.SnowView18     android:layout_width="match_parent"19     android:layout_height="match_parent"20     android:layout_alignBottom="@id/image"21     android:layout_alignEnd="@id/image"22     android:layout_alignLeft="@id/image"23     android:layout_alignRight="@id/image"24     android:layout_alignStart="@id/image"25     android:layout_alignTop="@id/image" />26 </RelativeLayout

This document is mainly used to review the process of custom views. We recommend that you first read the original article. Pai_^

Next, I will post some code after the annotation is changed and only use it for Research (eclipse version ...).

Ca, blog can not upload code. Wait until I upload it to git or 360 cloud disk.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.