Android簡單的圓盤形菜單

來源:互聯網
上載者:User

   今天偶然看到一個圓盤形的菜單,還可以轉動,感覺挺有意思,然後想了想,做了個簡單的效果。
      思路是這樣的,定一個原點和一個半徑,圓的四周均勻分布每個菜單。為了方便計算,菜單的座標用度數表示,然後轉化為極座標計算。
      定某個點為起始點,根據總菜單數確定每個點增加的度數,然後依次確定每個點的度數,也就確定了座標。

Java代碼

  1. package chroya.demo.roundspin; 
  2.  
  3. import android.content.Context; 
  4. import android.graphics.Bitmap; 
  5. import android.graphics.BitmapFactory; 
  6. import android.graphics.Canvas; 
  7. import android.graphics.Color; 
  8. import android.graphics.Paint; 
  9. import android.util.Log; 
  10. import android.view.MotionEvent; 
  11. import android.view.View; 
  12.  
  13. /**
  14. * 圓盤式的view
  15. * @author chroya
  16. *
  17. */ 
  18. public class RoundSpinView
    extends View { 
  19.     private Paint mPaint = new Paint(); 
  20.      
  21.     //stone列表 
  22.     private BigStone[] mStones; 
  23.     //數目 
  24.     private static
    final int STONE_COUNT =
    6; 
  25.      
  26.     //圓心座標 
  27.     private int mPointX=0, mPointY=0; 
  28.     //半徑 
  29.     private int mRadius =
    0; 
  30.     //每兩個點間隔的角度 
  31.     private int mDegreeDelta; 
  32.  
  33.     public RoundSpinView(Context context,
    int px, int py,
    int radius) { 
  34.         super(context); 
  35.         mPaint.setColor(Color.RED); 
  36.         mPaint.setStrokeWidth(2); 
  37.         setBackgroundResource(R.drawable.menubkground); 
  38.          
  39.         mPointX = px; 
  40.         mPointY = py; 
  41.         mRadius = radius; 
  42.          
  43.         setupStones(); 
  44.         computeCoordinates(); 
  45.     } 
  46.      
  47.     /**
  48.      * 初始化每個點
  49.      */ 
  50.     private void setupStones() { 
  51.         mStones = new BigStone[STONE_COUNT]; 
  52.         BigStone stone; 
  53.         int angle = 0; 
  54.         mDegreeDelta = 360/STONE_COUNT; 
  55.          
  56.         for(int index=0; index<STONE_COUNT; index++) { 
  57.             stone = new BigStone(); 
  58.             stone.angle = angle; 
  59.             stone.bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.menu1+index);             
  60.             angle += mDegreeDelta; 
  61.              
  62.             mStones[index] = stone; 
  63.         } 
  64.     } 
  65.      
  66.     /**
  67.      * 重新計算每個點的角度
  68.      */ 
  69.     private void resetStonesAngle(float x,
    float y) { 
  70.         int angle = computeCurrentAngle(x, y); 
  71.         Log.d("RoundSpinView",
    "angle:"+angle); 
  72.         for(int index=0; index<STONE_COUNT; index++) {            
  73.             mStones[index].angle = angle;        
  74.             angle += mDegreeDelta; 
  75.         } 
  76.     } 
  77.      
  78.     /**
  79.      * 計算每個點的座標
  80.      */ 
  81.     private void computeCoordinates() { 
  82.         BigStone stone; 
  83.         for(int index=0; index<STONE_COUNT; index++) { 
  84.             stone = mStones[index]; 
  85.             stone.x = mPointX+ (float)(mRadius * Math.cos(stone.angle*Math.PI/180)); 
  86.             stone.y = mPointY+ (float)(mRadius * Math.sin(stone.angle*Math.PI/180)); 
  87.         } 
  88.     } 
  89.      
  90.     /**
  91.      * 計算第一個點的角度
  92.      * @param x
  93.      * @param y
  94.      * @return
  95.      */ 
  96.     private int computeCurrentAngle(float x,
    float y) {      
  97.         float distance = (float)Math.sqrt(((x-mPointX)*(x-mPointX) + (y-mPointY)*(y-mPointY))); 
  98.         int degree = (int)(Math.acos((x-mPointX)/distance)*180/Math.PI); 
  99.         if(y < mPointY) { 
  100.             degree = -degree; 
  101.         } 
  102.          
  103.         Log.d("RoundSpinView",
    "x:"+x+",y:"+y+",degree:"+degree); 
  104.         return degree; 
  105.     } 
  106.      
  107.     @Override 
  108.     public boolean dispatchTouchEvent(MotionEvent event) { 
  109.         resetStonesAngle(event.getX(), event.getY()); 
  110.         computeCoordinates(); 
  111.         invalidate(); 
  112.         return true; 
  113.     } 
  114.      
  115.     @Override 
  116.     public void onDraw(Canvas canvas) { 
  117.         canvas.drawPoint(mPointX, mPointY, mPaint); 
  118.          
  119.         for(int index=0; index<STONE_COUNT; index++) { 
  120.             if(!mStones[index].isVisible)
    continue; 
  121.             drawInCenter(canvas, mStones[index].bitmap, mStones[index].x, mStones[index].y); 
  122.             //不想有紅線,就注掉下面這句 
  123. //          canvas.drawLine(mPointX, mPointY, mStones[index].x, mStones[index].y, mPaint); 
  124.         } 
  125.     } 
  126.      
  127.     /**
  128.      * 把中心點放到中心處
  129.      * @param canvas
  130.      * @param bitmap
  131.      * @param left
  132.      * @param top
  133.      */ 
  134.     void drawInCenter(Canvas canvas, Bitmap bitmap,
    float left, float top) { 
  135.         canvas.drawPoint(left, top, mPaint); 
  136.         canvas.drawBitmap(bitmap, left-bitmap.getWidth()/2, top-bitmap.getHeight()/2,
    null); 
  137.     }    
  138.      
  139.     class BigStone { 
  140.          
  141.         //圖片 
  142.         Bitmap bitmap; 
  143.          
  144.         //角度 
  145.         int angle; 
  146.          
  147.         //x座標 
  148.         float x; 
  149.          
  150.         //y座標 
  151.         float y; 
  152.          
  153.         //是否可見 
  154.         boolean isVisible = true; 
  155.     } 
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;/** * 圓盤式的view * @author chroya * */public class RoundSpinView extends View {private Paint mPaint = new Paint();//stone列表private BigStone[] mStones;//數目private static final int STONE_COUNT = 6;//圓心座標private int mPointX=0, mPointY=0;//半徑private int mRadius = 0;//每兩個點間隔的角度private int mDegreeDelta;public RoundSpinView(Context 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();}/** * 初始化每個點 */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[index] = stone;}}/** * 重新計算每個點的角度 */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;}}/** * 計算每個點的座標 */private void computeCoordinates() {BigStone stone;for(int index=0; index<STONE_COUNT; index++) {stone = mStones[index];stone.x = mPointX+ (float)(mRadius * Math.cos(stone.angle*Math.PI/180));stone.y = mPointY+ (float)(mRadius * Math.sin(stone.angle*Math.PI/180));}}/** * 計算第一個點的角度 * @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) {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);//不想有紅線,就注掉下面這句//canvas.drawLine(mPointX, mPointY, mStones[index].x, mStones[index].y, mPaint);}}/** * 把中心點放到中心處 * @param canvas * @param bitmap * @param left * @param top */void drawInCenter(Canvas 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 {//圖片Bitmap bitmap;//角度int angle;//x座標float x;//y座標float y;//是否可見boolean isVisible = true;}}

       代碼裡注釋也很清楚。STONE_COUNT表示菜單的數目,可以設定為1到7,更大的數字需要圖片支援,我只放了7張圖片。

       如果觸摸的點不在圓周上,會自動計算出點到圓心的直線跟圓的交點,然後映射上去。

       5個菜單的效果,畫了線的:

       6個菜單的效果:

          Ok,代碼也貢獻出來。

 

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.