Android uses Surfaceview custom draw big turntable _android

Source: Internet
Author: User
Tags drawtext

Use Surfaceview custom Draw big Turntable

Say not much, first on the effect chart

Full Code address Welcome start

Realization of ideas and processes

1, first understand the basic use of surfaceview, it is not the same as the general view, the use of dual caching mechanism, you can draw the view in the child thread, not because of the time to draw a loss of fluency, which is also the choice to use Surfaceview to customize this lottery big turntable reason, After all, drawing the disk block of this turntable, the picture and text of the award and the rotation are all by drawing out, is a more time-consuming drawing process.

2, the use of Surfaceview general template style

Member variables that are typically used

Private Surfaceholder Msurfaceholder;
Private Canvas    Mcanvas;

Initialization is always bright

Public surfaceviewtemplate (Context Context,attributeset attrs) {
  Super (context, attrs);
  Initialize
  Msurfaceholder = Getholder ();
  Msurfaceholder.addcallback (this);
  Set the focus to
  setfocusable (true);
  Setfocusableintouchmode (true);
  This is illuminated steady
  Setkeepscreenon (true);
}

Add callback to Surfaceview to implement three of these methods

 @Override public
void surfacecreated (Surfaceholder surfaceholder) {
  //surface created
  mthread = new Thread ( this);
  Opens the thread isrunning = True when it is created
  ;
  Mthread.start ();
}

@Override public
void surfacechanged (surfaceholder surfaceholder, int i, int i1, int i2) {
  //change Time
}
shut down the thread when @Override public void surfacedestroyed (Surfaceholder surfaceholder) {
  //destroy
  isrunning = false;< c16/>}

Define a dead loop in a child thread to draw continuously

 @Override public
