这一篇文在上一篇的基础上做的功能修改(上一篇地址:https://www.jianshu.com/p/ecea65f4015d)
效果图如下:
主要的修改有下面几个方面:
1.主菜单有五个,点击第三个会打开星级菜单
2.在星级菜单打开的情况,点击其余的主菜单会关闭星级菜单
3.主菜单和星级菜单的位置不一样了,星级菜单这次是180度的区域
4.星级菜单的移动动画的路径不一样
1.前面的步骤还是一样,自定义属性,自定义view,绘制xml布局,在自定义的view里面获取半径,重写onMeasure方法
2.重写onLayout方法
测量主button的位置
private void layoutCenter2() {
LinearLayout mainView = (LinearLayout) getChildAt(0);
int width = mainView.getMeasuredWidth();
int height = mainView.getMeasuredHeight();
int t = getMeasuredHeight() - height;
mainView.layout(0, t, width, getMeasuredHeight());
mCButton = findViewById(R.id.btnCenter);
findViewById(R.id.btnMain1).setOnClickListener(this);
findViewById(R.id.btnMain2).setOnClickListener(this);
findViewById(R.id.btnMain3).setOnClickListener(this);
findViewById(R.id.btnMain4).setOnClickListener(this);
mCButton.setOnClickListener(this);
}
测量星级菜单的位置
/**
* 设置itemMenu的位置
*/
private void layoutIButtom() {
int cout = getChildCount();
for (int i = 0; i < cout - 1; i++) {
View childView = getChildAt(i + 1);
int width = childView.getMeasuredWidth();
int height = childView.getMeasuredHeight();
//相对坐标
int rlx = (int) (mRadius * Math.cos(Math.PI / cout * (i + 1)));
int rly = (int) (mRadius * Math.sin(Math.PI / cout * (i + 1)));
int l = getMeasuredWidth() / 2 + rlx - width / 2;
int t = getMeasuredHeight() - rly - height;
childView.layout(l, t, l + width, t + height);
childView.setVisibility(GONE);
}
}
3.点击中间的星级菜单的动画效果,主菜单还是一样的,星级菜单会有点区别
/**
* mune的动画效果
*
* @param duration
*/
private void toggleItemMenu(int duration) {
int count = getChildCount();
for (int i = 0; i < count - 1; i++) {
final View childView = getChildAt(i + 1);
childView.setVisibility(VISIBLE);
int rlx = (int) (mRadius * Math.cos(Math.PI / count * (i + 1)));
int rly = (int) (mRadius * Math.sin(Math.PI / count * (i + 1)));
AnimationSet animationSet = new AnimationSet(true);
//位移动画
TranslateAnimation translateAnimation = null;
//打开
if (mCurrentStatus == State.CLOSE) {
translateAnimation = new TranslateAnimation(-rlx, 0f, rly, 0f);
childView.setEnabled(true);
childView.setFocusable(true);
} else {//关闭
translateAnimation = new TranslateAnimation(0f, -rlx, 0f, rly);
}
translateAnimation.setDuration(duration);
translateAnimation.setFillAfter(true);
//旋转动画
RotateAnimation rotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(duration);
rotateAnimation.setFillAfter(true);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(translateAnimation);
childView.startAnimation(animationSet);
animationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (mCurrentStatus == State.CLOSE) {
childView.setVisibility(GONE);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
final int pos = i + 1;
childView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onMenuItemClick != null) {
onMenuItemClick.onItemMenuItemClick(pos);
}
onMenuItemAnmiate(pos - 1);
changeMenuStatus();
}
});
}
changeMenuStatus();
}
其余的效果都差不多,项目地址和上篇的项目地址是一样的