SatelliteMenu实现

直接上图:

SatelliteMenu实现_第1张图片

SatelliteMenu.java
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;

/**
 * Created by Administrator on 2016/5/11.
 */
public class SatelliteMenu extends ViewGroup implements View.OnClickListener {
    /**
     * 卫星式菜单的四个位置
     */
    public static final int LEFT_TOP = 0;
    public static final int LEFT_BOTTOM = 1;
    public static final int RIGHT_TOP = 2;
    public static final int RIGHT_BOTTOM = 3;
    public static final int DEFAULT_RADIUS = 100;

    public float radius;  //菜单的弧形半径
    public Status status = Status.CLOSE; //菜单的开关状态
    public Poisition position = Poisition.LEFT_BOTTOM;
    public OnSatelliteMenuItemClickListener onSateMenuClickListener;  //点击菜单项事件回调的接口

    /**
     * 枚举菜单位置
     */
    public enum Poisition {
        LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM
    }

    /**
     * 枚举菜单状态
     */
    public enum Status {
        OPEN, CLOSE
    }

    public interface OnSatelliteMenuItemClickListener {
        public void onClick(View view);
    }

    /**
     * 主菜单点击事件的重写
     * @param v
     */
    @Override
    public void onClick(View v) {
        RotateButton(v, 0f, 360f, 300);
        toggleMenuButton(300);
    }


    public void setOnSateMenuClickListener(OnSatelliteMenuItemClickListener onSateMenuClickListener) {
        this.onSateMenuClickListener = onSateMenuClickListener;
    }

    public SatelliteMenu(Context context) {
        this(context, null);
    }

    public SatelliteMenu(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SatelliteMenu(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        /**
         * 获取自定义属性
         */
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SatelliteLayout);
        int pos = typedArray.getInt(R.styleable.SatelliteLayout_position, RIGHT_BOTTOM);
        radius = typedArray.getDimension(R.styleable.SatelliteLayout_radius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics()));

        Log.e("radius1", "" + radius);
        typedArray.recycle();


