Android simple disc menu

Source: Internet
Author: User

Today, I accidentally saw a menu in the disc shape, and it was quite interesting to turn it. Then I thought about it and made a simple effect.
The idea is this: Set an origin and a radius, and evenly distribute each menu around the circle. For easy calculation, the coordinates of the menu are expressed in degrees and then converted to polar coordinates.
Set a vertex as the starting point, and determine the degree of increase for each vertex based on the total number of menus. Then, determine the degree of each vertex in sequence, and then determine the coordinates.

Java code

  1. Package chroya. Demo. roundspin;
  2. Import Android. content. context;
  3. Import Android. Graphics. Bitmap;
  4. Import Android. Graphics. bitmapfactory;
  5. Import Android. Graphics. Canvas;
  6. Import Android. Graphics. color;
  7. Import Android. Graphics. paint;
  8. Import Android. util. log;
  9. Import Android. View. motionevent;
  10. Import Android. View. view;
  11. /**
  12. * Disc View
  13. * @ Author chroya
  14. *
  15. */
  16. Public class roundspinview
    Extends view {
  17. Private paint mpaint = new paint ();
  18. // Stone list
  19. Private bigstone [] mstones;
  20. // Number
  21. Private Static
    Final int stone_count =
    6;
  22. // Center Coordinate
  23. Private int mpointx = 0, mpointy = 0;
  24. // Radius
  25. Private int mradius =
    0;
  26. // Angle of interval between two points
  27. Private int mdegreedelta;
  28. Public roundspinview (context,
    Int PX, int py,
    Int radius ){
  29. Super (context );
  30. Mpaint. setcolor (color. Red );
  31. Mpaint. setstrokewidth (2 );
  32. Setbackgroundresource (R. drawable. menubkground );
  33. Mpointx = px;
  34. Mpointy = py;
  35. Mradius = radius;
  36. Setupstones ();
  37. Computecoordinates ();
  38. }
  39. /**
  40. * Initialize each vertex
  41. */
  42. Private void setupstones (){
  43. Mstones = new bigstone [stone_count];
  44. Bigstone stone;
  45. Int angle = 0;
  46. Mdegreedelta = 360/stone_count;
  47. For (INT Index = 0; index <stone_count; index ++ ){
  48. Stone = new bigstone ();
  49. Stone. angle = angle;
  50. Stone. Bitmap = bitmapfactory. decoderesource (getresources (), R. drawable. menu1 + index );
  51. Angle + = mdegreedelta;
  52. Mstones [Index] = stone;
  53. }
  54. }
  55. /**
  56. * Re-calculate the angle of each vertex
  57. */
  58. Private void resetstonesangle (float X,
    Float y ){
  59. Int angle = computecurrentangle (x, y );
  60. Log. D ("roundspinview ",
    "Angle:" + angle );
  61. For (INT Index = 0; index <stone_count; index ++ ){
  62. Mstones [Index]. angle = angle;
  63. Angle + = mdegreedelta;
  64. }
  65. }
  66. /**
  67. * Calculate the coordinates of each vertex.
  68. */
  69. Private void computecoordinates (){
  70. Bigstone stone;
  71. For (INT Index = 0; index <stone_count; index ++ ){
  72. Stone = mstones [Index];
  73. Stone. x = mpointx + (float) (mradius * Math. Cos (stone. Angle * Math. PI/180 ));
  74. Stone. Y = mpointy + (float) (mradius * Math. Sin (stone. Angle * Math. PI/180 ));
  75. }
  76. }
  77. /**
  78. * Calculate the angle of the first vertex.
  79. * @ Param x
  80. * @ Param y
  81. * @ Return
  82. */
  83. Private int computecurrentangle (float X,
    Float y ){
  84. Float distance = (float) math. SQRT (X-mpointx) * (X-mpointx) + (Y-mpointy) * (Y-mpointy )));
  85. Int degree = (INT) (math. ACOs (X-mpointx)/distance) * 180/Math. Pi );
  86. If (Y <mpointy ){
  87. Degree =-degree;
  88. }
  89. Log. D ("roundspinview ",
    "X:" + x + ", Y:" + Y + ", Degree:" + degree );
  90. Return degree;
  91. }
  92. @ Override
  93. Public Boolean dispatchtouchevent (motionevent event ){
  94. Resetstonesangle (event. getx (), event. Gety ());
  95. Computecoordinates ();
  96. Invalidate ();
  97. Return true;
  98. }
  99. @ Override
  100. Public void ondraw (canvas ){
  101. Canvas. drawpoint (mpointx, mpointy, mpaint );
  102. For (INT Index = 0; index <stone_count; index ++ ){
  103. If (! Mstones [Index]. isvisible)
    Continue;
  104. Drawincenter (canvas, mstones [Index]. bitmap, mstones [Index]. X, mstones [Index]. y );
  105. // Skip the following sentence if you do not want a red line
  106. // Canvas. drawline (mpointx, mpointy, mstones [Index]. X, mstones [Index]. Y, mpaint );
  107. }
  108. }
  109. /**
  110. * Place the center point in the center
  111. * @ Param canvas
  112. * @ Param bitmap
  113. * @ Param left
  114. * @ Param top
  115. */
  116. Void drawincenter (canvas, Bitmap bitmap,
    Float left, float top ){
  117. Canvas. drawpoint (left, top, mpaint );
  118. Canvas. drawbitmap (bitmap, left-bitmap.getWidth ()/2, top-bitmap.getHeight ()/2,
    Null );
  119. }
  120. Class bigstone {
  121. // Image
  122. Bitmap bitmap;
  123. // Angle
  124. Int angle;
  125. // X coordinate
  126. Float X;
  127. // Y coordinate
  128. Float y;
  129. // Visible
  130. Boolean isvisible = true;
  131. }
  132. }
