栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

基于Android实现转盘按钮代码

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

基于Android实现转盘按钮代码

先给大家展示下效果图:

package com.lixu.circlemenu;
 import android.app.Activity;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.TextView;
 import android.widget.Toast;
 import com.lixu.circlemenu.view.CircleImageView;
 import com.lixu.circlemenu.view.CircleLayout;
 import com.lixu.circlemenu.view.CircleLayout.OnItemClickListener;
 import com.lixu.circlemenu.view.CircleLayout.OnItemSelectedListener;
 import com.szugyi.circlemenu.R;
 public class MainActivity extends Activity implements OnItemSelectedListener, OnItemClickListener{
   private  TextView selectedTextView;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     CircleLayout circleMenu = (CircleLayout)findViewById(R.id.main_circle_layout);
     circleMenu.setonItemSelectedListener(this);
     circleMenu.setonItemClickListener(this);
     //这个TextView仅仅作为演示转盘按钮以何为默认的选中项,
     //默认的最底部的那一条被选中,然后显示到该TextView中。
     selectedTextView = (TextView)findViewById(R.id.main_selected_textView);
     selectedTextView.setText(((CircleImageView)circleMenu.getSelectedItem()).getName());
   }
   //圆盘转动到底部,则认为该条目被选中
   @Override
   public void onItemSelected(View view, int position, long id, String name) {    
     selectedTextView.setText(name);
   }
   //选择了转盘中的某一条。
   @Override
   public void onItemClick(View view, int position, long id, String name) {
     Toast.makeText(getApplicationContext(), getResources().getString(R.string.start_app) + " " + name, Toast.LENGTH_SHORT).show();
   }
 }

引用两个开源类:

 package com.lixu.circlemenu.view;
 
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 import com.szugyi.circlemenu.R;
 
 public class CircleImageView extends ImageView {
   private float angle = ;
   private int position = ;
   private String name;
   public float getAngle() {
     return angle;
   }
   public void setAngle(float angle) {
     this.angle = angle;
   }
   public int getPosition() {
     return position;
   }
   public void setPosition(int position) {
     this.position = position;
   }
   public String getName(){
     return name;
   }
   public void setName(String name){
     this.name = name;
   }
   
   public CircleImageView(Context context) {
     this(context, null);
   }
   
   public CircleImageView(Context context, AttributeSet attrs) {
     this(context, attrs, );
   }
   
   public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
     super(context, attrs, defStyle);
     if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs,
    R.styleable.CircleImageView);
