关于这个菜单应该在很多播放器应用里面可以看见,直接先上两张效果图吧,一张是该Demo的效果图,一张是优酷手机客户端的效果图。

android 三级树 android三级菜单_动画效果

因为没有时间去自己制作图标,所以Demo里面采用的就是优酷手机客户端里的图标了。

一、布局

首先从效果图中可以看出来,该菜单界面分成了三层,所以,我们采用RelativeLayout布局方式来排列这三层菜单背景。

其次,在每一层菜单中,每一个图标也是相对于自己菜单级有固定位置的,所以每一个菜单级也采用RelativeLayout布局方式。

既然布局方式都分析清楚了,那么就可以直接开始写布局文件了。需要注意的就是,每一个图标之间相对位置的摆放,这样才能使整体效果更好。

<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/level1"
        android:layout_width="100dip"
        android:layout_height="50dip"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/level1" >

        <ImageView
            android:id="@+id/icon_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/icon_home" 
            android:layout_centerInParent="true"/>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/level2"
        android:layout_width="180dip"
        android:layout_height="90dip"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/level2" >
        
        <ImageView 
            android:id="@+id/icon_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/icon_search"
            android:layout_alignParentBottom="true"
            android:layout_margin="10dip"/>
        
        <ImageView
            android:id="@+id/icon_menu"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/icon_menu"
            android:layout_marginTop="5dip"
            android:layout_centerHorizontal="true"/>
        
        <ImageView 
            android:id="@+id/icon_myyouku"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/icon_myyouku"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_margin="10dip"/>
        
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/level3"
        android:layout_width="280dip"
        android:layout_height="140dip"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@drawable/level3" >
        
        <ImageView 
            android:id="@+id/channel1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/channel1"
            android:layout_alignParentBottom="true"
            android:layout_marginLeft="10dip"
            android:layout_marginBottom="10dip"/>
        
        <ImageView 
            android:id="@+id/channel2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/channel2"
            android:layout_above="@id/channel1"
            android:layout_alignLeft="@id/channel1"
            android:layout_marginLeft="18dip"
            android:layout_marginBottom="6dip"/>

        <ImageView
            android:id="@+id/channel3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/channel2"
            android:layout_alignLeft="@id/channel2"
            android:background="@drawable/channel3" 
            android:layout_marginLeft="30dip"
            android:layout_marginBottom="6dip"/>
        
        <ImageView 
            android:id="@+id/channel4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/channel4"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="5dip"/>
        
        <ImageView 
            android:id="@+id/channel7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/channel7"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dip"
            android:layout_marginBottom="10dip"/>
        
        <ImageView 
            android:id="@+id/channel6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/channel6"
            android:layout_above="@id/channel7"
            android:layout_alignRight="@id/channel7"
            android:layout_marginRight="18dip"
            android:layout_marginBottom="6dip"/>
        
        <ImageView
            android:id="@+id/channel5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/channel6"
            android:layout_alignRight="@id/channel6"
            android:background="@drawable/channel5" 
            android:layout_marginRight="30dip"
            android:layout_marginBottom="6dip"/>
        
    </RelativeLayout>

</RelativeLayout>

二、MainActivity加载布局文件

在MainActivity.java中,通过onCreate()方法,来加载出布局文件。

三、实现动画效果和点击事件

首先分析可以得出,每一级菜单消失和出现的动画都是相似的,所以可以在此建立一个工具类,来统一编写动画效果的代码,在此建立MyUtils.java

整体的动画效果就分为,消失和出现,所以只用实现这两个方法就好了。

/**
	 * 出现的动画效果* @param view   需要动画效果的view* @startOffset  需要延时执行的时间
	 */
	public static void startAnimIn(RelativeLayout view, int startOffset) {
		RotateAnimation animation = new RotateAnimation(180, 360, view.getWidth()/2, view.getHeight());
		animation.setDuration(500);		      // 设置运行的时间
		animation.setFillAfter(true);	              // 动画执行完以后保持最后的状态
		animation.setStartOffset(startOffset);        // 设置延时执行的时间
		view.startAnimation(animation);
	}在代码中,采用了RotateAnimation这个类,来控制view的动画效果。我们需要的是一个旋转的动画效果,所以我们需要知道默认圆心为 view的左上角,在此需要设置为 view的中心,即(view.getWidth()/2, view.getHeight())根据同样的道理,只需要修改一样动画效果的旋转角度,就可以写出消失动画的效果/**
	 * 让指定view 延时执行旋转离开的动画
	 * @param view
	 * @param i	延时时间
	 */
	public static void startAnimOut(RelativeLayout view, int startOffset) {
		
		RotateAnimation animation = new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());
		animation.setDuration(500);		        // 设置运行的时间
		animation.setFillAfter(true);	                // 动画执行完以后保持最后的状态
		animation.setStartOffset(startOffset);		// 设置延时执行的时间
		view.startAnimation(animation);
	}动画效果的类完成之后,就可以返回MainActivity中去监听按键的点击事件了。@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.icon_menu:		// 处理menu图标的点击事件
			// 如果第三级菜单是显示状态,则将其隐藏
			if(isLevel3Show) {
				// 隐藏
				MyUtils.startAnimOut(level3,0);
			} else {
				// 显示
				MyUtils.startAnimIn(level3,0);
			}
			
			isLevel3Show = !isLevel3Show;
			
			break;
			
		case R.id.icon_home:		// 处理home图标的点击事件
			// 如果二级菜单是显示状态,那么就隐藏2,3级菜单
			if(isLevel2Show ) {
				MyUtils.startAnimOut(level2,0);
				isLevel2Show = false;
				if(isLevel3Show) {
					MyUtils.startAnimOut(level3,200);
					isLevel3Show = false;
				} 
			} else {
				// 如果二级菜单是隐藏状态,那么就显示2级菜单
				MyUtils.startAnimIn(level2,0);
				isLevel2Show = true;
			}
			break;
			
		default:
			break;
		}
	}最后就是修改Menu按键的事件,使按下Menu可以隐藏或显示全部菜单的效果。