package com.marshalchen.common.uimodule.arcmenu; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; 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.DecelerateInterpolator; import android.view.animation.RotateAnimation; import android.view.animation.ScaleAnimation; import android.view.animation.Animation.AnimationListener; import android.widget.ImageView; import android.widget.RelativeLayout; import com.marshalchen.common.uimodule.R; public class RayMenu extends RelativeLayout { private RayLayout mRayLayout; private ImageView mHintView; public RayMenu(Context context) { super(context); init(context); } public RayMenu(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context) { setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); setClipChildren(false); LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); li.inflate(R.layout.arc_menu_ray_menu, this); mRayLayout = (RayLayout) findViewById(R.id.item_layout); final ViewGroup controlLayout = (ViewGroup) findViewById(R.id.control_layout); controlLayout.setClickable(true); controlLayout.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mHintView.startAnimation(createHintSwitchAnimation(mRayLayout.isExpanded())); mRayLayout.switchState(true); } return false; } }); mHintView = (ImageView) findViewById(R.id.control_hint); } public void addItem(View item, OnClickListener listener) { mRayLayout.addView(item); item.setOnClickListener(getItemClickListener(listener)); } private OnClickListener getItemClickListener(final OnClickListener listener) { return new OnClickListener() { @Override public void onClick(final View viewClicked) { Animation animation = bindItemAnimation(viewClicked, true, 400); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { postDelayed(new Runnable() { @Override public void run() { itemDidDisappear(); } }, 0); } }); final int itemCount = mRayLayout.getChildCount(); for (int i = 0; i < itemCount; i++) { View item = mRayLayout.getChildAt(i); if (viewClicked != item) { bindItemAnimation(item, false, 300); } } mRayLayout.invalidate(); mHintView.startAnimation(createHintSwitchAnimation(true)); if (listener != null) { listener.onClick(viewClicked); } } }; } private Animation bindItemAnimation(final View child, final boolean isClicked, final long duration) { Animation animation = createItemDisapperAnimation(duration, isClicked); child.setAnimation(animation); return animation; } private void itemDidDisappear() { final int itemCount = mRayLayout.getChildCount(); for (int i = 0; i < itemCount; i++) { View item = mRayLayout.getChildAt(i); item.clearAnimation(); } mRayLayout.switchState(false); } private static Animation createItemDisapperAnimation(final long duration, final boolean isClicked) { AnimationSet animationSet = new AnimationSet(true); animationSet.addAnimation(new ScaleAnimation(1.0f, isClicked ? 2.0f : 0.0f, 1.0f, isClicked ? 2.0f : 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f)); animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f)); animationSet.setDuration(duration); animationSet.setInterpolator(new DecelerateInterpolator()); animationSet.setFillAfter(true); return animationSet; } private static Animation createHintSwitchAnimation(final boolean expanded) { Animation animation = new RotateAnimation(expanded ? 45 : 0, expanded ? 0 : 45, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setStartOffset(0); animation.setDuration(100); animation.setInterpolator(new DecelerateInterpolator()); animation.setFillAfter(true); return animation; } }