Android Custom Arc Tick Selector

Source: Internet
Author: User
Tags asin drawtext gety pow sin

The ARC scale selector implemented by custom view is implemented during Android development with the following effect.

Demo effect

One, measurement:

First, in the Onmeasure method, the width, center, and radius of the current view are obtained by measuring the

Mwidth = Getmeasuredwidth (); mheight = Getmeasuredheight (); Mcenterx = Mwidth/2;mcentery = 0;radius = Math.min (mwidth/2 -Padding, mheight/2-padding);


Two, draw the arc:

Arcs can be drawn by canvas.drawpath or by means of the Canvas.drawarc () method, which is selected in this article by the Canvas.drawpath method, which explains why the DrawPath method is used to draw arcs

int top =-radius;int Bottom = Radius;int left = Mcenterx-radius;int right = Mcenterx + Radius;marcpath.reset (); Marcpath . AddArc (New RECTF (left, top, right, bottom), 0,); Canvas.drawpath (Marcpath, marcpaint);


Three, draw curved tick marks and scale:

How to draw scale floss?? By observing that the tick marks are perpendicular to the arc tangent, we first need to know the current tangents of the tick marks. Pathmeasure.getpostan () can get the xy coordinate and tan value of a point on path, pathmeasure.getlength can get the length of path, GetLength with the Getpostan method gets the POS and tan values of points on the path line, obtains the coordinate value and the tan value, and we can draw the tick mark. The pathmeasure approach only works on path, which explains why the DrawPath method is chosen to draw arcs.