        switch (pos) {
            case LEFT_TOP:
                position = Poisition.LEFT_TOP;
                break;
            case LEFT_BOTTOM:
                position = Poisition.LEFT_BOTTOM;
                break;
            case RIGHT_TOP:
                position = Poisition.RIGHT_TOP;
                break;
            case RIGHT_BOTTOM:
                position = Poisition.RIGHT_BOTTOM;
                break;
        }
    }

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

    }

    /**
     *         确定各个菜单项的位置
     * @param changed
     * @param l
     * @param t
     * @param r
     * @param b
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed) {
            int childCount = getChildCount();
            layoutCenterButton(getChildAt(0), position);
            for (int i = 1; i < childCount; i++) {
                View child = getChildAt(i);
                int childLeft = (int) (radius * Math.sin((i - 1) * Math.PI / 2 / (childCount - 2)));
                int childTop = (int) (radius * Math.cos((i - 1) * Math.PI / 2 / (childCount - 2)));

                if (position == Poisition.LEFT_TOP) {

                } else if (position == Poisition.LEFT_BOTTOM) {

                    childTop = getMeasuredHeight() - childTop - child.getMeasuredHeight();

                } else if (position == Poisition.RIGHT_TOP) {
                    childLeft = getMeasuredWidth() - childLeft - child.getMeasuredWidth();


                } else if (position == Poisition.RIGHT_BOTTOM) {
                    childLeft = getMeasuredWidth() - childLeft - child.getMeasuredWidth();
                    childTop = getMeasuredHeight() - childTop - child.getMeasuredHeight();

                }
                int childRight = childLeft + child.getMeasuredWidth();
                int childBottom = childTop + child.getMeasuredHeight();
                child.layout(childLeft, childTop, childRight, childBottom);
                child.setVisibility(GONE);
            }
        }
    }

    /**
     * 确定主菜单的位置
     * @param centerButton
     * @param position
     */
    public void layoutCenterButton(View centerButton, Poisition position) {
        centerButton.setOnClickListener(this);

        switch (position) {
            case LEFT_TOP:
                centerButton.layout(0, 0, centerButton.getMeasuredWidth(), centerButton.getMeasuredHeight());
                break;
            case LEFT_BOTTOM:
                centerButton.layout(0, getMeasuredHeight() - centerButton.getMeasuredHeight(), centerButton.getMeasuredWidth(), getMeasuredHeight());
                break;
            case RIGHT_TOP:
                centerButton.layout(getMeasuredWidth() - centerButton.getMeasuredWidth(), 0, getMeasuredWidth(), centerButton.getMeasuredHeight());
                break;
            case RIGHT_BOTTOM:
                centerButton.layout(getMeasuredWidth() - centerButton.getMeasuredWidth(), getMeasuredHeight() - centerButton.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
                break;
        }

    }

    /**
     * 点击主菜单时的旋转动画
     * @param v
     * @param start
     * @param end
     * @param during
     */
    private void RotateButton(View v, float start, float end, long during) {
        RotateAnimation rotataAnimation = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotataAnimation.setFillAfter(true);
        rotataAnimation.setDuration(during);
        v.startAnimation(rotataAnimation);
    }

    /**
     * 点击主菜单弹出或收回菜单项
     * @param during
     */
    private void toggleMenuButton( int during) {
        int childCount = getChildCount();
        for (int i = 1; i < childCount; i++) {
            final View child = getChildAt(i);
            child.setVisibility(VISIBLE);
            int childLeft = (int) (radius * Math.sin((i - 1) * Math.PI / 2 / (childCount - 2)));
            int childTop = (int) (radius * Math.cos((i - 1) * Math.PI / 2 / (childCount - 2)));
            int xflag = 1;
            int yflag = 1;
            if (position == Poisition.LEFT_TOP || position == Poisition.RIGHT_TOP) {
                yflag = -1;
            }
            if (position == Poisition.LEFT_TOP || position == Poisition.LEFT_BOTTOM) {
                xflag = -1;
            }
            AnimationSet animationSet = new AnimationSet(true);
            Animation traAnimation = null;
            //to close
            if (status == Status.CLOSE) {
                traAnimation = new TranslateAnimation(xflag * childLeft, 0, yflag * childTop, 0);
                child.setFocusable(true);
                child.setClickable(true);
            }
            //to close
            if (status == Status.OPEN) {
                traAnimation = new TranslateAnimation(0, xflag * childLeft, 0, yflag * childTop);
                child.setFocusable(false);
                child.setClickable(false);
            }

            traAnimation.setDuration(during);
            traAnimation.setFillAfter(true);
            traAnimation.setStartOffset(i * 100/childCount);

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

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    if (status == Status.CLOSE) {
                        child.setVisibility(GONE);
                    }
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            RotateAnimation childRotateAnimation = new RotateAnimation(0, 720,
                    Animation.RELATIVE_TO_SELF, 0.5f,
                    Animation.RELATIVE_TO_SELF, 0.5f);
            childRotateAnimation.setFillAfter(true);
            childRotateAnimation.setDuration(during);
            animationSet.addAnimation(childRotateAnimation);
            animationSet.addAnimation(traAnimation);
            child.startAnimation(animationSet);
            child.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(onSateMenuClickListener!=null){
                        onSateMenuClickListener.onClick(v);
                    }
                    addChildAnimation(300,v);
                    changeStatus();
                }
            });

        }
        changeStatus();

    }

    /**
     * 添加mennuitem的点击动画
     * @param during
     * @param
     */
    public void addChildAnimation(int during ,View view){
        int count=getChildCount();
        for(int i=1;i<count;i++){
            View child=getChildAt(i);
            if(child==view){
                child.startAnimation(scaleBigMenuItem(during));
            }else {
                child.startAnimation(scaleSmallMenuItem(during));
            }
            child.setClickable(false);
            child.setFocusable(false);
        }

    }

    /**
     * 菜单项的缩小动画
     * @param during
     * @return
     */
    public Animation scaleSmallMenuItem(int during){
        AnimationSet animationSet = new AnimationSet(true);
        ScaleAnimation scaleAnimation= new ScaleAnimation(1.0f, 0.0f, 1.0f, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0f);
        animationSet.addAnimation(scaleAnimation);
        animationSet.addAnimation(alphaAnimation);
        animationSet.setDuration(during);
        animationSet.setFillAfter(true);
        return animationSet;
    }

    /**
     * 菜单项的放大动画
     * @param during
     * @return
     */
    public Animation scaleBigMenuItem(int during){
        AnimationSet animationSet = new AnimationSet(true);
        ScaleAnimation scaleAnimation= new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0f);
        animationSet.addAnimation(scaleAnimation);
        animationSet.addAnimation(alphaAnimation);
        animationSet.setDuration(during);
        animationSet.setFillAfter(true);
        return animationSet;

    }

    /**
     * 改变菜单项的展开收缩状态
     */
    public void changeStatus() {
        status = (status == Status.CLOSE ? Status.OPEN : Status.CLOSE);
    }

}



你可能感兴趣的:(ViewGroup)