zoukankan      html  css  js  c++  java
  • 转盘按钮。

     1 package com.lixu.circlemenu;
     2 
     3 
     4 import android.app.Activity;
     5 import android.os.Bundle;
     6 import android.view.View;
     7 import android.widget.TextView;
     8 import android.widget.Toast;
     9 
    10 import com.lixu.circlemenu.view.CircleImageView;
    11 import com.lixu.circlemenu.view.CircleLayout;
    12 import com.lixu.circlemenu.view.CircleLayout.OnItemClickListener;
    13 import com.lixu.circlemenu.view.CircleLayout.OnItemSelectedListener;
    14 import com.szugyi.circlemenu.R;
    15 
    16 public class MainActivity extends Activity implements OnItemSelectedListener, OnItemClickListener{
    17     
    18     private    TextView selectedTextView;
    19     
    20     @Override
    21     protected void onCreate(Bundle savedInstanceState) {
    22         super.onCreate(savedInstanceState);
    23         setContentView(R.layout.activity_main);
    24         
    25         CircleLayout circleMenu = (CircleLayout)findViewById(R.id.main_circle_layout);
    26         circleMenu.setOnItemSelectedListener(this);
    27         circleMenu.setOnItemClickListener(this);
    28 
    29         //这个TextView仅仅作为演示转盘按钮以何为默认的选中项,
    30         //默认的最底部的那一条被选中,然后显示到该TextView中。
    31         selectedTextView = (TextView)findViewById(R.id.main_selected_textView);
    32         selectedTextView.setText(((CircleImageView)circleMenu.getSelectedItem()).getName());
    33     }
    34 
    35     //圆盘转动到底部,则认为该条目被选中
    36     @Override
    37     public void onItemSelected(View view, int position, long id, String name) {        
    38         selectedTextView.setText(name);
    39     }
    40 
    41     //选择了转盘中的某一条。
    42     @Override
    43     public void onItemClick(View view, int position, long id, String name) {
    44         Toast.makeText(getApplicationContext(), getResources().getString(R.string.start_app) + " " + name, Toast.LENGTH_SHORT).show();
    45     }
    46 }

    引用两个开源类:

     1 package com.lixu.circlemenu.view;
     2 
     3 /*
     4  * Copyright 2013 Csaba Szugyiczki
     5  *
     6  * Licensed under the Apache License, Version 2.0 (the "License");
     7  * you may not use this file except in compliance with the License.
     8  * You may obtain a copy of the License at
     9  *
    10  *      http://www.apache.org/licenses/LICENSE-2.0
    11  *
    12  * Unless required by applicable law or agreed to in writing, software
    13  * distributed under the License is distributed on an "AS IS" BASIS,
    14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  * See the License for the specific language governing permissions and
    16  * limitations under the License.
    17  */
    18 
    19 import android.content.Context;
    20 import android.content.res.TypedArray;
    21 import android.util.AttributeSet;
    22 import android.widget.ImageView;
    23 
    24 import com.szugyi.circlemenu.R;
    25 
    26 /**
    27  * 
    28  * @author Szugyi
    29  * Custom ImageView for the CircleLayout class.
    30  * Makes it possible for the image to have an angle, position and a name.
    31  * Angle is used for the positioning in the circle menu.
    32  */
    33 public class CircleImageView extends ImageView {
    34 
    35     private float angle = 0;
    36     private int position = 0;
    37     private String name;
    38 
    39     public float getAngle() {
    40         return angle;
    41     }
    42 
    43     public void setAngle(float angle) {
    44         this.angle = angle;
    45     }
    46 
    47     public int getPosition() {
    48         return position;
    49     }
    50 
    51     public void setPosition(int position) {
    52         this.position = position;
    53     }
    54     
    55     public String getName(){
    56         return name;
    57     }
    58     
    59     public void setName(String name){
    60         this.name = name;
    61     }
    62 
    63     /**
    64      * @param context
    65      */
    66     public CircleImageView(Context context) {
    67         this(context, null);
    68     }
    69 
    70     /**
    71      * @param context
    72      * @param attrs
    73      */
    74     public CircleImageView(Context context, AttributeSet attrs) {
    75         this(context, attrs, 0);
    76     }
    77 
    78     /**
    79      * @param context
    80      * @param attrs
    81      * @param defStyle
    82      */
    83     public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
    84         super(context, attrs, defStyle);
    85         if (attrs != null) {
    86             TypedArray a = getContext().obtainStyledAttributes(attrs,
    87                     R.styleable.CircleImageView);
    88             
    89             name = a.getString(R.styleable.CircleImageView_name);
    90         }
    91     }
    92 
    93 }
      1 package com.lixu.circlemenu.view;
      2 
      3 import com.szugyi.circlemenu.R;
      4 
      5 /*
      6  * Copyright 2013 Csaba Szugyiczki
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  */
     20 
     21 import android.content.Context;
     22 import android.content.res.TypedArray;
     23 import android.graphics.Bitmap;
     24 import android.graphics.BitmapFactory;
     25 import android.graphics.Canvas;
     26 import android.graphics.Matrix;
     27 import android.util.AttributeSet;
     28 import android.view.GestureDetector;
     29 import android.view.GestureDetector.SimpleOnGestureListener;
     30 import android.view.MotionEvent;
     31 import android.view.View;
     32 import android.view.ViewGroup;
     33 
     34 
     35 /**
     36  * 
     37  * @author Szugyi
     38  * Creates a rotatable circle menu which can be parameterized by custom attributes.
     39  * Handles touches and gestures to make the menu rotatable, and to make the 
     40  * menu items selectable and clickable.
     41  * 
     42  */
     43 public class CircleLayout extends ViewGroup {
     44     // Event listeners
     45     private OnItemClickListener mOnItemClickListener = null;
     46     private OnItemSelectedListener mOnItemSelectedListener = null;
     47     private OnCenterClickListener mOnCenterClickListener = null;
     48     
     49     // Background image
     50     private Bitmap imageOriginal, imageScaled;
     51     private Matrix matrix;
     52 
     53     private int mTappedViewsPostition = -1;
     54     private View mTappedView = null;
     55     private int selected = 0;
     56 
     57     // Child sizes
     58     private int mMaxChildWidth = 0;
     59     private int mMaxChildHeight = 0;
     60     private int childWidth = 0;
     61     private int childHeight = 0;
     62 
     63     // Sizes of the ViewGroup
     64     private int circleWidth, circleHeight;
     65     private int radius = 0;
     66 
     67     // Touch detection
     68     private GestureDetector mGestureDetector;
     69     // needed for detecting the inversed rotations
     70     private boolean[] quadrantTouched;
     71 
     72     // Settings of the ViewGroup
     73     private boolean allowRotating = true;
     74     private float angle = 90;
     75     private float firstChildPos = 90;
     76     private boolean rotateToCenter = true;
     77     private boolean isRotating = true;
     78 
     79     /**
     80      * @param context
     81      */
     82     public CircleLayout(Context context) {
     83         this(context, null);
     84     }
     85 
     86     /**
     87      * @param context
     88      * @param attrs
     89      */
     90     public CircleLayout(Context context, AttributeSet attrs) {
     91         this(context, attrs, 0);
     92     }
     93     
     94     /**
     95      * @param context
     96      * @param attrs
     97      * @param defStyle
     98      */
     99     public CircleLayout(Context context, AttributeSet attrs, int defStyle) {
    100         super(context, attrs, defStyle);
    101         init(attrs);
    102     }
    103 
    104     /**
    105      * Initializes the ViewGroup and modifies it's default behavior by the passed attributes
    106      * @param attrs    the attributes used to modify default settings
    107      */
    108     protected void init(AttributeSet attrs) {
    109         mGestureDetector = new GestureDetector(getContext(),
    110                 new MyGestureListener());
    111         quadrantTouched = new boolean[] { false, false, false, false, false };
    112 
    113         if (attrs != null) {
    114             TypedArray a = getContext().obtainStyledAttributes(attrs,
    115                     R.styleable.Circle);
    116             
    117             // The angle where the first menu item will be drawn
    118             angle = a.getInt(R.styleable.Circle_firstChildPosition, 90);
    119             firstChildPos = angle;
    120 
    121             rotateToCenter = a.getBoolean(R.styleable.Circle_rotateToCenter,
    122                     true);            
    123             isRotating = a.getBoolean(R.styleable.Circle_isRotating, true);
    124             
    125             // If the menu is not rotating then it does not have to be centered
    126             // since it cannot be even moved
    127             if (!isRotating) {
    128                 rotateToCenter = false;
    129             }
    130 
    131             if (imageOriginal == null) {
    132                 int picId = a.getResourceId(
    133                         R.styleable.Circle_circleBackground, -1);
    134                 
    135                 // If a background image was set as an attribute, 
    136                 // retrieve the image
    137                 if (picId != -1) {
    138                     imageOriginal = BitmapFactory.decodeResource(
    139                             getResources(), picId);
    140                 }
    141             }
    142 
    143             a.recycle();
    144 
    145             // initialize the matrix only once
    146             if (matrix == null) {
    147                 matrix = new Matrix();
    148             } else {
    149                 // not needed, you can also post the matrix immediately to
    150                 // restore the old state
    151                 matrix.reset();
    152             }
    153             // Needed for the ViewGroup to be drawn
    154             setWillNotDraw(false);
    155         }
    156     }
    157 
    158     /**
    159      * Returns the currently selected menu
    160      * @return the view which is currently the closest to the start position
    161      */
    162     public View getSelectedItem() {
    163         return (selected >= 0) ? getChildAt(selected) : null;
    164     }
    165 
    166     @Override
    167     protected void onDraw(Canvas canvas) {
    168         // the sizes of the ViewGroup
    169         circleHeight = getHeight();
    170         circleWidth = getWidth();
    171 
    172         if (imageOriginal != null) {
    173             // Scaling the size of the background image
    174             if (imageScaled == null) {
    175                 matrix = new Matrix();
    176                 float sx = (((radius + childWidth / 4) * 2) / (float) imageOriginal
    177                         .getWidth());
    178                 float sy = (((radius + childWidth / 4) * 2) / (float) imageOriginal
    179                         .getHeight());
    180                 matrix.postScale(sx, sy);
    181                 imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0,
    182                         imageOriginal.getWidth(), imageOriginal.getHeight(),
    183                         matrix, false);
    184             }
    185 
    186             if (imageScaled != null) {
    187                 // Move the background to the center
    188                 int cx = (circleWidth - imageScaled.getWidth()) / 2;
    189                 int cy = (circleHeight - imageScaled.getHeight()) / 2;
    190 
    191                 Canvas g = canvas;
    192                 canvas.rotate(0, circleWidth / 2, circleHeight / 2);
    193                 g.drawBitmap(imageScaled, cx, cy, null);
    194 
    195             }
    196         }
    197     }
    198 
    199     @Override
    200     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    201         mMaxChildWidth = 0;
    202         mMaxChildHeight = 0;
    203 
    204         // Measure once to find the maximum child size.
    205         int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
    206                 MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST);
    207         int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
    208                 MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST);
    209 
    210         final int count = getChildCount();
    211         for (int i = 0; i < count; i++) {
    212             final View child = getChildAt(i);
    213             if (child.getVisibility() == GONE) {
    214                 continue;
    215             }
    216 
    217             child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    218 
    219             mMaxChildWidth = Math.max(mMaxChildWidth, child.getMeasuredWidth());
    220             mMaxChildHeight = Math.max(mMaxChildHeight,
    221                     child.getMeasuredHeight());
    222         }
    223 
    224         // Measure again for each child to be exactly the same size.
    225         childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildWidth,
    226                 MeasureSpec.EXACTLY);
    227         childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildHeight,
    228                 MeasureSpec.EXACTLY);
    229 
    230         for (int i = 0; i < count; i++) {
    231             final View child = getChildAt(i);
    232             if (child.getVisibility() == GONE) {
    233                 continue;
    234             }
    235 
    236             child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    237         }
    238 
    239         setMeasuredDimension(resolveSize(mMaxChildWidth, widthMeasureSpec),
    240                 resolveSize(mMaxChildHeight, heightMeasureSpec));
    241     }
    242 
    243     @Override
    244     protected void onLayout(boolean changed, int l, int t, int r, int b) {
    245         int layoutWidth = r - l;
    246         int layoutHeight = b - t;
    247 
    248         // Laying out the child views
    249         final int childCount = getChildCount();
    250         int left, top;
    251         radius = (layoutWidth <= layoutHeight) ? layoutWidth / 3
    252                 : layoutHeight / 3;
    253         
    254         childWidth = (int) (radius / 1.5);
    255         childHeight = (int) (radius / 1.5);
    256         
    257         float angleDelay = 360 / getChildCount();
    258         
    259         for (int i = 0; i < childCount; i++) {
    260             final CircleImageView child = (CircleImageView) getChildAt(i);
    261             if (child.getVisibility() == GONE) {
    262                 continue;
    263             }
    264 
    265             if (angle > 360) {
    266                 angle -= 360;
    267             } else {
    268                 if (angle < 0) {
    269                     angle += 360;
    270                 }
    271             }
    272 
    273             child.setAngle(angle);
    274             child.setPosition(i);
    275 
    276             left = Math
    277                     .round((float) (((layoutWidth / 2) - childWidth / 2) + radius
    278                             * Math.cos(Math.toRadians(angle))));
    279             top = Math
    280                     .round((float) (((layoutHeight / 2) - childHeight / 2) + radius
    281                             * Math.sin(Math.toRadians(angle))));
    282 
    283             child.layout(left, top, left + childWidth, top + childHeight);
    284             angle += angleDelay;
    285         }
    286     }
    287 
    288     /**
    289      * Rotate the buttons.
    290      * 
    291      * @param degrees The degrees, the menu items should get rotated.
    292      */
    293     private void rotateButtons(float degrees) {
    294         int left, top, childCount = getChildCount();
    295         float angleDelay = 360 / childCount;
    296         angle += degrees;
    297         
    298         if (angle > 360) {
    299             angle -= 360;
    300         } else {
    301             if (angle < 0) {
    302                 angle += 360;
    303             }
    304         }
    305 
    306         for (int i = 0; i < childCount; i++) {
    307             if (angle > 360) {
    308                 angle -= 360;
    309             } else {
    310                 if (angle < 0) {
    311                     angle += 360;
    312                 }
    313             }
    314 
    315             final CircleImageView child = (CircleImageView) getChildAt(i);
    316             if (child.getVisibility() == GONE) {
    317                 continue;
    318             }
    319             left = Math
    320                     .round((float) (((circleWidth / 2) - childWidth / 2) + radius
    321                             * Math.cos(Math.toRadians(angle))));
    322             top = Math
    323                     .round((float) (((circleHeight / 2) - childHeight / 2) + radius
    324                             * Math.sin(Math.toRadians(angle))));
    325 
    326             child.setAngle(angle);
    327 
    328             if (Math.abs(angle - firstChildPos) < (angleDelay / 2)
    329                     && selected != child.getPosition()) {
    330                 selected = child.getPosition();
    331 
    332                 if (mOnItemSelectedListener != null && rotateToCenter) {
    333                     mOnItemSelectedListener.onItemSelected(child, selected,
    334                             child.getId(), child.getName());
    335                 }
    336             }
    337 
    338             child.layout(left, top, left + childWidth, top + childHeight);
    339             angle += angleDelay;
    340         }
    341     }
    342 
    343     /**
    344      * @return The angle of the unit circle with the image view's center
    345      */
    346     private double getAngle(double xTouch, double yTouch) {
    347         double x = xTouch - (circleWidth / 2d);
    348         double y = circleHeight - yTouch - (circleHeight / 2d);
    349 
    350         switch (getQuadrant(x, y)) {
    351         case 1:
    352             return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
    353 
    354         case 2:
    355         case 3:
    356             return 180 - (Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);
    357 
    358         case 4:
    359             return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
    360 
    361         default:
    362             // ignore, does not happen
    363             return 0;
    364         }
    365     }
    366 
    367     /**
    368      * @return The selected quadrant.
    369      */
    370     private static int getQuadrant(double x, double y) {
    371         if (x >= 0) {
    372             return y >= 0 ? 1 : 4;
    373         } else {
    374             return y >= 0 ? 2 : 3;
    375         }
    376     }
    377 
    378     private double startAngle;
    379 
    380     @Override
    381     public boolean onTouchEvent(MotionEvent event) {
    382         if (isEnabled()) {
    383             if (isRotating) {
    384                 switch (event.getAction()) {
    385                 case MotionEvent.ACTION_DOWN:
    386 
    387                     // reset the touched quadrants
    388                     for (int i = 0; i < quadrantTouched.length; i++) {
    389                         quadrantTouched[i] = false;
    390                     }
    391 
    392                     allowRotating = false;
    393 
    394                     startAngle = getAngle(event.getX(), event.getY());
    395                     break;
    396                 case MotionEvent.ACTION_MOVE:
    397                     double currentAngle = getAngle(event.getX(), event.getY());
    398                     rotateButtons((float) (startAngle - currentAngle));
    399                     startAngle = currentAngle;
    400                     break;
    401                 case MotionEvent.ACTION_UP:
    402                     allowRotating = true;
    403                     rotateViewToCenter((CircleImageView) getChildAt(selected),
    404                             false);
    405                     break;
    406                 }
    407             }
    408 
    409             // set the touched quadrant to true
    410             quadrantTouched[getQuadrant(event.getX() - (circleWidth / 2),
    411                     circleHeight - event.getY() - (circleHeight / 2))] = true;
    412             mGestureDetector.onTouchEvent(event);
    413             return true;
    414         }
    415         return false;
    416     }
    417 
    418     private class MyGestureListener extends SimpleOnGestureListener {
    419         @Override
    420         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
    421                 float velocityY) {
    422             if (!isRotating) {
    423                 return false;
    424             }
    425             // get the quadrant of the start and the end of the fling
    426             int q1 = getQuadrant(e1.getX() - (circleWidth / 2), circleHeight
    427                     - e1.getY() - (circleHeight / 2));
    428             int q2 = getQuadrant(e2.getX() - (circleWidth / 2), circleHeight
    429                     - e2.getY() - (circleHeight / 2));
    430 
    431             // the inversed rotations
    432             if ((q1 == 2 && q2 == 2 && Math.abs(velocityX) < Math
    433                     .abs(velocityY))
    434                     || (q1 == 3 && q2 == 3)
    435                     || (q1 == 1 && q2 == 3)
    436                     || (q1 == 4 && q2 == 4 && Math.abs(velocityX) > Math
    437                             .abs(velocityY))
    438                     || ((q1 == 2 && q2 == 3) || (q1 == 3 && q2 == 2))
    439                     || ((q1 == 3 && q2 == 4) || (q1 == 4 && q2 == 3))
    440                     || (q1 == 2 && q2 == 4 && quadrantTouched[3])
    441                     || (q1 == 4 && q2 == 2 && quadrantTouched[3])) {
    442 
    443                 CircleLayout.this.post(new FlingRunnable(-1
    444                         * (velocityX + velocityY)));
    445             } else {
    446                 // the normal rotation
    447                 CircleLayout.this
    448                         .post(new FlingRunnable(velocityX + velocityY));
    449             }
    450 
    451             return true;
    452 
    453         }
    454 
    455         @Override
    456         public boolean onSingleTapUp(MotionEvent e) {
    457             mTappedViewsPostition = pointToPosition(e.getX(), e.getY());
    458             if (mTappedViewsPostition >= 0) {
    459                 mTappedView = getChildAt(mTappedViewsPostition);
    460                 mTappedView.setPressed(true);
    461             } else {
    462                 float centerX = circleWidth / 2;
    463                 float centerY = circleHeight / 2;
    464 
    465                 if (e.getX() < centerX + (childWidth / 2)
    466                         && e.getX() > centerX - childWidth / 2
    467                         && e.getY() < centerY + (childHeight / 2)
    468                         && e.getY() > centerY - (childHeight / 2)) {
    469                     if (mOnCenterClickListener != null) {
    470                         mOnCenterClickListener.onCenterClick();
    471                         return true;
    472                     }
    473                 }
    474             }
    475 
    476             if (mTappedView != null) {
    477                 CircleImageView view = (CircleImageView) (mTappedView);
    478                 if (selected != mTappedViewsPostition) {
    479                     rotateViewToCenter(view, false);
    480                     if (!rotateToCenter) {
    481                         if (mOnItemSelectedListener != null) {
    482                             mOnItemSelectedListener.onItemSelected(mTappedView,
    483                                     mTappedViewsPostition, mTappedView.getId(), view.getName());
    484                         }
    485 
    486                         if (mOnItemClickListener != null) {
    487                             mOnItemClickListener.onItemClick(mTappedView,
    488                                     mTappedViewsPostition, mTappedView.getId(), view.getName());
    489                         }
    490                     }
    491                 } else {
    492                     rotateViewToCenter(view, false);
    493 
    494                     if (mOnItemClickListener != null) {
    495                         mOnItemClickListener.onItemClick(mTappedView,
    496                                 mTappedViewsPostition, mTappedView.getId(), view.getName());
    497                     }
    498                 }
    499                 return true;
    500             }
    501             return super.onSingleTapUp(e);
    502         }
    503     }
    504 
    505     /**
    506      * Rotates the given view to the center of the menu.
    507      * @param view            the view to be rotated to the center
    508      * @param fromRunnable    if the method is called from the runnable which animates the rotation
    509      *                         then it should be true, otherwise false 
    510      */
    511     private void rotateViewToCenter(CircleImageView view, boolean fromRunnable) {
    512         if (rotateToCenter) {
    513             float velocityTemp = 1;
    514             float destAngle = (float) (firstChildPos - view.getAngle());
    515             float startAngle = 0;
    516             int reverser = 1;
    517 
    518             if (destAngle < 0) {
    519                 destAngle += 360;
    520             }
    521 
    522             if (destAngle > 180) {
    523                 reverser = -1;
    524                 destAngle = 360 - destAngle;
    525             }
    526 
    527             while (startAngle < destAngle) {
    528                 startAngle += velocityTemp / 75;
    529                 velocityTemp *= 1.0666F;
    530             }
    531 
    532             CircleLayout.this.post(new FlingRunnable(reverser * velocityTemp,
    533                     !fromRunnable));
    534         }
    535     }
    536 
    537     /**
    538      * A {@link Runnable} for animating the menu rotation.
    539      */
    540     private class FlingRunnable implements Runnable {
    541 
    542         private float velocity;
    543         float angleDelay;
    544         boolean isFirstForwarding = true;
    545 
    546         public FlingRunnable(float velocity) {
    547             this(velocity, true);
    548         }
    549 
    550         public FlingRunnable(float velocity, boolean isFirst) {
    551             this.velocity = velocity;
    552             this.angleDelay = 360 / getChildCount();
    553             this.isFirstForwarding = isFirst;
    554         }
    555 
    556         public void run() {
    557             if (Math.abs(velocity) > 5 && allowRotating) {
    558                 if (rotateToCenter) {
    559                     if (!(Math.abs(velocity) < 200 && (Math.abs(angle
    560                             - firstChildPos)
    561                             % angleDelay < 2))) {
    562                         rotateButtons(velocity / 75);
    563                         velocity /= 1.0666F;
    564 
    565                         CircleLayout.this.post(this);
    566                     }
    567                 } else {
    568                     rotateButtons(velocity / 75);
    569                     velocity /= 1.0666F;
    570 
    571                     CircleLayout.this.post(this);
    572                 }
    573             } else {
    574                 if (isFirstForwarding) {
    575                     isFirstForwarding = false;
    576                     CircleLayout.this.rotateViewToCenter(
    577                             (CircleImageView) getChildAt(selected), true);
    578                 }
    579             }
    580         }
    581     }
    582 
    583     private int pointToPosition(float x, float y) {
    584 
    585         for (int i = 0; i < getChildCount(); i++) {
    586 
    587             View item = (View) getChildAt(i);
    588             if (item.getLeft() < x && item.getRight() > x & item.getTop() < y
    589                     && item.getBottom() > y) {
    590                 return i;
    591             }
    592 
    593         }
    594         return -1;
    595     }
    596 
    597     public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
    598         this.mOnItemClickListener = onItemClickListener;
    599     }
    600 
    601     public interface OnItemClickListener {
    602         void onItemClick(View view, int position, long id, String name);
    603     }
    604 
    605     public void setOnItemSelectedListener(
    606             OnItemSelectedListener onItemSelectedListener) {
    607         this.mOnItemSelectedListener = onItemSelectedListener;
    608     }
    609 
    610     public interface OnItemSelectedListener {
    611         void onItemSelected(View view, int position, long id, String name);
    612     }
    613 
    614     public interface OnCenterClickListener {
    615         void onCenterClick();
    616     }
    617 
    618     public void setOnCenterClickListener(
    619             OnCenterClickListener onCenterClickListener) {
    620         this.mOnCenterClickListener = onCenterClickListener;
    621     }
    622 }

    xml文件:

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:circle="http://schemas.android.com/apk/res/com.szugyi.circlemenu"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent"
     6     tools:context=".MainActivity" >
     7 
     8     <com.lixu.circlemenu.view.CircleLayout
     9         android:id="@+id/main_circle_layout"
    10         android:layout_width="fill_parent"
    11         android:layout_height="fill_parent"
    12         android:layout_above="@+id/main_selected_textView"
    13         android:layout_gravity="center_horizontal"
    14         circle:firstChildPosition="South" 
    15         circle:rotateToCenter="true" 
    16         circle:isRotating="true" >       
    17 <!--         circle:circleBackground="@drawable/green"  > -->
    18 
    19 
    20         <com.lixu.circlemenu.view.CircleImageView
    21             android:id="@+id/main_facebook_image"
    22             android:layout_width="35dp"
    23             android:layout_height="35dp"
    24             android:src="@drawable/icon_facebook"
    25             circle:name="@string/facebook" />
    26 
    27         <com.lixu.circlemenu.view.CircleImageView
    28             android:id="@+id/main_myspace_image"
    29             android:layout_width="wrap_content"
    30             android:layout_height="wrap_content"
    31             android:src="@drawable/icon_myspace"
    32             circle:name="@string/myspace" />
    33 
    34         <com.lixu.circlemenu.view.CircleImageView
    35             android:id="@+id/main_google_image"
    36             android:layout_width="wrap_content"
    37             android:layout_height="wrap_content"
    38             android:src="@drawable/icon_google"
    39             circle:name="@string/google" />
    40 
    41         <com.lixu.circlemenu.view.CircleImageView
    42             android:id="@+id/main_linkedin_image"
    43             android:layout_width="wrap_content"
    44             android:layout_height="wrap_content"
    45             android:src="@drawable/icon_linkedin"
    46             circle:name="@string/linkedin" />
    47 
    48         <com.lixu.circlemenu.view.CircleImageView
    49             android:id="@+id/main_twitter_image"
    50             android:layout_width="wrap_content"
    51             android:layout_height="wrap_content"
    52             android:src="@drawable/icon_twitter"
    53             circle:name="@string/twitter" />
    54 
    55         <com.lixu.circlemenu.view.CircleImageView
    56             android:id="@+id/main_wordpress_image"
    57             android:layout_width="wrap_content"
    58             android:layout_height="wrap_content"
    59             android:src="@drawable/icon_wordpress"
    60             circle:name="@string/wordpress" />
    61     </com.lixu.circlemenu.view.CircleLayout>
    62 
    63     <TextView
    64         android:id="@+id/main_selected_textView"
    65         android:layout_width="wrap_content"
    66         android:layout_height="wrap_content"
    67         android:layout_alignParentBottom="true"
    68         android:layout_centerHorizontal="true"
    69         android:layout_marginBottom="50dp"
    70         android:textAppearance="?android:attr/textAppearanceLarge" />
    71 
    72 </RelativeLayout>

     运行效果:

  • 相关阅读:
    Hpuoj1039--【C语言训练】角谷猜想
    hpuoj--1093: 回文数(一)
    Zoj1628--Diamond(Dfs《暴力》)
    Poj1995--Raising Modulo Numbers(快速幂)
    杭电5137--How Many Maos Does the Guanxi Worth(Spfa+暴力枚举)
    杭电1166--敌兵布阵(线段树 | 树状数组)

    南阳5--Binary String Matching(Kmp)
    CGAL
    vs c++默认路径
  • 原文地址:https://www.cnblogs.com/labixiaoxin/p/5046614.html
Copyright © 2011-2022 走看看