Pathmeasure mpathmeasure = new Pathmeasure () Mpathmeasure.setpath (Marcpath, false); float[] pos = new float[2];float[]  Tan = new Float[2];for (int i = 1; I <= mscalenumber; i++) {  //mscalenumber is the number of tick points, for loop traversal tick point float percentage = I/ (float) mscalenumber;//calculates the percentage of the total scale for the current scale, Mpathmeasure.getpostan (mpathmeasure.getlength () * percentage, POS, tan);// The percentage calculated from the previous step calculates the position of the current tick on path
    Double atan2 = math.atan2 (tan[1], tan[0]);
    Double angle = Calcarcangle (atan2) + 90;//tick line vertical tangent, so rotate 90°int scale = Math.Round (currentangle + mscalemin + i * mscales    PACE);        if (scale >= mscalemin && scale% Mdrawlinespace = = 0) {Float StartX = pos[0];        float starty = pos[1];        float EndX = 0;        float EndY = pos[1]; If (scale% Mdrawtextspace = = 0) {EndX = Pos[0] + 80;mscalelinepaint.setstrokewidth (n); Mscalelinepaint.setcolor (            Mscalelinecolor); if (Currentangle >= (-(MSCALENUMBER/2) * mscalespace)) {canvas.save (); Canvas.rotate ((float) (angle + +), Pos[0], POS [1]);                String Mscaletext = scale + mscaleunit; float scaletextlength = mscaletextpaint.measuretext (mscaletext, 0, Mscaletext.length ()); Canvas.drawtext (MScaleText, Pos[0]-SCALETEXTLENGTH/2, pos[1]-mscaletextpaint); Canvas.restore ();}} else if (scale% Mdrawlinespace = = 0) {mscalelinepaint.setcolor (Mscaletextcolor); Mscalelinepaint.setstrokewidth (10); EndX = pos[0] + 50;} Canvas.save (); Canvas.rotate (FloaT) angle, pos[0], pos[1]) canvas.drawline (StartX, Starty, EndX, EndY, Mscalelinepaint); Canvas.restore ();}} 


Four, draw the currently selected tick value

String Selectedscaletext = Selectedscale + mscaleunit;float selectedscaletextlength = Mselectedtextpaint.measuretext ( Selectedscaletext, 0, Selectedscaletext.length ()); Canvas.drawtext (Selectedscaletext, Mcenterx- SELECTEDSCALETEXTLENGTH/2, Mcentery +, mselectedtextpaint);


Five, Draw Center indicator:

The center indicator is located in the center of the arc, so first get the center point coordinate, tan value to arc. The ARC center point is half the arc length and is mpathmeasure.getlength () * (0.5f). Draw the DrawPath method with the DrawLine method using the coordinate and tan values to draw the cutting head

  
PathMeasure Mpathmeasure = new Pathmeasure (); Mpathmeasure.setpath (Marcpath, false); float[] tan = new float[2];float[] pos = new float [2];mpathmeasure.getpostan (Mpathmeasure.getlength () * (0.5f), POS, tan); Canvas.save ();d ouble angle = Calcarcangle ( Math.atan2 (Tan[1], tan[0])) + 90;canvas.rotate ((float) angle, pos[0], pos[1]);//Draw Line Canvas.drawline (Pos[0], pos[1], POS [0] +, pos[1], mindicatorpaint); Path Linepath = new Path (),//Arrow Linepath.moveto (Pos[0] + Linepath.lineto, pos[1]-(Pos[0] + + +, pos[1]); Linepa Th.lineto (Pos[0] +, pos[1] +); Canvas.drawpath (Linepath, Mindicatorpaint); Canvas.restore (); 


Six, in order to beautiful painting on both sides of the mask layer

There is a linear gradient with white to transparent on both sides of the arc, and the LinearGradient class can implement a linear gradient of the brush.

  
//draw left Matte lineargradient Mleftlineargradient = new LinearGradient (0, 0, mCenterX-100, Color.White, Color.transparent, Shader.TileMode.CLAMP ); Mmaskpaint.setshader (mleftlineargradient); Canvas.drawpath (Marcpath, mmaskpaint);//Draw Right Matte lineargradient Rightlineargradient = new LinearGradient (mwidth, 0, Mcenterx +, Max, Color.White, Color.transparent, Shader.TileMode. CLAMP); Mmaskpaint.setshader (rightlineargradient); Canvas.drawpath (Marcpath, Mmaskpaint); Canvas.drawpath (MArcPath , marcpaint); 


Seven, calculate the sliding angle of rotation:

When touching the screen, there will be horizontal coordinates x and vertical coordinate values y,x and Y and midpoint will produce a triangle, through the trigonometric theorem and the current coordinates we can get to the sin value, through the inverse trigonometric function Math.asin method through the sin value we can calculate the sliding angle. During the sliding process, the angle changes continuously, and the difference of the angle change determines the increment or decrease of the selectors.

Touch the screen to handle the angle

Switch (event.getaction ()) {case MotionEvent.ACTION_DOWN:float mdownx = Event.getx ();        float Mdowny = event.gety (); initangle = Computeangle (Mdownx, mdowny);        if (Mdownx > Mcenterx) {initangle = 180-initangle;} break;    Case MotionEvent.ACTION_MOVE:float Mtouchx = Event.getx ();        float mtouchy = event.gety ();        if (Istouch (Mtouchx, Mtouchy)) {Double moveangle = Computeangle (Mtouchx, mtouchy);            if (Mtouchx > Mcenterx) {moveangle = 180-moveangle;} Double tempangle = moveangle-initangle;            Long AddValue = Math.Round (Tempangle * mevenyscalevalue); Currentangle + = AddValue;            if (Currentangle >=-(MSCALENUMBER/2) * mscalespace) {invalidate ();} else {currentangle = Currentangle-addvalue;} Initangle = Moveangle;            return true;} break;}


Calculation angle

Private double Computeangle (float Touchx, float touchy) {Double atan2 = math.atan2 (touchy, touchx);    Double Taperededge = math.sqrt (Math.pow (Touchx-mcenterx, 2) + Math.pow (Touchy-mcentery, 2));//compute hypotenuse double sin = (touchy -mcentery)/Taperededge;    Double asin = Math.asin (sin);    Double calcarcangle = calcarcangle (ASIN);    return calcarcangle;}


This article explains how to achieve a curved scale selector, due to my limited ability, there must be a lot of shortcomings, forget everyone's opinion

? You can download the complete code to Https://github.com/yhongm/ArcScaleView and have detailed comments in the code. Welcome everyone Fork,star

Android Custom Arc Tick Selector

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.