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.