美文网首页
圆形菜单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