Android 实现卫星导航

这里写图片描述

类似这种点击展开的效果

package com.example.arcmenu;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;

public class ArcMenu extends ViewGroup implements OnClickListener {

    public enum Position {
        LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM
    }

    private Position mPosition = Position.RIGHT_BOTTOM;
    private int mRadius;
    private Status mCurrentStatus = Status.CLOSE;

    private String[] tags = { "camera", "music", "sleep", "place", "thought" };
    private View ivButton;

    public enum Status {
        OPEN, CLOSE;
    }

    private onMenuItemListener mMenuItemListener;

    public void setmMenuItemListener(onMenuItemListener mMenuItemListener) {
        this.mMenuItemListener = mMenuItemListener;
    }

    public interface onMenuItemListener {
        void onClick(View view, int pos);
    }

    int mAttr[] = { R.attr.position, R.attr.radius };

    public ArcMenu(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray ta = context.obtainStyledAttributes(attrs, mAttr);
        mRadius = ta.getDimensionPixelSize(1, 0);

        int pos = ta.getInt(0, 3);
        switch (pos) {
        case 0:
            mPosition = Position.LEFT_TOP;
            break;
        case 1:
            mPosition = Position.LEFT_BOTTOM;
            break;
        case 2:
            mPosition = Position.RIGHT_TOP;
            break;
        case 3:
            mPosition = Position.RIGHT_BOTTOM;
            break;
        }
        ta.recycle();
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        if (changed) {
            layoutMainButton();
            layoutItem();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        for (int i = 0; i < getChildCount(); i++) {
            measureChild(getChildAt(0), widthMeasureSpec, heightMeasureSpec);
        }
    }

    private void layoutMainButton() {

        ivButton = getChildAt(0);
        ivButton.setOnClickListener(this);

        int left = 0, top = 0, width = ivButton.getMeasuredWidth(), height = ivButton
                .getMeasuredHeight(), right, bottom;

        switch (mPosition) {

        case LEFT_TOP:
            left = 0;
            top = 0;
            break;
        case LEFT_BOTTOM:
            left = 0;
            top = getMeasuredHeight() - height;
            break;
        case RIGHT_TOP:
            left = getMeasuredWidth() - width;
            top = 0;
            break;
        case RIGHT_BOTTOM:
            left = getMeasuredWidth() - width;
            top = getMeasuredHeight() - height;
            break;
        default:
            break;
        }
        right = left + width;
        bottom = top + height;

        ivButton.layout(left, top, right, bottom);
    }

    private void layoutItem() {

        float angle = 90 * 1f / (tags.length - 1);

        float itemAngle = 0;

        double startX = 0, startY = 0, endX = 0, endY = 0;
        ivButton.measure(0, 0);

        for (int i = 0; i < tags.length; i++) {

            View child = findViewWithTag(tags[i]);
            child.setVisibility(View.GONE);
            child.measure(0, 0);

            switch (mPosition) {

            case LEFT_TOP:
                startX = 0;
                startY = ivButton.getMeasuredHeight() / 2;

                endX = startX + mRadius * Math.cos(Math.toRadians(itemAngle));
                endY = startY + mRadius * Math.sin(Math.toRadians(itemAngle));

                break;
            case LEFT_BOTTOM:
                startX = 0;
                startY = getMeasuredHeight();

                endX = startX + mRadius * Math.cos(Math.toRadians(itemAngle));
                endY = startY - mRadius * Math.sin(Math.toRadians(itemAngle))
                        - child.getMeasuredHeight();

                break;
            case RIGHT_TOP:
                startX = getMeasuredWidth();
                startY = 0;

                endX = startX - mRadius * Math.cos(Math.toRadians(itemAngle))
                        - child.getMeasuredWidth();
                endY = startY + mRadius * Math.sin(Math.toRadians(itemAngle));

                break;
            case RIGHT_BOTTOM:

                startX = getMeasuredWidth();
                startY = getMeasuredHeight();

                endX = startX - mRadius * Math.cos(Math.toRadians(itemAngle))
                        - child.getMeasuredWidth();
                endY = startY - mRadius * Math.sin(Math.toRadians(itemAngle))
                        - child.getMeasuredHeight();

                break;
            default:
                break;
            }

            child.layout((int) endX, (int) endY,
                    (int) (endX + child.getMeasuredWidth()),
                    (int) (endY + child.getMeasuredHeight()));

            itemAngle += angle;
        }

    }

    private void toggleMenu(int duration) {

        float angle = 90 * 1f / (tags.length - 1);

        float itemAngle = 0;

        double startX = 0, startY = 0, endX = 0, endY = 0;



        for (int i = 0; i < tags.length; i++) {

            final View child = findViewWithTag(tags[i]);
            child.measure(0, 0);
            child.setVisibility(View.VISIBLE);

            switch (mPosition) {

            case LEFT_TOP:
                startX = 0;
                startY = 0;

                endX = startX + mRadius * Math.cos(Math.toRadians(itemAngle));
                endY = startY + mRadius * Math.sin(Math.toRadians(itemAngle));

                break;
            case LEFT_BOTTOM:
                startX = 0;
                startY = getMeasuredHeight();

                endX = startX + mRadius * Math.cos(Math.toRadians(itemAngle));
                endY = startY - mRadius * Math.sin(Math.toRadians(itemAngle))
                        - child.getMeasuredHeight();

                break;
            case RIGHT_TOP:

                startX = getMeasuredWidth();
                startY = 0;

                endX = startX - mRadius * Math.cos(Math.toRadians(itemAngle))
                        - child.getMeasuredWidth();
                endY = startY + mRadius * Math.sin(Math.toRadians(itemAngle));

                break;
            case RIGHT_BOTTOM:

                startX = getMeasuredWidth();
                startY = getMeasuredHeight();

                endX = startX - mRadius * Math.cos(Math.toRadians(itemAngle))
                        - child.getMeasuredWidth();
                endY = startY - mRadius * Math.sin(Math.toRadians(itemAngle))
                        - child.getMeasuredHeight();

                break;
            default:
                break;
            }

            itemAngle += angle;

            AnimationSet animSet = new AnimationSet(true);
            animSet.setDuration(duration);
            TranslateAnimation animation = null;
            RotateAnimation rotaAnimation = new RotateAnimation(0, 360,
                    RotateAnimation.RELATIVE_TO_SELF,0.5f,
                    RotateAnimation.RELATIVE_TO_SELF,0.5f);


            if (mCurrentStatus == Status.CLOSE) {
                animation = new TranslateAnimation(
                        (float) (-endX + startX),
                        0,
                        (float) (-endY + startY) - ivButton.getMeasuredHeight(),
                        0);
            } else {
                animation = new TranslateAnimation(0, (float) (-endX + startX),
                        0, (float) (-endY + startY)
                                - ivButton.getMeasuredHeight());

            }

            animSet.addAnimation(rotaAnimation);
            animSet.addAnimation(animation);

            animSet.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                }

                @Override
                public void onAnimationRepeat(Animation animation) {
                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    if (mCurrentStatus == Status.CLOSE) {
                        child.clearAnimation();
                        child.setVisibility(View.GONE);
                    } 
                }
            });
            animSet.setFillAfter(true);
            child.startAnimation(animSet);
        }

        if (mCurrentStatus == Status.CLOSE) {
            mCurrentStatus = Status.OPEN;
        } else {
            mCurrentStatus = Status.CLOSE;
        }

    }

    @Override
    public void onClick(View v) {
        if (ivButton == v) {
            toggleMenu(2000);
        }
    }

}
http://download.csdn.net/detail/luo446718254/9636644
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值