name = a.getString(R.styleable.CircleImageView_name);
     }
   }
 }

  package com.lixu.circlemenu.view;
  import com.szugyi.circlemenu.R;
  
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.util.AttributeSet;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 
 public class CircleLayout extends ViewGroup {
   // Event listeners
   private onItemClickListener monItemClickListener = null;
   private onItemSelectedListener monItemSelectedListener = null;
   private onCenterClickListener monCenterClickListener = null;
   // Background image
   private Bitmap imageOriginal, imageScaled;
   private Matrix matrix;
   private int mTappedViewsPostition = -;
   private View mTappedView = null;
   private int selected = ;
   // Child sizes
   private int mMaxChildWidth = ;
   private int mMaxChildHeight = ;
   private int childWidth = ;
   private int childHeight = ;
   // Sizes of the ViewGroup
   private int circleWidth, circleHeight;
   private int radius = ;
   // Touch detection
   private GestureDetector mGestureDetector;
   // needed for detecting the inversed rotations
   private boolean[] quadrantTouched;
   // Settings of the ViewGroup
   private boolean allowRotating = true;
   private float angle = ;
   private float firstChildPos = ;
   private boolean rotateToCenter = true;
   private boolean isRotating = true;
   
   public CircleLayout(Context context) {
     this(context, null);
   }
   
   public CircleLayout(Context context, AttributeSet attrs) {
     this(context, attrs, );
   }
   
   public CircleLayout(Context context, AttributeSet attrs, int defStyle) {
     super(context, attrs, defStyle);
     init(attrs);
   }
   
   protected void init(AttributeSet attrs) {
     mGestureDetector = new GestureDetector(getContext(),
  new MyGestureListener());
     quadrantTouched = new boolean[] { false, false, false, false, false };
     if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs,
    R.styleable.Circle);
// The angle where the first menu item will be drawn
angle = a.getInt(R.styleable.Circle_firstChildPosition, );
firstChildPos = angle;
rotateToCenter = a.getBoolean(R.styleable.Circle_rotateToCenter,
    true);      
isRotating = a.getBoolean(R.styleable.Circle_isRotating, true);
// If the menu is not rotating then it does not have to be centered
// since it cannot be even moved
if (!isRotating) {
  rotateToCenter = false;
}
if (imageOriginal == null) {
  int picId = a.getResourceId(
      R.styleable.Circle_circleBackground, -);
  // If a background image was set as an attribute, 
  // retrieve the image
  if (picId != -) {
    imageOriginal = BitmapFactory.decodeResource(
 getResources(), picId);
  }
}
a.recycle();
// initialize the matrix only once
if (matrix == null) {
  matrix = new Matrix();
} else {
  // not needed, you can also post the matrix immediately to
  // restore the old state
  matrix.reset();
}
// Needed for the ViewGroup to be drawn
setWillNotDraw(false);
     }
   }
   
   public View getSelectedItem() {
     return (selected >= ) ? getChildAt(selected) : null;
   }
   @Override
   protected void onDraw(Canvas canvas) {
     // the sizes of the ViewGroup
     circleHeight = getHeight();
     circleWidth = getWidth();
     if (imageOriginal != null) {
// Scaling the size of the background image
if (imageScaled == null) {
  matrix = new Matrix();
  float sx = (((radius + childWidth / ) * ) / (float) imageOriginal
      .getWidth());
  float sy = (((radius + childWidth / ) * ) / (float) imageOriginal
      .getHeight());
  matrix.postScale(sx, sy);
  imageScaled = Bitmap.createBitmap(imageOriginal, , ,
      imageOriginal.getWidth(), imageOriginal.getHeight(),
      matrix, false);
}
if (imageScaled != null) {
  // Move the background to the center
  int cx = (circleWidth - imageScaled.getWidth()) / ;
  int cy = (circleHeight - imageScaled.getHeight()) / ;
  Canvas g = canvas;
  canvas.rotate(, circleWidth / , circleHeight / );
  g.drawBitmap(imageScaled, cx, cy, null);
}
     }
   }
   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     mMaxChildWidth = ;
     mMaxChildHeight = ;
     // Measure once to find the maximum child size.
     int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
  MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST);
     int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
  MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST);
     final int count = getChildCount();
     for (int i = ; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
  continue;
}
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
mMaxChildWidth = Math.max(mMaxChildWidth, child.getMeasuredWidth());
mMaxChildHeight = Math.max(mMaxChildHeight,
    child.getMeasuredHeight());
     }
     // Measure again for each child to be exactly the same size.
     childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildWidth,
  MeasureSpec.EXACTLY);
     childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildHeight,
  MeasureSpec.EXACTLY);
     for (int i = ; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
  continue;
}
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
     }
     setMeasuredDimension(resolveSize(mMaxChildWidth, widthMeasureSpec),
  resolveSize(mMaxChildHeight, heightMeasureSpec));
   }
   @Override
   protected void onLayout(boolean changed, int l, int t, int r, int b) {
     int layoutWidth = r - l;
     int layoutHeight = b - t;
     // Laying out the child views
     final int childCount = getChildCount();
     int left, top;
     radius = (layoutWidth <= layoutHeight) ? layoutWidth / 
  : layoutHeight / ;
     childWidth = (int) (radius / .);
     childHeight = (int) (radius / .);
     float angleDelay = / getChildCount();
     for (int i = ; i < childCount; i++) {
final CircleImageView child = (CircleImageView) getChildAt(i);
if (child.getVisibility() == GONE) {
  continue;
}
if (angle > ) {
  angle -= ;
} else {
  if (angle < ) {
    angle += ;
  }
}
child.setAngle(angle);
child.setPosition(i);
left = Math
    .round((float) (((layoutWidth / ) - childWidth / ) + radius
 * Math.cos(Math.toRadians(angle))));
top = Math
    .round((float) (((layoutHeight / ) - childHeight / ) + radius
 * Math.sin(Math.toRadians(angle))));
child.layout(left, top, left + childWidth, top + childHeight);
angle += angleDelay;
     }
   }
   
   private void rotateButtons(float degrees) {
     int left, top, childCount = getChildCount();
     float angleDelay = / childCount;
     angle += degrees;
     if (angle > ) {
angle -= ;
     } else {
if (angle < ) {
  angle += ;
}
     }
     for (int i = ; i < childCount; i++) {
if (angle > ) {
  angle -= ;
} else {
  if (angle < ) {
    angle += ;
  }
}
final CircleImageView child = (CircleImageView) getChildAt(i);
if (child.getVisibility() == GONE) {
  continue;
}
left = Math
    .round((float) (((circleWidth / ) - childWidth / ) + radius
 * Math.cos(Math.toRadians(angle))));
top = Math
    .round((float) (((circleHeight / ) - childHeight / ) + radius
 * Math.sin(Math.toRadians(angle))));
child.setAngle(angle);
if (Math.abs(angle - firstChildPos) < (angleDelay / )
    && selected != child.getPosition()) {
  selected = child.getPosition();
  if (monItemSelectedListener != null && rotateToCenter) {
    mOnItemSelectedListener.onItemSelected(child, selected,
 child.getId(), child.getName());
  }
}
child.layout(left, top, left + childWidth, top + childHeight);
angle += angleDelay;
     }
   }
   
   private double getAngle(double xTouch, double yTouch) {
     double x = xTouch - (circleWidth / d);
     double y = circleHeight - yTouch - (circleHeight / d);
     switch (getQuadrant(x, y)) {
     case :
return Math.asin(y / Math.hypot(x, y)) * / Math.PI;
     case :
     case :
return - (Math.asin(y / Math.hypot(x, y)) * / Math.PI);
     case :
return + Math.asin(y / Math.hypot(x, y)) * / Math.PI;
     default:
// ignore, does not happen
return ;
     }
   }
   
   private static int getQuadrant(double x, double y) {
     if (x >= ) {
return y >= ? : ;
     } else {
return y >= ? : ;
     }
   }
   private double startAngle;
   @Override
   public boolean onTouchEvent(MotionEvent event) {
     if (isEnabled()) {
if (isRotating) {
  switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
    // reset the touched quadrants
    for (int i = ; i < quadrantTouched.length; i++) {
      quadrantTouched[i] = false;
    }
    allowRotating = false;
    startAngle = getAngle(event.getX(), event.getY());
    break;
  case MotionEvent.ACTION_MOVE:
    double currentAngle = getAngle(event.getX(), event.getY());
    rotateButtons((float) (startAngle - currentAngle));
    startAngle = currentAngle;
    break;
  case MotionEvent.ACTION_UP:
    allowRotating = true;
    rotateViewToCenter((CircleImageView) getChildAt(selected),
 false);
    break;
  }
}
// set the touched quadrant to true
quadrantTouched[getQuadrant(event.getX() - (circleWidth / ),
    circleHeight - event.getY() - (circleHeight / ))] = true;
mGestureDetector.onTouchEvent(event);
return true;
     }
     return false;
   }
   private class MyGestureListener extends SimpleonGestureListener {
     @Override
     public boolean onFling(MotionEvent e, MotionEvent e, float velocityX,
  float velocityY) {
if (!isRotating) {
  return false;
}
// get the quadrant of the start and the end of the fling
int q = getQuadrant(e.getX() - (circleWidth / ), circleHeight
    - e.getY() - (circleHeight / ));
int q = getQuadrant(e.getX() - (circleWidth / ), circleHeight
    - e.getY() - (circleHeight / ));
// the inversed rotations
if ((q == && q == && Math.abs(velocityX) < Math
    .abs(velocityY))
    || (q == && q == )
    || (q == && q == )
    || (q == && q == && Math.abs(velocityX) > Math
 .abs(velocityY))
    || ((q == && q == ) || (q == && q == ))
    || ((q == && q == ) || (q == && q == ))
    || (q == && q == && quadrantTouched[])
    || (q == && q == && quadrantTouched[])) {
  CircleLayout.this.post(new FlingRunnable(-
      * (velocityX + velocityY)));
} else {
  // the normal rotation
  CircleLayout.this
      .post(new FlingRunnable(velocityX + velocityY));
}
return true;
     }
     @Override
     public boolean onSingleTapUp(MotionEvent e) {
mTappedViewsPostition = pointToPosition(e.getX(), e.getY());
if (mTappedViewsPostition >= ) {
  mTappedView = getChildAt(mTappedViewsPostition);
  mTappedView.setPressed(true);
} else {
  float centerX = circleWidth / ;
  float centerY = circleHeight / ;
  if (e.getX() < centerX + (childWidth / )
      && e.getX() > centerX - childWidth / 
      && e.getY() < centerY + (childHeight / )
      && e.getY() > centerY - (childHeight / )) {
    if (monCenterClickListener != null) {
      mOnCenterClickListener.onCenterClick();
      return true;
    }
  }
}
if (mTappedView != null) {
  CircleImageView view = (CircleImageView) (mTappedView);
  if (selected != mTappedViewsPostition) {
    rotateViewToCenter(view, false);
    if (!rotateToCenter) {
      if (monItemSelectedListener != null) {
 mOnItemSelectedListener.onItemSelected(mTappedView,
     mTappedViewsPostition, mTappedView.getId(), view.getName());
      }
      if (monItemClickListener != null) {
 mOnItemClickListener.onItemClick(mTappedView,
     mTappedViewsPostition, mTappedView.getId(), view.getName());
      }
    }
  } else {
    rotateViewToCenter(view, false);
    if (monItemClickListener != null) {
      mOnItemClickListener.onItemClick(mTappedView,
   mTappedViewsPostition, mTappedView.getId(), view.getName());
    }
  }
  return true;
}
return super.onSingleTapUp(e);
     }
   }
   
   private void rotateViewToCenter(CircleImageView view, boolean fromRunnable) {
     if (rotateToCenter) {
float velocityTemp = ;
float destAngle = (float) (firstChildPos - view.getAngle());
float startAngle = ;
int reverser = ;
if (destAngle < ) {
  destAngle += ;
}
if (destAngle > ) {
  reverser = -;
  destAngle = - destAngle;
}
while (startAngle < destAngle) {
  startAngle += velocityTemp / ;
  velocityTemp *= .F;
}
CircleLayout.this.post(new FlingRunnable(reverser * velocityTemp,
    !fromRunnable));
     }
   }
   
   private class FlingRunnable implements Runnable {
     private float velocity;
     float angleDelay;
     boolean isFirstForwarding = true;
     public FlingRunnable(float velocity) {
this(velocity, true);
     }
     public FlingRunnable(float velocity, boolean isFirst) {
this.velocity = velocity;
this.angleDelay = / getChildCount();
this.isFirstForwarding = isFirst;
     }
     public void run() {
if (Math.abs(velocity) > && allowRotating) {
  if (rotateToCenter) {
    if (!(Math.abs(velocity) < && (Math.abs(angle
 - firstChildPos)
 % angleDelay < ))) {
      rotateButtons(velocity / );
      velocity /= .F;
      CircleLayout.this.post(this);
    }
  } else {
    rotateButtons(velocity / );
    velocity /= .F;
    CircleLayout.this.post(this);
  }
} else {
  if (isFirstForwarding) {
    isFirstForwarding = false;
    CircleLayout.this.rotateViewToCenter(
 (CircleImageView) getChildAt(selected), true);
  }
}
     }
   }
   private int pointToPosition(float x, float y) {
     for (int i = ; i < getChildCount(); i++) {
View item = (View) getChildAt(i);
if (item.getLeft() < x && item.getRight() > x & item.getTop() < y
    && item.getBottom() > y) {
  return i;
}
     }
     return -;
   }
   public void setonItemClickListener(onItemClickListener onItemClickListener) {
     this.monItemClickListener = onItemClickListener;
   }
   public interface onItemClickListener {
     void onItemClick(View view, int position, long id, String name);
   }
   public void setonItemSelectedListener(
onItemSelectedListener onItemSelectedListener) {
     this.monItemSelectedListener = onItemSelectedListener;
   }
   public interface onItemSelectedListener {
     void onItemSelected(View view, int position, long id, String name);
   }
   public interface onCenterClickListener {
     void onCenterClick();
   }
   public void setonCenterClickListener(
onCenterClickListener onCenterClickListener) {
     this.monCenterClickListener = onCenterClickListener;
   }
 }

