美文网首页
圆形菜单Menu

圆形菜单Menu

作者: 菜鸟何时起飞 | 来源:发表于2020-04-19 19:06 被阅读0次
    image.png image.png
    public class CircleButtonMenu extends ViewGroup
    {
        private static final String TAG = "CircleButtonMenu";
        private int DEFAULT_SIZE = 200;
        private Paint mPaint;
        private int state = STATE_OPEN;
        public static final int STATE_OPEN = 0;
        public static final int STATE_CLOSE = 1;
    
        public CircleButtonMenu(Context context, AttributeSet attrs, int defStyleAttr)
        {
            super(context, attrs, defStyleAttr);
            init(context, attrs, defStyleAttr);
        }
    
        public CircleButtonMenu(Context context, AttributeSet attrs)
        {
            this(context, attrs, 0);
        }
    
        public CircleButtonMenu(Context context)
        {
            this(context, null);
        }
    
        private void init(Context context, AttributeSet attrs, int defStyleAttr)
        {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(Color.BLACK);
            setWillNotDraw(false);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width = measure(widthMeasureSpec);
            int height = measure(widthMeasureSpec);
            int childCount = getChildCount();
            for (int i = 0; i < childCount; i++)
            {
                View childAt = getChildAt(i);
                LayoutParams layoutParams = childAt.getLayoutParams();
                if (i == childCount - 1)
                {
                    layoutParams.width = UnitConversionUtil.Dp2Px(50);
                    layoutParams.height = UnitConversionUtil.Dp2Px(50);
                    childAt.setOnClickListener(listener);
                } else
                {
                    layoutParams.width = UnitConversionUtil.Dp2Px(40);
                    layoutParams.height = UnitConversionUtil.Dp2Px(40);
                }
            }
            int length = Math.min(width, height);
            setMeasuredDimension(length, length);
        }
    
        private int measure(int widthMeasureSpec)
        {
            int mode = MeasureSpec.getMode(widthMeasureSpec);
            int size = MeasureSpec.getSize(widthMeasureSpec);
            switch (mode)
            {
                case MeasureSpec.AT_MOST:
                    return Math.min(size, DEFAULT_SIZE);
                case MeasureSpec.EXACTLY:
                    return size;
                case MeasureSpec.UNSPECIFIED:
                    return DEFAULT_SIZE;
                default:
                    return 0;
            }
        }
    
        private int centerX;
        private int centerY;
        private int max_radius = 0;
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b)
        {
            centerX = (r - l) / 2;
            centerY = (b - t) / 2;
            max_radius = Math.min((r - l) / 2, (b - t) / 2) - 60;
            int childCount = getChildCount();
            for (int i = 0; i < childCount; i++)
            {
                View child = getChildAt(i);
                LayoutParams layoutParams = child.getLayoutParams();
                int childWidth = layoutParams.width;
                int childHeight = layoutParams.height;
                if (i == childCount - 1)
                {
                    child.layout(centerX - childWidth / 2,
                            centerY - childHeight / 2,
                            centerX + childWidth / 2,
                            centerY + childWidth / 2);
                } else
                {
                    child.layout(centerX + (int) (max_radius * Math.cos((Math.PI * 2) / (childCount - 1) * i)) - childWidth / 2,
                            centerY + (int) (max_radius * Math.sin((Math.PI * 2) / (childCount - 1) * i)) - childHeight / 2,
                            centerX + (int) (max_radius * Math.cos((Math.PI * 2) / (childCount - 1) * i)) + childWidth / 2,
                            centerY + (int) (max_radius * Math.sin((Math.PI * 2) / (childCount - 1) * i)) + childWidth / 2);
                }
            }
        }
    
        public void setState(int state)
        {
            this.state = state;
        }
    
        private OnClickListener listener = new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if (state == STATE_CLOSE)
                {
                    ValueAnimator openAnimator = ValueAnimator.ofInt(0, max_radius);
                    openAnimator.setDuration(1000);
                    openAnimator.addListener(new AnimatorListenerAdapter()
                    {
                        @Override
                        public void onAnimationEnd(Animator animation)
                        {
                            super.onAnimationEnd(animation);
                            setState(STATE_OPEN);
                        }
                    });
                    openAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
                    {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation)
                        {
                            int childCount = getChildCount();
                            int radius = (int) animation.getAnimatedValue();
                            for (int i = 0; i < childCount - 1; i++)
                            {
                                View child = getChildAt(i);
                                LayoutParams layoutParams = child.getLayoutParams();
                                int childWidth = layoutParams.width;
                                int childHeight = layoutParams.height;
                                child.setLeft(centerX + (int) (radius * Math.cos((Math.PI * 2) / (childCount - 1) * i)) - childWidth / 2);
                                child.setTop(centerY + (int) (radius * Math.sin((Math.PI * 2) / (childCount - 1) * i)) - childHeight / 2);
                                child.setRight(centerX + (int) (radius * Math.cos((Math.PI * 2) / (childCount - 1) * i)) + childWidth / 2);
                                child.setBottom(centerY + (int) (radius * Math.sin((Math.PI * 2) / (childCount - 1) * i)) + childHeight / 2);
                            }
                        }
                    });
                    openAnimator.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {
                            int childCount = getChildCount();
                            for (int i = 0; i < childCount - 1; i++)
                            {
                                View child = getChildAt(i);
                                child.setVisibility(VISIBLE);
                            }
                        }
    
                        @Override
                        public void onAnimationEnd(Animator animation) {
    
                        }
    
                        @Override
                        public void onAnimationCancel(Animator animation) {
    
                        }
    
                        @Override
                        public void onAnimationRepeat(Animator animation) {
    
                        }
                    });
                    openAnimator.setInterpolator(new TInterpolator());
                    openAnimator.start();
                } else if (state == STATE_OPEN)
                {
                    ValueAnimator closeAnimator = ValueAnimator.ofInt(max_radius, 0);
                    closeAnimator.setDuration(1000);
                    closeAnimator.addListener(new AnimatorListenerAdapter()
                    {
                        @Override
                        public void onAnimationEnd(Animator animation)
                        {
                            super.onAnimationEnd(animation);
                            setState(STATE_CLOSE);
                        }
                    });
                    closeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
                    {
                        @Override
                        public void onAnimationUpdate(ValueAnimator animation)
                        {
                            int childCount = getChildCount();
                            int radius = (int) animation.getAnimatedValue();
                            for (int i = 0; i < childCount - 1; i++)
                            {
                                View child = getChildAt(i);
                                LayoutParams layoutParams = child.getLayoutParams();
                                int childWidth = layoutParams.width;
                                int childHeight = layoutParams.height;
                                child.setLeft(centerX + (int) (radius * Math.cos((Math.PI * 2) / (childCount - 1) * i)) - childWidth / 2);
                                child.setTop(centerY + (int) (radius * Math.sin((Math.PI * 2) / (childCount - 1) * i)) - childHeight / 2);
                                child.setRight(centerX + (int) (radius * Math.cos((Math.PI * 2) / (childCount - 1) * i)) + childWidth / 2);
                                child.setBottom(centerY + (int) (radius * Math.sin((Math.PI * 2) / (childCount - 1) * i)) + childHeight / 2);
                            }
                        }
                    });
                    closeAnimator.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {
    
                        }
    
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            int childCount = getChildCount();
                            for (int i = 0; i < childCount - 1; i++)
                            {
                                View child = getChildAt(i);
                                child.setVisibility(View.GONE);
                            }
                        }
    
                        @Override
                        public void onAnimationCancel(Animator animation) {
    
                        }
    
                        @Override
                        public void onAnimationRepeat(Animator animation) {
    
                        }
                    });
                    closeAnimator.setInterpolator(new TInterpolator());
                    closeAnimator.start();
                }
            }
        };
    }
    
    

    相关文章

      网友评论

          本文标题:圆形菜单Menu

          本文链接:https://www.haomeiwen.com/subject/cpebbhtx.html