一、布局效果图如图所示:
要实现的逻辑功能:
点击menu,控制三级菜单的显示:
如果当前三级菜单显示,就把它转出去(逆时针180度)。如果不显示,就转出来三级菜单(顺时针180度)。
点击home,控制二级菜单的显示:
如果三级菜单不显示,二级菜单显示直接转出去二级菜单:
如果三级菜单不显示,二级菜单不显示直接转出来二级菜单:
如果当前三级菜单显示,就先把它转出去,间隔一段时间二级菜单也转出去;
点击手机键盘上的menu,控制所有菜单的显示:
如果,当前有菜单显示,则按照三,二,一的顺序,互相间隔一定的时间顺序转出去。
如果,当前没有菜单显示,则按照一、二、三的顺序,互相间隔一定的时间顺序转出来。
二、xml布局:
layout_marginTop/Bottom和layout_marginLeft/Right控制组件的位置
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<RelativeLayout
android:id="@+id/first_menu"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level1" >
<ImageButton
android:id="@+id/ib_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@null"
android:src="@drawable/icon_home" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/second_menu"
android:layout_width="180dp"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level2" >
<ImageButton
android:id="@+id/ib_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@null"
android:layout_marginTop="5dp"
android:src="@drawable/icon_menu" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_marginBottom="5dp"
android:background="@null"
android:src="@drawable/icon_search" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:background="@null"
android:src="@drawable/icon_myyouku" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/third_menu"
android:layout_width="280dp"
android:layout_height="140dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level3" >
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_marginBottom="5dp"
android:background="@null"
android:src="@drawable/channel1" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="60dp"
android:background="@null"
android:src="@drawable/channel2" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="65dp"
android:layout_marginTop="25dp"
android:background="@null"
android:src="@drawable/channel3" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@null"
android:layout_marginTop="5dp"
android:src="@drawable/channel4" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="@null"
android:layout_marginRight="30dp"
android:layout_marginTop="60dp"
android:src="@drawable/channel5" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="65dp"
android:layout_marginTop="25dp"
android:layout_alignParentRight="true"
android:background="@null"
android:src="@drawable/channel6" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:background="@null"
android:src="@drawable/channel7" />
</RelativeLayout>
</RelativeLayout>
三、旋转动画的逻辑,使用补间动画旋转指定的菜单,并监听记录在旋转的菜单个数,当菜单被旋转出去的时候设置该菜单内的控件不可点击,旋转出来的时候可以点击。
public class AnimationUtils{
// 正在运行的动画个数
public static int runningAnimationCount = 0;
public static void rotateOut(RelativeLayout layout,long delay){
//旋转出去后,找到它的所有子view,禁用,防止layout隐藏之后在原来位置还可以响应点击事件
int childCount = layout.getChildCount();
for (int i = 0; i < childCount; i++) {
layout.getChildAt(i).setEnabled(false);
}
RotateAnimation ra = new RotateAnimation(
0f, -180f, // 开始, 结束的角度, 逆时针
Animation.RELATIVE_TO_SELF, 0.5f, // 相对的x坐标点(指定旋转中心x值)
Animation.RELATIVE_TO_SELF, 1.0f); // 相对的y坐标点(指定旋转中心y值)
ra.setDuration(500);//设置旋转的时间
ra.setFillAfter(true);//设置动画结束的时候,停留在结束的位置
ra.setStartOffset(delay);//设置动画开始延时
ra.setAnimationListener(new MyAnimationListener());//添加监听
layout.startAnimation(ra);
}
public static void rotateIn(RelativeLayout layout,long delay){
//旋转进来后,找到它的所有子view,启用
int childCount = layout.getChildCount();
for (int i = 0; i < childCount; i++) {
layout.getChildAt(i).setEnabled(true);
}
RotateAnimation ra=new RotateAnimation(-180f, 0f//开始和结束的角度,顺时针
, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 1.0f);
ra.setDuration(500);//设置旋转的时间
ra.setFillAfter(true);//设置动画结束的时候,停留在结束的位置
ra.setStartOffset(delay);//设置动画开始延时
ra.setAnimationListener(new MyAnimationListener());//添加监听
layout.startAnimation(ra);
}
static class MyAnimationListener implements AnimationListener{
@Override
public void onAnimationEnd(Animation animation) {
runningAnimationCount --;
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationStart(Animation animation) {
runningAnimationCount ++;
}
}
}
四、
对相应的按钮设置监听事件,在没有菜单正在旋转的时候,开始响应,实现相应的业务逻辑。
public class MainActivity extends Activity implements OnClickListener {
private RelativeLayout rl_level1;
private RelativeLayout rl_level2;
private RelativeLayout rl_level3;
boolean isLevel3Display = true;
boolean isLevel2Display = true;
boolean isLevel1Display = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.ib_home).setOnClickListener(this);
findViewById(R.id.ib_menu).setOnClickListener(this);
rl_level1 = (RelativeLayout) findViewById(R.id.first_menu);
rl_level2 = (RelativeLayout) findViewById(R.id.second_menu);
rl_level3 = (RelativeLayout) findViewById(R.id.third_menu);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//点击手机上的menu按钮执行的逻辑
// keyCode 事件码
//通过这个可以获取到事件码System.out.println("onKeyDown: " + keyCode);
if(keyCode == KeyEvent.KEYCODE_MENU){
if(AnimationUtils.runningAnimationCount > 0){
// 当前有动画正在执行, 取消当前事件
return true;
}
if(isLevel1Display){
long delay = 0;
// 隐藏三级菜单
if(isLevel3Display){
AnimationUtils.rotateOut(rl_level3, 0);
isLevel3Display = false;
delay += 200;
}
// 隐藏二级菜单
if(isLevel2Display){
AnimationUtils.rotateOut(rl_level2, delay);
isLevel2Display = false;
delay += 200;
}
// 隐藏一级菜单
AnimationUtils.rotateOut(rl_level1, delay);
}else {
// 三级菜单全部依次转出来
AnimationUtils.rotateIn(rl_level1, 0);
AnimationUtils.rotateIn(rl_level2, 200);
AnimationUtils.rotateIn(rl_level3, 400);
isLevel3Display = true;
isLevel2Display = true;
}
isLevel1Display = !isLevel1Display;
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onClick(View v) {
if(AnimationUtils.runningAnimationCount > 0){
// 有动画正在执行, 取消该次点击事件
return;
}
switch (v.getId()) {
case R.id.ib_home:
if(isLevel2Display){
long delay = 0;
// 如果三级菜单已经显示, 先转出去
if(isLevel3Display){
AnimationUtils.rotateOut(rl_level3, 0);
isLevel3Display = false;
delay += 200;
}
// 如果二级菜单已经显示, 转出去
AnimationUtils.rotateOut(rl_level2, delay);
}else {
// 如果二级菜单没有显示, 转出来
AnimationUtils.rotateIn(rl_level2, 0);
}
isLevel2Display = !isLevel2Display;
break;
case R.id.ib_menu:
if(isLevel3Display){
// 如果三级菜单已经显示, 转出去
AnimationUtils.rotateOut(rl_level3, 0);
}else {
// 如果三级菜单没有显示, 转出来
AnimationUtils.rotateIn(rl_level3, 0);
}
isLevel3Display = !isLevel3Display;
break;
default:
break;
}
}
}
五、重要的事情写后边
测试很顺利啊,感冒了,涕流不止啊,就写到这儿吧!