Reprint please indicate the source: Wang 亟亟 's way of Daniel
The Spring Festival is 1 days away. Continue this series of Git flipping tours.
Yesterday's tool class is really very good, here again to praise the Portal: http://blog.csdn.net/ddwhan0123/article/details/50624061 (the actual experience of the small partners have agreed)
A button that you defined today:Sendbutton
Effect:
It's recommended to pull out the code. Because there is not much content, a class is finished.
Address: Https://github.com/ddwhan0123/SendButton
Because there is not much content. Let's analyze it.
publicclass SendButton extends View
31 lines. Inherit view instead of ViewGroup (that is, unlike a layout that draws something out of a floor, it is a pure painting)
int0; Point a, b, c, d, e; Path mOutlinePath, mPlanePath; int mButtonColor, mButtonSide, mBorderStrokeWidth, mPlaneStrokeWidth, mPlaneColor; Paint mBackgroundPaint, mPlanePaint; ValueAnimator mPlaneAnimator; long mDuration; AnimationType mAnimationType;
35-42, define a series of variables, animation mode Ah, the duration AH. Brushes, sizes, whatever.
Public Sendbutton (context context, AttributeSet Attrs) {Super (context, attrs);TypedArray A = Context. Gettheme(). Obtainstyledattributes(Attrs, R. Styleable. Sendbutton,0,0);try {Mbuttoncolor = a. GetColor(R. Styleable. Sendbutton_buttoncolor, Color. White);Mbuttonside = A. Getdimensionpixelsize(R. Styleable. Sendbutton_buttonside, $);Mborderstrokewidth = A. Getinteger(R. Styleable. Sendbutton_borderstrokewidth,5);Mplanestrokewidth = A. Getinteger(R. Styleable. Sendbutton_planestrokewidth,5);Mplanecolor = A. GetColor(R. Styleable. Sendbutton_planecolor, Getresources (). GetColor(R. Color. Orange));Manimationtype = Animationtype. Values() [A. Getinteger(R. Styleable . Sendbutton_animationtype,0)];Mduration = A. Getinteger(R. Styleable. Sendbutton_duration, the);} catch (Exception e) {E. Printstacktrace();} finally {a. Recycle();} init ();}
45-74, the constructor, gets a series of contents of the tag, fills in the preceding variables, and then calls the Init () method.
Private void Init() {Mbackgroundpaint =NewPaint (Paint.anti_alias_flag); Mplanepaint =NewPaint (Paint.anti_alias_flag); Mbackgroundpaint.setstyle (Paint.Style.STROKE); Mplanepaint.setstrokewidth (Mplanestrokewidth); Mbackgroundpaint.setstrokewidth (Mborderstrokewidth); Mbackgroundpaint.setcolor (Mbuttoncolor); Moutlinepath =NewPath (); Mplanepath =NewPath (); Mplaneanimator = Valueanimator.ofint (0, the); Mplaneanimator.setduration (mduration); Mplaneanimator.setrepeatmode (Valueanimator.restart); Mplaneanimator.setrepeatcount (Valueanimator.infinite);Switch(Manimationtype) { CaseLINEAR:mPlaneAnimator.setInterpolator (NewLinearinterpolator ()); Break; CaseANTICIPATE:mPlaneAnimator.setInterpolator (NewAnticipateinterpolator ()); Break; CaseANTICIPATE_OVERSHOOT:mPlaneAnimator.setInterpolator (NewAnticipateovershootinterpolator ()); Break; CaseACCELERATE:mPlaneAnimator.setInterpolator (NewAccelerateinterpolator ()); Break; CaseACCELERATE_DECELERATE:mPlaneAnimator.setInterpolator (NewAcceleratedecelerateinterpolator ()); Break; CaseBOUNCE:mPlaneAnimator.setInterpolator (NewBounceinterpolator ()); Break; CaseDECELERATE:mPlaneAnimator.setInterpolator (NewDecelerateinterpolator ()); Break; CaseFASTOUTLINEARIN:mPlaneAnimator.setInterpolator (NewFastoutlinearininterpolator ()); Break; CaseFASTOUTSLOWIN:mPlaneAnimator.setInterpolator (NewFastoutslowininterpolator ()); Break; CaseLINEAROUTSLOWIN:mPlaneAnimator.setInterpolator (NewLinearoutslowininterpolator ()); Break; CaseOVERSHOOT:mPlaneAnimator.setInterpolator (NewOvershootinterpolator ()); Break; } mplaneanimator.start ();/** * The coordinates position calculated by percentage of button side. */A =NewPoint (Mbuttonside *Ten) / -, (Mbuttonside * -) / -);//Point A: (10% of Mbuttonside, 55% of Mbuttonside)b =NewPoint (Mbuttonside * the) / -, (Mbuttonside * -) / -);//point B: (80% of Mbuttonside, 20% of Mbuttonside)c =NewPoint (Mbuttonside * $) / -, (Mbuttonside * -) / -);//Point C: (45% of Mbuttonside, 90% of Mbuttonside)D =NewPoint (Mbuttonside * -) / -, (Mbuttonside * -) / -);//Point D: (30% of Mbuttonside, 70% of Mbuttonside)E =NewPoint (Mbuttonside/2, Mbuttonside/2);//Point e: (10% of Mbuttonside, 55% of Mbuttonside)}
76-139, color the brush, and then select the Interpolator mode (sudden acceleration ah, slow ah.) A series of patterns that I have in my previous view article, Portal: http://blog.csdn.net/ddwhan0123/article/details/50464283)
Another is to calculate the coordinates of each point, draw the triangle are used. (This part of the algorithm is not studied.) Anyway, it's based on the control size.
public void SetPath () {Mplanepath = new Path ();Mplanepath. MoveTo(A. xA. Y);//set the starting point to AMplanepath. LineTo(A. xA. Y);Mplanepath. LineTo(b. xB. Y);Mplanepath. LineTo(c. xC. Y);Mplanepath. LineTo(d. xD. Y);Mplanepath. LineTo(E. xE. Y);Mplanepath. LineTo(d. xD. Y);Mplanepath. LineTo(A. xA. Y);}
164-174, draw the track with
Private void Translate() {A.Set((Mbuttonside *Ten) / -, (Mbuttonside * -) / -);//Point A: (10% of Mbuttonside, //55% of Mbuttonside)B.Set((Mbuttonside * the) / -, (Mbuttonside * -) / -);//point B: (80% of Mbuttonside, //20% of Mbuttonside)C.Set((Mbuttonside * $) / -, (Mbuttonside * -) / -);//Point C: (45% of Mbuttonside, //90% of Mbuttonside)D.Set((Mbuttonside * -) / -, (Mbuttonside * -) / -);//Point D: (30% of Mbuttonside, //70% of Mbuttonside)E.Set(Mbuttonside/2, Mbuttonside/2);//Point e: (10% of Mbuttonside, 55% of //Mbuttonside) intChange =3* (int) Mplaneanimator.getanimatedvalue (); LOG.I (LogTag,"animated Value:"+ Change +", Flag:"+ flag++); a.x + = change; A.Y-= change; b.x + = change; B.Y-= change; c.x + = change; C.Y-= change; D.x + = change; D.Y-= change; e.x + = change; E.Y-= change; Invalidate (); }
178-209, the triangle used, the triangle has a concave angle problem, the calculation is still a bit of a brain (algorithm poor, sad)
privateenum AnimationType { LINEAR, ANTICIPATE, ANTICIPATE_OVERSHOOT, ACCELERATE, ACCELERATE_DECELERATE, BOUNCE, DECELERATE, FASTOUTLINEARIN, FASTOUTSLOWIN, LINEAROUTSLOWIN, OVERSHOOT }
211-224, enumeration of various types of interpolator
@Override protected void OnDraw (canvas canvas) {Super. OnDraw(canvas);Mbackgroundpaint. Setalpha(255);Moutlinepath. Addroundrect(New RECTF (0,0, Mbuttonside, Mbuttonside), Mbuttonside/3, Mbuttonside/3, Path. Direction. CCW);Canvas. DrawPath(Moutlinepath, Mbackgroundpaint);Canvas. Clippath(Moutlinepath);For different color of Fill andStroke,//First paintedinchFill style andThen Stroke style with different color mplanepaint. SetStyle(Paint. Style. FILL);Mplanepaint. SetColor(Mplanecolor);Mplanepaint. Setalpha(255-((int) mplaneanimator. Getanimatedvalue() * -) /Ten);Translate ();SetPath ();Canvas. DrawPath(Mplanepath, Mplanepaint);Mplanepaint. SetStyle(Paint. Style. STROKE);Mplanepaint. SetColor(Color. White);Mplanepaint. Setalpha(255-((int) mplaneanimator. Getanimatedvalue() * -) /Ten);Canvas. DrawPath(Mplanepath, Mplanepaint);}
142-162, detailed painting implementation, this part to read
The brush is first done with some rounded corners. Then draw the square and draw the circle. Then use direction to remove unnecessary parts. There's a white line in our outer ring.
Then there is the triangle. The triangle is also based on position and animation position has been in the brush UI.
So this control lasts a lot longer, and there may be a lag phenomenon.
Background ah, size ah, triangle color these can be changed. But to change it in XML, the author does not provide a set of methods.
OK, here it is. I'm on vacation tomorrow. Some things at home may stop more, after the holiday at home nothing to do when the time to fill it, Happy New Year!!
!!
Flip git---Define email buttonsendbutton (Process analysis, realization of ideas to learn)