Because the company project needs to do nine lottery, has not done similar functions before, although before browsing the blog of the Great Gods, inadvertently also saw a lot about the lottery project, but because there is no need for the project, has not been clicked to see. Not to see this time. Until the company plans to do lottery function, only to find a demo online
Online looking for most of the day, and finally found a few demo, download down, decompression bag found unexpectedly inside empty, only a few nine Sudoku pictures, I wasted a few csdn points. Back in the EoE site that found a demo, so good happy, download immediately after the import into the project, run to see the effect, nine Sudoku is out, but the effect is really not flattering, mainly run not smooth. But I went into a little look at the demo, the basic idea is this: Define a good nine Sudoku interface, and then open the child thread constantly cyclic modify state, and then through the handler send messages to the main thread to modify the interface (child thread can not directly modify the interface).
Although this demo function is realized, but not the effect I want, because I can not pass this one, to the product side more needless to say. What about it?
So I thought of a control, called Surfaceview, do game development comrades, should this control is not unfamiliar? First, let's introduce this control:
1.SurfaceView inherits from view and is used in game development
2. Can be run directly in a child thread (other UI controls must be running in the main thread).
3. The General UI control customization is overridden by the OnDraw method, but in Surfaceview the surfaceholder gets canvas to draw the graph
All right, come on, guys, let's take a look at the effect chart:
In this way, I begin by saying the steps of the custom nine Sudoku according to my idea.
Steps:
1. Calculate the position of the squares
2. Draw each prize box (mainly make the interface more beautiful)
3. Draw a prize map
4. Calculate the next position of the rotation box
5. Draw the Rotation box
6. Monitor Click Start button Event
Main Core Technology:
Surfaceview,surfaceholder
OK, with the basic steps, the next step is to proceed step-by-step.
Before we start drawing the nine Sudoku, we rewrite the Onmeasure method, mainly to make the nine Sudoku a square, so that it looks better, and the basic code is as follows:
public class Lotteryview extends surfaceview{
/**
* Holder
/private Surfaceholder mholder;
Private list<prize>prizes;
private Boolean flags; Lottery switch
private int lottery=6; Set the winning number
private int current=2; The position of the lottery begins
private int count=0; Rotation number of cumulative
private int countdown; The number of times, the speed of rotation after the completion of the number of cycles to be counted to stop
//rotate the Lottery box default color
private int transfer= 0xffff0000;
private int max=50; Max rotational times
/**
* Re
-measuring
/@Override protected void onmeasure (int widthmeasurespec, int Heightmeasurespec)
{
super.onmeasure (Widthmeasurespec, heightmeasurespec);
int width = math.min (Getmeasuredwidth (), Getmeasuredheight ());
Setmeasureddimension (width, width);
}
Surfaceview generally do not use the rewrite OnDraw method to draw the control, then how to get to canvas? Mainly through the Surfaceholder monitoring callback events to obtain
The basic code is as follows:
/**
* Holder
/private Surfaceholder mholder;
Public Lotteryview (context, AttributeSet attrs) {
Super (context, attrs);
Mholder = This.getholder ();
Monitor callback
Mholder.addcallback (this);
}
Public Lotteryview {This
(context,null);
}
Now that we have the object Surfaceholder object, we can get to the canvas object and start the real drawing work below.
1. Calculate the concrete display position of the square
2. Draw the squares of each prize
Draw background
private void Drawbg (Canvas Canvas) {
//clear Drawn graphics
Canvas.drawcolor (Color.White, mode.clear);
Gets the width of the control, because you want to draw the nine Sudoku, so draw into three columns
int width = getmeasuredwidth ()/3;
int x1=0;
int y1=0;
int x2=0;
int y2=0;
int len = (int) math.sqrt (prizes.size ());
for (int x=0;x<len*len;x++) {
Prize Prize = prizes.get (x);
int index=x;
X1=getpaddingleft () +width* (Math.Abs (index)%len);
Y1=getpaddingtop () +width* (Index/len);
X2=x1+width;
Y2=y1+width;
Rect rect=new Rect (x1,y1,x2,y2);
Paint paint=new Paint ();
Draw Square
Canvas.drawrect (rect, paint);
}
Parsing: Prizes is a collection that encapsulates some of the basic information about the prizes, x1,y1,x2,y2 the top left and bottom right vertices of the prize container square, respectively,
The observation shows that each square position has a certain relationship, namely X1=getpaddingleft () +width* (Math.Abs (index)%len);
Y1=getpaddingtop () +width* (Index/len);
X2=x1+width;
With the relationship of these points, you can pass Canvas.drawrect (rect, paint); draw the squares.
3. Draw a prize map
Draw Prizes
private void Drawprize (Canvas Canvas) {
int width = getmeasuredwidth ()/3;
int x1=0;
int y1=0;
int x2=0;
int y2=0;
int len = (int) math.sqrt (prizes.size ());
for (int x=0;x<len*len;x++) {
Prize Prize = prizes.get (x);
int index=x;
X1=getpaddingleft () +width* (Math.Abs (index)%len);
Y1=getpaddingtop () +width* (Index/len);
X2=x1+width;
Y2=y1+width;
Rect rect=new Rect (X1+WIDTH/6,Y1+WIDTH/6,X2-WIDTH/6,Y2-WIDTH/6);
Prize.setrect (rect);
Canvas.drawbitmap (Prize.geticon (), NULL, rect, NULL);
}
Through the steps 1,2 know the position of the box, you can easily draw on the relationship between the prizes, Rect rect=new Rect (X1+WIDTH/6,Y1+WIDTH/6,X2-WIDTH/6,Y2-WIDTH/6); is to let the prizes, for example, shrink a little bit, so it will look more natural.
4. Calculate the next position of the rotation box
Next public
int next (int position,int len) {
int current=position;
if (Current+1<len) {return
++current;
}
if ((current+1)%len==0&¤t<len*len-1) {return
current+=len;
}
if (current%len==0) {return
current-=len;
}
if (Current<len*len) {return
--current;
}
return current;
}
Position is the position of the current rotation box, Len is 3
5. Draw the Rotation box
Draw the rotated box
private void Drawtransfer (Canvas Canvas) {
int width = getmeasuredwidth ()/3;
int x1;
int y1;
int x2;
int y2;
int len = (int) math.sqrt (prizes.size ());
Get the next box position
Current=next (current, Len);
X1=getpaddingleft () +width* (Math.Abs (current)%len);
Y1=getpaddingtop () +width* (current)/len);
X2=x1+width;
Y2=y1+width;
Rect rect=new Rect (x1,y1,x2,y2);
Paint paint=new Paint ();
Paint.setcolor (transfer);
Canvas.drawrect (rect, paint);
}
6. Monitor Click Start button Event
Private Ontransferwinninglistener listener;
public void Setontransferwinninglistener (Ontransferwinninglistener listener) {This.listener=listener; public interface ontransferwinninglistener{/** * Jackpot Callback * @param position/void onwinning (int
position);
@Override public boolean ontouchevent (Motionevent event) {Handletouch (event);
Return Super.ontouchevent (event); /** * Touch * @param event/public void Handletouch (Motionevent event) {Point Touchpoint=new Point (i
NT) Event.getx ()-getleft (), (int) event.gety ());
Switch (event.getaction ()) {case MotionEvent.ACTION_DOWN:Prize Prize = Prizes.get (Math.Round (Prizes.size ())/2);
if (Prize.isclick (touchpoint)) {if (!flags) {setstartflags (true);
Prize.click ();
}} break;
Default:break;
Control rotation private void Controllertransfer () {if (Count>max) {countdown++; SystemClock.sleep (COUNT*5);
}else{Systemclock.sleep (count*2);
} count++;
if (countdown>2) {if (lottery==current) {countdown=0;
count=0;
Setstartflags (FALSE); if (listener!=null) {//switch to run post in main thread (new Runnable () {@Override public void R
Un () {listener.onwinning (current);
}
});
}
}
}
}
At this point, the basic customization work is almost done, using the demo as follows:
<?xml version= "1.0" encoding= "Utf-8"?> <relativelayout xmlns:android=
"http://schemas.android.com/apk" /res/android "
android:layout_width=" match_parent "
android:layout_height=" match_parent "
android:o" rientation= "vertical" >
<com.example.test.lotteryview
android:id= "@+id/nl"
android:layout_ Width= "Match_parent"
android:layout_height= "match_parent"
/>
</RelativeLayout>
public class Homeactivity extends activity {Lotteryview nl;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.act_home);
Nl= (Lotteryview) Findviewbyid (r.id.nl); Int[]prizesicon={r.drawable.danfan,r.drawable.meizi,r.drawable.iphone,r.drawable.f015,r.drawable.arrow,
R.drawable.f040,r.drawable.ipad,r.drawable.spree_icon,r.drawable.spree_success_icon};
Final List<prize>prizes=new arraylist<prize> ();
for (int x=0;x<9;x++) {Prize lottery=new Prize ();
Lottery.setid (x+1);
Lottery.setname ("Lottery" + (x+1));
Bitmap Bitmap = Bitmapfactory.decoderesource (Getresources (), prizesicon[x]);
Lottery.seticon (bitmap);
if ((x+1)%2==0) {Lottery.setbgcolor (0XFF4FCCEE);
}else if (x==4) {lottery.setbgcolor (0xFFFFFFFF);
}else{Lottery.setbgcolor (0XFF00FF34);
} prizes.add (lottery); } nl.setprizes (Prizes); Nl.setontransferwinninglistener (New Ontransferwinninglistener () {@Override public void onwinning (int positio
N) {Toast.maketext (Getapplicationcontext (), prizes.get (position). GetName (), Toast.length_short). Show ();
}
});
}
}
Very smooth running effect
Lotteryview Overall Demo:
Package com.example.test;
Import java.util.List;
Import Java.util.Random;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors;
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.Point;
Import Android.graphics.PorterDuff;
Import Android.graphics.PorterDuff.Mode;
Import Android.graphics.Rect;
Import Android.os.SystemClock;
Import Android.util.AttributeSet;
Import android.view.MotionEvent;
Import Android.view.SurfaceHolder;
Import Android.view.SurfaceHolder.Callback;
Import Android.view.SurfaceView;
public class Lotteryview extends Surfaceview implements callback{/** * Holder/private Surfaceholder Mholder;
Private list<prize>prizes;
private Boolean flags; private int lottery=6; Set the winning number private int current=2; The position of the lottery begins private int count=0; Rotation number of cumulative private int countdown; Number of times, after the rapid rotation is completed, the number of cycles to be counted to stop the private int transfer= 0xFFFF0000; private int max=50;
Maximum number of rotations private ontransferwinninglistener listener;
public void Setontransferwinninglistener (Ontransferwinninglistener listener) {This.listener=listener;
public interface ontransferwinninglistener{/** * Jackpot Callback * @param position/void onwinning (int position); /** * Set the winning number * @param lottery/public void setlottery (int lottery) {if Prizes!=null&&math.round (prize S.size ()/2) ==0 {throw new RuntimeException ("Start the Lottery button cannot be set to the winning position!")
");
} this.lottery = lottery;
/** * Set Turntable color * @param transfer */public void settransfer (int transfer) {this.transfer = transfer;
/** * Set the collection of prizes * @param prizes */public void setprizes (list<prize>prizes) {this.prizes=prizes;
@Override public boolean ontouchevent (Motionevent event) {Handletouch (event);
Return Super.ontouchevent (event); /** * Touch * @param event/public void Handletouch (Motionevent event) {point touchpoint=new Point (int) event.g EtX ()-getlEFT (), (int) event.gety ());
Switch (event.getaction ()) {case MotionEvent.ACTION_DOWN:Prize Prize = Prizes.get (Math.Round (Prizes.size ())/2);
if (Prize.isclick (touchpoint)) {if (!flags) {setstartflags (true);
Prize.click ();
}} break;
Default:break; The private class Surfacerunnable implements runnable{@Override public void Run () {while (flags) {Canvas canvas=n
ull;
try {canvas = Mholder.lockcanvas ();
DRAWBG (canvas);
Drawtransfer (canvas);
Drawprize (canvas);
Controllertransfer ();
catch (Exception e) {e.printstacktrace (); }finally{//Trickle Ms. Clever ╂ piles Rao $ 粯 鍒 stamp trajectory 褰 ㈡ 椂 鑳 luo 埄 ma 涜 adze 屾 渶 Lian I 皢 nowshera 攣 鏀 father Juan Lang 傚 屽 Ricoh 嗭 紝 cen 熷 ammonia 鏄 adze 屽 鏋 Noble laser Anvas brand-紝-閮 by 皢 鍏 stamp just 闂 紝 Ms. Clever ╀ Lower Rao ″ 鐜
鍒 ╄ Indent 粯 鍒 if (canvas!=null) mholder.unlockcanvasandpost (canvas);
()}}//Draw background private void Drawbg (Canvas Canvas) {canvas.drawcolor (Color.White, mode.clear);
int width = getmeasuredwidth ()/3;
int x1=0;
int y1=0;
int x2=0;
int y2=0;
int len = (int) math.sqrt (prizes.size ()); for (iNT x=0;x<len*len;x++) {Prize Prize = prizes.get (x);
int index=x;
X1=getpaddingleft () +width* (Math.Abs (index)%len);
Y1=getpaddingtop () +width* (Index/len);
X2=x1+width;
Y2=y1+width;
Rect rect=new Rect (x1,y1,x2,y2);
Paint paint=new Paint ();
Paint.setcolor (Prize.getbgcolor ());
Canvas.drawrect (rect, paint);
}///Draw the rotated box private void Drawtransfer (Canvas Canvas) {int width = getmeasuredwidth ()/3;
int x1;
int y1;
int x2;
int y2;
int len = (int) math.sqrt (prizes.size ());
Current=next (current, Len);
X1=getpaddingleft () +width* (Math.Abs (current)%len);
Y1=getpaddingtop () +width* (current)/len);
X2=x1+width;
Y2=y1+width;
Rect rect=new Rect (x1,y1,x2,y2);
Paint paint=new Paint ();
Paint.setcolor (transfer);
Canvas.drawrect (rect, paint);
//control rotation private void Controllertransfer () {if (Count>max) {countdown++;
Systemclock.sleep (COUNT*5);
}else{Systemclock.sleep (count*2);
} count++; if (countdown>2) {if (lottery==current) {countdown=0;
count=0;
Setstartflags (FALSE); if (listener!=null) {//switch to run post in main thread (new Runnable () {@Override public void run () {listener.onwinning) (CU
Rrent);
}
});
}}} public void Setstartflags (Boolean flags) {this.flags=flags;
//Draw Prizes private void Drawprize (Canvas Canvas) {int width = getmeasuredwidth ()/3;
int x1=0;
int y1=0;
int x2=0;
int y2=0;
int len = (int) math.sqrt (prizes.size ());
for (int x=0;x<len*len;x++) {Prize Prize = prizes.get (x);
int index=x;
X1=getpaddingleft () +width* (Math.Abs (index)%len);
Y1=getpaddingtop () +width* (Index/len);
X2=x1+width;
Y2=y1+width;
Rect rect=new Rect (X1+WIDTH/6,Y1+WIDTH/6,X2-WIDTH/6,Y2-WIDTH/6);
Prize.setrect (rect);
Canvas.drawbitmap (Prize.geticon (), NULL, rect, NULL);
} public void Start () {Setlottery (Getrandom ());
Executorservice service = Executors.newcachedthreadpool ();
Service.execute (New surfacerunnable ()); //Get random Jackpot number, the actual development of the general winning number is the server tells us the private int GetraNdom () {Random r=new Random ();
int Nextint =r.nextint (prizes.size ());
if (nextint% (Math.Round (Prizes.size ()/2)) ==0) {//random number equals middle start position, it needs to continue to shake random number return getrandom ();
return nextint;
//Next public int next (int position,int len) {int current=position;
if (Current+1<len) {return ++current;
} if ((current+1)%len==0&¤t<len*len-1) {return current+=len;
} if (current%len==0) {return current-=len;
} if (Current<len*len) {return--current;
return to current;
Public Lotteryview (context, AttributeSet attrs) {Super (context, attrs);
Mholder = This.getholder ();
Mholder.addcallback (this);
{This (context,null) is public lotteryview; @Override public void surfacechanged (surfaceholder holder, int format, int width, int height) {} @Override Pub
LIC void surfacecreated (Surfaceholder holder) {Canvas canvas=null;
try {canvas = Mholder.lockcanvas ();
DRAWBG (canvas);
Drawprize (canvas); Prize Prize = Prizes.get (Math.Round (Prizes.size ()/2));
Prize.setlistener (New Prize.onclicklistener () {@Override public void OnClick () {start ();
}
});
catch (Exception e) {e.printstacktrace ();
}finally{if (canvas!=null) mholder.unlockcanvasandpost (canvas);
@Override public void surfacedestroyed (Surfaceholder holder) {setstartflags (false); /** * Re-measuring * * @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {Super.onmea
Sure (Widthmeasurespec, heightmeasurespec);
int width = math.min (Getmeasuredwidth (), Getmeasuredheight ());
Setmeasureddimension (width, width);
}
}
above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud-dwelling community.