Package chroya. demo. roundspin; import android. content. context; import android. graphics. bitmap; import android. graphics. bitmapfactory; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. util. log; import android. view. motionevent; import android. view. view;/*** disc view * @ author chroya **/public class roundspinview extends view {private paint mpaint = New paint (); // stone list private bigstone [] mstones; // Number of Private Static final int stone_count = 6; // center coordinate private int mpointx = 0, mpointy = 0; // radius private int mradius = 0; // The angle between each two points Private int mdegreedelta; Public roundspinview (context, int PX, int py, int radius) {super (context); mpaint. setcolor (color. red); mpaint. setstrokewidth (2); setbackgroundresource (R. drawable. menubkground); mpointx = px; mpointy = PY; mradius = radius; setupstones (); computecoordinates ();}/*** initialize each vertex */private void setupstones () {mstones = new bigstone [stone_count]; bigstone stone; int angle = 0; mdegreedelta = 360/stone_count; For (INT Index = 0; index <stone_count; index ++) {stone = new bigstone (); stone. angle = angle; stone. bitmap = bitmapfactory. decoderesource (getresources (), R. drawable. menu1 + index); angle + = mdegreedelta; mstones [I Ndex] = stone ;}}/*** recalculate the angle of each vertex */private void resetstonesangle (float X, float y) {int angle = computecurrentangle (x, y ); log. D ("roundspinview", "angle:" + angle); For (INT Index = 0; index <stone_count; index ++) {mstones [Index]. angle = angle; angle + = mdegreedelta;}/*** calculate the coordinates of each vertex */private void computecoordinates () {bigstone stone; For (INT Index = 0; index <stone_count; index ++) {stone = mstones [Index]; ston E. X = mpointx + (float) (mradius * Math. cos (stone. angle * Math. PI/180); stone. y = mpointy + (float) (mradius * Math. sin (stone. angle * Math. PI/180);}/*** calculate the angle of the first vertex * @ Param x * @ Param y * @ return */private int computecurrentangle (float X, float y) {float distance = (float) math. SQRT (X-mpointx) * (X-mpointx) + (Y-mpointy) * (Y-mpointy); int degree = (INT) (math. ACOs (X-mpointx)/distance) * 180/math. pi); If (Y <Mpointy) {degree =-degree;} log. D ("roundspinview", "X:" + x + ", Y:" + Y + ", Degree:" + degree); Return degree ;} @ overridepublic Boolean dispatchtouchevent (motionevent event) {resetstonesangle (event. getx (), event. gety (); computecoordinates (); invalidate (); Return true ;}@ overridepublic void ondraw (canvas) {canvas. drawpoint (mpointx, mpointy, mpaint); For (INT Index = 0; index <stone_count; index ++) {If (! Mstones [Index]. isvisible) continue; drawincenter (canvas, mstones [Index]. bitmap, mstones [Index]. x, mstones [Index]. y); // if you do not want to have a red line, delete the following sentence: // canvas. drawline (mpointx, mpointy, mstones [Index]. x, mstones [Index]. y, mpaint) ;}}/*** place the central point to the center * @ Param canvas * @ Param bitmap * @ Param left * @ Param top */void drawincenter (canvas, bitmap bitmap, float left, float top) {canvas. drawpoint (left, top, mpaint); canvas. drawbitmap (bitmap, left-bitmap.getWidth ()/2, top-bitmap.getHeight ()/2, null);} class bigstone {// picture Bitmap bitmap; // angle int angle; // X coordinate float X; // y coordinate float y; // Boolean isvisible = true ;}}

The comments in the Code are also clear. Stone_count indicates the number of menus, which can be set to 1 to 7. A larger number must be supported by images. I only put seven images.

If the touch point is not on the circumference, the intersection of the straight line from the point to the center of the circle is automatically calculated and mapped.

The following figure shows the effect of the five menus:

Effects of the six menus:

OK, and the code is also contributed.

 

Zhuanzi: http://chroya.iteye.com/blog/830682

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.