Custom bean sprinkling

Source: Internet
Author: User

Custom bean sprinkling

 

 

First

The effects of bean sprinkling are an amazing surprise. I think this animation is quite interesting, so I took the time to write a play.

Drawing Process:

Define six ''beans ''. Each bean has its own attributes, size, throw speed, and so on, and then control each direction and status. The rebound effect is implemented using the BounceInterpolator.

Package com. fragmentapp. view. beans; import android. animation. animator; import android. animation. valueAnimator; import android. content. context; import android. graphics. canvas; import android. graphics. paint; import android. util. attributeSet; import android. util. log; import android. view. view; import android. view. animation. bounceInterpolator; import com. fragmentapp. r; import com. fragmentapp. helper. randomUtil;/*** Created by liuzhen on. */public class BeansView extends View {private Paint paint; private int mWidth; private int mHeight; private int top; private ValueAnimator va; private Beans beans1, beans2, beans3, beans4, beans5, beans6; public BeansView (Context context) {this (context, null);} public BeansView (Context context, AttributeSet attrs) {this (context, attrs, 0 );} public BeansView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); init ();} private void init () {Log. e ("tag", "init"); setWillNotDraw (false); paint = new Paint (); paint. setAntiAlias (true); paint. setStyle (Paint. style. FILL); paint. setColor (getResources (). getColor (R. color. color_ff9c19); // the size of the randomly generated sphere, beans1 = new Beans (RandomUtil. random (5, 15); beans2 = new Beans (RandomUtil. random (5, 15); beans3 = new Beans (RandomUtil. random (5, 15); beans4 = new Beans (RandomUtil. random (5, 15); beans5 = new Beans (RandomUtil. random (5, 15); beans6 = new Beans (RandomUtil. random (5, 15) ;}@ Override protected void onLayout (boolean changed, int left, int top, int right, int bottom) {super. onLayout (changed, left, top, right, bottom); if (changed) {mWidth = getWidth (); mHeight = getHeight (); this. top = top; startAnim () ;}@ Override protected void onDraw (Canvas canvas) {// normally drops to the right. You can also randomly generate a direction here, the three canvas on the right on the left is fixed here. drawCircle (beans1.getCx (), beans1.getCy (), beans1.getRadius (), paint); canvas. drawCircle (beans2.getCx (), beans2.getCy (), beans2.getRadius (), paint); canvas. drawCircle (beans3.getCx (), beans3.getCy (), beans3.getRadius (), paint); // let the ball drop the canvas to the left. drawCircle (-beans4.getCx () + mWidth, beans4.getCy (), beans4.getRadius (), paint); canvas. drawCircle (-beans5.getCx () + mWidth, beans5.getCy (), beans5.getRadius (), paint); canvas. drawCircle (-beans6.getCx () + mWidth, beans6.getCy (), beans6.getRadius (), paint);} public void startAnim () {if (mWidth = 0) return; beans1.setState (0); beans1.setOff (0); beans1.setRand (RandomUtil. random (20); // randomly generate the throw speed value beans2.setState (0); beans2.setOff (0); beans2.setRand (RandomUtil. random (20); beans3.setState (0); beans3.setOff (0); beans3.setRand (RandomUtil. random (20); beans4.setState (0); beans4.setOff (0); beans4.setRand (RandomUtil. random (20); beans5.setState (0); beans5.setOff (0); beans5.setRand (RandomUtil. random (20); beans6.setState (0); beans6.setOff (0); beans6.setRand (RandomUtil. random (20); va = ValueAnimator. ofFloat (top, mHeight-top); va. addUpdateListener (new ValueAnimator. animatorUpdateListener () {@ Override public void onAnimationUpdate (ValueAnimator animation) {float val = (float) animation. getAnimatedValue (); beans1.setCy (val); beans1.move (mWidth); // first move the coordinate, which actually changes the value of the off offset beans1.setCx (mWidth/2 + beans1.getOff ()); // refresh the X axis coordinates beans2.setCy (val); beans2.move (mWidth); beans2.setCx (mWidth/2 + beans2.getOff (); beans3.setCy (val); beans3.move ); round (mWidth/2 + beans3.getOff (); beans4.setCy (val); beans4.move (mWidth); Round (mWidth/2 + beans4.getOff (); beans5.setCy (val ); beans5.move (mWidth); beans5.setCx (mWidth/2 + beans5.getOff (); Round (val); beans6.move (mWidth); Round (mWidth/2 + beans6.getOff ()); invalidate () ;}}); va. addListener (new Animator. animatorListener () {@ Override public void onAnimationStart (Animator animator) {}@ Override public void onAnimationEnd (Animator animator) {// prevent the sphere from falling to the ground at different levels due to different radius after stopping. unified horizontal line beans1.setCy (mHeight-beans1.getRadius (); beans2.setCy (mHeight-beans2.getRadius ()); round (mHeight-beans3.getRadius (); beans4.setCy (mHeight-beans4.getRadius (); Round (mHeight-beans5.getRadius (); beans6.setCy (mHeight-beans6.getRadius ()); invalidate () ;}@ Override public void onAnimationCancel (Animator animator) {}@ Override public void onAnimationRepeat (Animator animator) {}}); va. setInterpolator (new BounceInterpolator (); // the va. setDuration (3000); va. setRepeatMode (ValueAnimator. RESTART); va. start ();} public void stopAnim () {va. cancel (); va = null ;}}
View Code

The logic is encapsulated in a separate object, so the view class looks refreshing.

Below are bean classes

Package com. fragmentapp. view. beans; import android. util. log;/*** Created by liuzhen on 2018/1/18. */public class Beans {public Beans () {} public Beans (int radius) {this. radius = radius;}/** X coordinate */private float cx;/** Y coordinate */private float cy;/** offset */private float off; /** randomly generated speed value */private float rand;/** whether the edge exists */private int state;/** ball size */private float radius; /** move the X coordinate and rebound after hitting the boundary */public void move (int width) {if (cx <0 | state = 1) {// touch the left edge state = 1; off + = rand;} else if (cx> = width | state = 2) {// The edge state on the right is 2; off-= rand;} else if (state = 0) {state = 0; off + = rand;} // Log. e ("tag", "-- cx" + (int) cx + "width" + width + "state" + state);} public float getCx () {return cx ;} public void setCx (float cx) {this. cx = cx;} public float getOff () {return off;} public void setOff (float off) {this. off = off;} public float getRand () {return rand;} public void setRand (float rand) {this. rand = rand;} public int getState () {return state;} public void setState (int state) {this. state = state;} public float getCy () {return cy;} public void setCy (float cy) {this. cy = cy;} public float getRadius () {return radius;} public void setRadius (float radius) {this. radius = radius ;}}
View Code

The main logic is concentrated in the move method.

It is thrown normally by default, and then changed to the status after hitting the edge to play back

Only two methods can be followed.

 

The control is placed in a dialog, which I like. Obviously, dialog is not very suitable, or can be added to the header of the drop-down database. The effect should be good.

<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "match_parent" android: layout_height = "match_parent" android: background = "@ drawable/shape_dig_alobg" android: padding = "@ dimen/d20.0" android: orientation = "vertical" android: id = "@ + id/root"> <com. fragmentapp. view. beans. beansView android: id = "@ + id/beans" android: layout_width = "@ dimen/d350.0" android: layout_height =" @ Dimen/d300.0 "android: layout_gravity =" center_horizontal "/> <! -- <View --> <! -- Android: layout_width = "match_parent" --> <! -- Android: layout_height = "@ dimen/d1.0" --> <! -- Android: background = "@ color/white"/> --> <TextView android: id = "@ + id/TV _val" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_gravity = "center_horizontal" android: layout_marginTop = "@ dimen/d20.0" android: text = "loading... "android: textColor =" @ color/color_cccccc "android: textSize =" @ dimen/d43.0 "/> </LinearLayout>
View Code

 

GitHub: https://github.com/1024477951/FragmentApp

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.