ArcMenu如何去修改类似小米的系统菜单

在源码中,这段是申请空间大小的,为那些子控件,不然你出现就没有地方显示了.
@Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  final int radius = mRadius = mSetRadius == -1 ? computeRadius(
    Math.abs(mToDegrees - mFromDegrees), getChildCount(),
    mChildSize, mChildPadding, MIN_RADIUS) : mSetRadius;
  final int size = radius * 2 + mChildSize + mChildPadding
    + mLayoutPadding * 2;
  setMeasuredDimension(size, size);
  final int count = getChildCount();
  for (int i = 0; i < count; i++) {
   getChildAt(i)
     .measure(
       MeasureSpec.makeMeasureSpec(mChildSize,
         MeasureSpec.EXACTLY),
       MeasureSpec.makeMeasureSpec(mChildSize,
         MeasureSpec.EXACTLY));
  }
 }
这段代码是当动画后,requestlayout 就触发这个,让子控件显示在真正的位置上.
原来这里 getheight()/2的,我改成了 gethe... ,是为了将控件放在最下面,才能形成
从最下面出来的效果.
@Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  final int centerX = getWidth() / 2;
  final int centerY = getHeight();
  final int radius = mExpanded ? mRadius : 0; // 如果半径为0,回到了中心点.
  final int childCount = getChildCount();
  final float perDegrees = (mToDegrees - mFromDegrees) / (childCount - 1);
  float degrees = mFromDegrees; // 角度.
  for (int i = 0; i < childCount; i++) {
   Rect frame = computeChildFrame(centerX, centerY, radius, degrees,
     mChildSize);
   degrees += perDegrees;
   getChildAt(i).layout(frame.left, frame.top, frame.right,
     frame.bottom);
  }
 }
 @SuppressLint("NewApi")
 private void bindChildAnimation(final View child, final int index,
   final long duration) {
  /**
   * true : 回来. false : 出去.
   */
  final boolean expanded = mExpanded; // 弹出,弹进的动画旋转.
  final int centerX = getWidth() / 2;
  final int centerY = getHeight();
  final int radius = expanded ? 0 : mRadius;
  final int childCount = getChildCount();
  // (360 - 180) / (5 - 1) = 45 度 !! 如果这里是5个的话,还是可以到达中心点的,如果6,7,这里需要改为45.
  final float perDegrees = (mToDegrees - mFromDegrees) / (childCount - 1);
  Rect frame;
  if (!expanded) {
   frame = computeChildFrame(centerX, centerY, radius, mFromDegrees
     + index * perDegrees, mChildSize); // 计算需要移动过去的位置.
  } else {
   frame = computeChildFrame(centerX, centerY, mRadius, mFromDegrees
     + (270 - mFromDegrees), mChildSize); // 计算需要移动过去的位置.
  }
  //
  Rect framedown = computeChildFrame(centerX, centerY, 0, mFromDegrees
    + (270 - mFromDegrees), mChildSize); // 计算需要移动过去的位置.
  //
  final int toXDelta = frame.left - child.getLeft(); // 用准备移动的left -
               // 控件原始的left.
  final int toYDelta = frame.top - child.getTop(); //
  Interpolator interpolator = mExpanded ? new AccelerateInterpolator()
    : new OvershootInterpolator(1.5f); // 加速器.
  final long startOffset = computeStartOffset(childCount, mExpanded,
    index, 0.1f, duration, interpolator); //
    // 旋转动画. createShrinkAnimation 缩回去的动画,反之.
  Animation animation = mExpanded ? createShrinkAnimation(0, toXDelta, 0,
    toYDelta, startOffset, duration + 300, interpolator, framedown)
    : createExpandAnimation(0, toXDelta, 0, toYDelta, startOffset,
      duration, interpolator); // 动画效果.
  if (mExpanded) {
   this.cb.onSwitchGone();
  } else {
   this.cb.onSwitchVisible();
  }
  final boolean isLast = getTransformedIndex(expanded, childCount, index) == childCount - 1;
  animation.setAnimationListener(new AnimationListener() {
   @Override
   public void onAnimationStart(Animation animation) {
   }
   @Override
   public void onAnimationRepeat(Animation animation) {
   }
   @Override
   public void onAnimationEnd(Animation animation) {
    if (isLast) {
     postDelayed(new Runnable() {
      @Override
      public void run() {
       onAllAnimationsEnd();
      }
     }, 0);
    }
   }
  });
  child.setAnimation(animation); // 设置动画.
 }

然后再修改角度. 当外部的 toDegrees, mFromDegrees 进行加减的时候,就开始旋转了.

 public void setArc(float fromDegrees, float toDegrees,
   ArcMenuDegreesCallBack cb) {
  if (mFromDegrees == fromDegrees && mToDegrees == toDegrees) {
   return;
  }
  mFromDegrees = fromDegrees;
  mToDegrees = toDegrees;
  requestLayout(); //
  if (cb != null)
   cb.onLastDegrees();
 }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。