Void Run () {
  //constantly drawing while
  (isrunning) {
    draw () in
child threads)

private void Draw () {
  try {
    Mcanvas = Msurfaceholder.lockcanvas ();
    if (null!= mcanvas) {
  //Avoid execution at this time the program has exited Surfaceview has been destroyed so get to canvas null
    }
  catch (Exception e) {
    //exception can not be handled
  } finally {
    //must release canvas to avoid leaking
    msurfaceholder.unlockcanvasandpost (Mcanvas);
  }


3, understand the basic usage of Surfaceview, then realize the lottery turntable

First measure the entire view range, set to square

@Override
  protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
    super.onmeasure ( Widthmeasurespec, Heightmeasurespec);
    Direct control span for square
    int width = math.min (Getmeasuredwidth (), Getmeasuredheight ());
    mpadding = Getpaddingleft ();
    Diameter
    Mradius = width-mpadding * 2;
    Set Center point
    mcenter = WIDTH/2;
    Set to square
    setmeasureddimension (width, width);
  }

Initialize the brush rectangle range when Surfaceview is created, see Code

public void surfacecreated (Surfaceholder surfaceholder) {//Initialize brush for drawing span mspanpaint = new Paint ();
    Mspanpaint.setantialias (TRUE);
    Mspanpaint.setdither (TRUE);
    Initializes the brush that draws the text Mtextpaint = new Paint ();
    Mtextpaint.settextsize (mtextsize);
    Mtextpaint.setcolor (0xffa58453);
    Draws a circle's brush mcirclepaint = new Paint ();
    Mcirclepaint.setantialias (TRUE);
    Mcirclepaint.setcolor (0xffdfc89c);
    Initialize span range mrectrange = new RECTF (mpadding, mpadding, mpadding + Mradius, mpadding + Mradius);  Mrectcirclerange = new RECTF (mpadding * 3/2, mpadding * 3/2, Getmeasuredwidth ()-mpadding * 3/2, Getmeasuredwidth ()
    -mpadding * 3/2);
    Initialize Bitmap Mimgiconbitmap = new Bitmap[mspancount]; Store the icon for the award as bitmap for (int i = 0; i < Mspancount i++) {Mimgiconbitmap[i] = Bitmapfactory.decoderesource (g
    Etresources (), mprizeicon[i]);
    Mthread = new Thread (this) when//surface is created;
    Opens the thread isrunning = True when it is created; Mthread.Start ();

 }

The next step is to draw in an open child thread

 @Override public
  Void Run () {
    //continuous drawing while in child threads while
    (isrunning) {
      //guaranteed to draw no less than 50 millisecond optimization performance
      long start = Systemclock.currentthreadtimemillis ();
      Draw ();
      Long end = Systemclock.currentthreadtimemillis ();
      if ((End-start) <) {
        //Hibernate to 50 milliseconds
        systemclock.sleep (End-start);
      }
  }}

The emphasis is on the following implementation of the draw method in the Draw () method:

Note: avoid memory leaks caused by Mcanvas

 try {
    Mcanvas = Msurfaceholder.lockcanvas ();
    if (null!= mcanvas) {
      //Avoid execution at this time the program has exited Surfaceview has been destroyed so get to canvas null
      //Draw background
      DRAWBG ();
      Draw Ring
      mcanvas.drawcircle (Mcenter, Mcenter, MRADIUS/2 + mpadding/20, mcirclepaint);
      Drawspan ();
    }
  catch (Exception e) {
    //exception can not be handled
  } finally {
    //must be released canvas avoid leaking
    Msurfaceholder.unlockcanvasandpost (Mcanvas);
  }

Drawing background:

Draw background
  private void Drawbg () {
    //background set to white
    mcanvas.drawcolor (0xFFFFFFFF);
    Mcanvas.drawbitmap (Mspanbackground, NULL, new RECTF (MPADDING/2, MPADDING/2, Getmeasuredwidth ()-MPADDING/2, GetMeas Uredheight ()-MPADDING/2), mspanpaint);
  }

Parameter explanation:

  Mspanbackground background picture
  new RECTF (MPADDING/2, MPADDING/2, Getmeasuredwidth ()-MPADDING/2, Getmeasuredheight ()-MPa DDING/2)
  //restricted background in a rectangular range or something 

Draw Inner Ring

Mcanvas.drawcircle (Mcenter, Mcenter, MRADIUS/2 + mpadding/20, mcirclepaint); 

Draw eight pieces of disk in the middle

Define a variable temp record start turning angle
float tempangle = mstartspanangle;
Each disk block occupies an angle Circle_angle = 360
float sweepangle = circle_angle/mspancount;
Loops draw Eight plates
  for (int i = 0; i < Mspancount i++) {
    //Set the color of each disk block brush
    mspanpaint.setcolor (mspancolor[i)); c14/>//Draws a pie block, the fourth argument is true is a fan or arc
    Mcanvas.drawarc (Mrectcirclerange, Tempangle, Sweepangle, True, Mspanpaint) ;
    Draw Text
    DrawText (Tempangle, Sweepangle, Mprizename[i]);
    Draw Awards Icon
    Drawprizeicon (Tempangle, mimgiconbitmap[i]);
      Change the angle
      tempangle + = Sweepangle;
    }

Draw text

Text is drawn as a doughnut shape, drawing text according to Path

private void DrawText (float tempangle, float sweepangle, String text) {
  //Draw Curved text path to draw text from path path path
  = new P Ath ();
  Path.addarc (Mrectrange, Tempangle, sweepangle);
  To center the text horizontally the starting point of the drawing text is half the radian-half of the text
  float textWidth = mtextpaint.measuretext (text);
  float hoval = (float) ((Mradius * math.pi/mspancount/2)-(TEXTWIDTH/2));

  float Voval = mradius/15;//Vertical offset can be customized

  mcanvas.drawtextonpath (text, Path, Hoval, Voval, Mtextpaint); The third four parameters are vertical and horizontal offsets
}

Draw a prize in a disk block icon picture

private void Drawprizeicon (float tempangle, Bitmap Bitmap) {
  //the size of the picture is set to a diameter of 1/8
  int iconwidth = MRADIUS/20;
  Calculate the icon center point//angle based on the angle
  1 degrees = = math.pi/180
  Double angle = (Tempangle + CIRCLE_ANGLE/MSPANCOUNT/2) * Math.PI/ 180;
  According to trigonometric functions, the Computing Center Point (x,y)
  int x = (int) (Mcenter + MRADIUS/4 * Math.Cos (angle));
  int y = (int) (Mcenter + MRADIUS/4 * Math.sin (angle));
  Defines a rectangle that restricts the icon position
  RECTF RECTF = new RECTF (x-iconwidth, y-iconwidth, x + iconwidth, y + iconwidth);
  Mcanvas.drawbitmap (bitmap, NULL, RECTF, NULL);

Rough drawing is basically done, the focus is to change the starting point of rotation to turn the turntable.

 Mstartspanangle + = Mspeed;//mspeed Numerical control rotational speed
   //declaration of an end sign
  if (isspanend) {
    Mspeed-= 1;
  }
  if (mspeed <= 0) {
    //stop spinning
    mspeed = 0;
    Isspanend = false;
    Define a callback, monitor the turntable to stop turning
   Mspanrolllistener.onspanrolllistener (mspeed);
  }

Define a method to start the turntable

  float angle = circle_angle/mspancount;
  The angle range at which the pointer rests under a certain index half_circle_angle=180
  float from = half_circle_angle-(index-1) * ANGLE;
  Float end = from + angle;

  Set the distance that the rotation needs to be stopped to ensure that the same position under one index at a time does not stay
  float Targetfrom = 4 * circle_angle + from;
  float targetend = 4 * circle_angle + end;//The final stop position between From-end, 4 * Circle_angle custom to turn a few more laps

  /calculate the speed of the range of time to stay down, Note here: The formula involved in arithmetic progression, because it involves making the turntable stop turning is to make the mspeed-=1, so it is a process from the vfrom--0, so it can be calculated out Vfrom, the same calculation vend
  float vfrom = (float) ( (MATH.SQRT (1 + 8 * targetfrom)-1)/2);
  Float Vend = (float) ((math.sqrt (1 + 8 * targetend)-1)/2);
  The index value passed in when the click starts to rotate has been decided to stay on that item
  mspeed = Vfrom + math.random () * (vend-vfrom);
  Isspanend = false;
}

Stop turning

 public void Luckstop () {
  //force when stopping the turntable the starting angle is assigned to 0 because the angle calculation of the control stop specified position is Mstartspanangle = 0 based on the starting angle of 0
  ;
  Isspanend = true;
}

Specific implementation involves some mathematical knowledge, may tell not very clear, but on the code is better, directly to see the code will be more clear, code comments in detail, to prevent the future when they look back to forget. Welcome to visit the GitHub address, see the complete code, you can change according to their needs, by the way learn about the custom view to learn about the use of Surfaceview.

Address: Full code address Welcome to start, if there is a problem, please give a lot of advice to learn and communicate with each other.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.