xml文件:
 
        xmlns:circle="http://schemas.android.com/apk/res/com.szugyi.circlemenu"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:context=".MainActivity" >
                android:id="@+id/main_circle_layout"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:layout_above="@+id/main_selected_textView"
         android:layout_gravity="center_horizontal"
         circle:firstChildPosition="South"
         circle:rotateToCenter="true"
         circle:isRotating="true" >      
 
                      android:id="@+id/main_facebook_image"
             android:layout_width="dp"
             android:layout_height="dp"
             android:src="@drawable/icon_facebook"
             circle:name="@string/facebook" />
                      android:id="@+id/main_myspace_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:src="@drawable/icon_myspace"
             circle:name="@string/myspace" />
                      android:id="@+id/main_google_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:src="@drawable/icon_google"
             circle:name="@string/google" />
                      android:id="@+id/main_linkedin_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:src="@drawable/icon_linkedin"
             circle:name="@string/linkedin" />
                      android:id="@+id/main_twitter_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:src="@drawable/icon_twitter"
             circle:name="@string/twitter" />
                      android:id="@+id/main_wordpress_image"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:src="@drawable/icon_wordpress"
             circle:name="@string/wordpress" />
    
              android:id="@+id/main_selected_textView"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
         android:layout_centerHorizontal="true"
         android:layout_marginBottom="dp"
         android:textAppearance="?android:attr/textAppearanceLarge" />
 

基于Android实现转盘按钮代码的全部内容就到此结束了,希望能够帮助到大家。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/163833.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号