Android to create a smooth nine Sudoku lottery results _android

Source: Internet
Author: User
Tags abs gety

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&&current<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&&current<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.

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.