Android优酷菜单组件自定义

主要做的就是模仿优酷手机客户端的底部菜单控件的实现。先来几张图片,点击中间的home,显示二级菜单,点击二级菜单的menu,显示三级菜单。

这是实现起来最简单的一个布局,但是从中学会了自定义动画和一些布局的基本知识,从中还是收获很大的。

首先是定义布局文件,三个菜单条其实就是三个relativelayout,level1,level2,level3,然后每个菜单条中的小标题就加到对应的相对布局中。

<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="com.test.youku.MainActivity$PlaceholderFragment" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
   <RelativeLayout
        android:id="@+id/level1"
        android:layout_width="100dp"
    	android:layout_height="50dp"
        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:layout_alignParentBottom="true"
           android:layout_centerHorizontal="true"
           android:background="@drawable/icon_home"/>

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/level2"
        android:layout_width="180dp"
    	android:layout_height="90dp"
        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:layout_alignParentBottom="true"
           android:layout_margin="10dp"
           android:background="@drawable/icon_search"/>

        <ImageView
           android:id="@+id/icon_menu"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_centerHorizontal="true"
           android:background="@drawable/icon_menu"/>

        <ImageView
           android:id="@+id/icon_myyouku"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_alignParentBottom="true"
           android:layout_margin="10dp"
           android:layout_alignParentRight="true"
           android:background="@drawable/icon_myyouku"/>

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/level3"
        android:layout_width="280dp"
    	android:layout_height="145dp"
        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:layout_alignParentBottom="true"
           android:layout_marginLeft="10dp"
           android:layout_marginBottom="10dp"
           android:background="@drawable/channel1"/>

        <ImageView
            android:id="@+id/channel2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_above="@id/channel1"
            android:layout_alignLeft="@id/channel1"
            android:layout_marginBottom="6dp"
            android:layout_marginLeft="20dp"
            android:background="@drawable/channel2" />

        <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:layout_marginBottom="6dp"
            android:layout_marginLeft="30dp"
            android:background="@drawable/channel3" />
        <ImageView
            android:id="@+id/channel4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="5dp"
            android:background="@drawable/channel4" />

        <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_marginBottom="10dp"
            android:layout_marginRight="10dp"
            />

        <ImageView
            android:id="@+id/channel6"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/channel7"
            android:layout_alignRight="@id/channel7"
            android:layout_marginBottom="6dp"
            android:layout_marginRight="20dp"
            android:background="@drawable/channel6" />

        <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:layout_marginBottom="6dp"
            android:layout_marginRight="30dp"
            android:background="@drawable/channel5" />

    </RelativeLayout>

</RelativeLayout>

然后就是进入进出动画的定义:

因为是旋转进入,所有 要定义一个RotateAnimation,并进行配置:

import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;

public class MyUtils {

	/**
	 * 让指定的view 执行 旋转离开的动画
	 * @param view
	 */
	public static void startAnimOut(RelativeLayout view) {

		startAnimOut(view, 0);
	}

	/**
	 * 让指定view 延时 执行旋转离开的动画,
	 * @param level3
	 * @param offset	延时的时间
	 */
	public static void startAnimOut(RelativeLayout view, long offset) {
		/*
		 * 默认圆为 为view的左上角,
		 * 水平向右 为 0度
		 * 顺时针旋转度数增加
		 */
		RotateAnimation animation  =new RotateAnimation(0, 180, view.getWidth()/2, view.getHeight());
		animation.setDuration(500);	//	设置运行的时间
		animation.setFillAfter(true);	//动画执行完以后,保持最后的状态
		animation.setStartOffset(offset);	// 设置延时执行的时间

		view.startAnimation(animation);

	}

	/**
	 * 让指定的view 执行 旋转进入的动画
	 * @param view
	 */
	public static void startAnimIn(RelativeLayout view) {

		startAnimIn(view, 0);
	}

	/**
	 * 让指定的view 延时执行 旋转进入的动画
	 * @param level2
	 * @param i	延时的时间
	 */
	public static void startAnimIn(RelativeLayout view, int i) {
		/*
		 * 默认圆为 为view的左上角,
		 * 水平向右 为 0度
		 * 顺时针旋转度数增加
		 */
		RotateAnimation animation  =new RotateAnimation(180, 360, view.getWidth()/2, view.getHeight());
		animation.setDuration(500);	//	设置运行的时间
		animation.setFillAfter(true);	//动画执行完以后,保持最后的状态
		animation.setStartOffset(i);	//设置延时执行的时间
		view.startAnimation(animation);

	}

}

最后就是空间显示的主类了,这个类没什么难的,就是根据逻辑,调用上面写得进入进出动作,要注意逻辑的清晰:

public class MainActivity extends Activity implements OnClickListener {

	private ImageView icon_menu;
	private ImageView icon_home;

	private RelativeLayout level1;
	private RelativeLayout level2;
	private RelativeLayout level3;
	/**
	 * 判断 第3级菜单是否显示
	 * true 为显示
	 */
	private boolean isLevel3Show = true;
	/**
	 * 判断 第2级菜单是否显示
	 * true 为显示
	 */
	private boolean isLevel2Show = true;
	/**
	 * 判断 第1级菜单是否显示
	 * true 为显示
	 */
	private boolean isLevel1show = true;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		icon_home = (ImageView) findViewById(R.id.icon_home);
		icon_menu = (ImageView) findViewById(R.id.icon_menu);

		level1 = (RelativeLayout) findViewById(R.id.level1);
		level2 = (RelativeLayout) findViewById(R.id.level2);
		level3 = (RelativeLayout) findViewById(R.id.level3);

		icon_home.setOnClickListener(this);
		icon_menu.setOnClickListener(this);

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.icon_menu:	//处理 menu 图标的点击事件
			// 如果第3级菜单是显示状态,那么将其隐藏
			if(isLevel3Show){
				//隐藏 第3级菜单
				MyUtils.startAnimOut(level3);
			}else{
				// 如果第3级菜单是隐藏状态,那么将其显示
				MyUtils.startAnimIn(level3);
			}

			isLevel3Show = !isLevel3Show;

			break;
		case R.id.icon_home:	//处理 home 图标 的点击事件
			// 如果第2级菜单是显示状态,那么就隐藏,2,3级菜单
			if(isLevel2Show ){
				MyUtils.startAnimOut(level2);
				isLevel2Show = false;

				if(isLevel3Show){ // 如果此时,第3级菜单也显示,那也将其隐藏
					MyUtils.startAnimOut(level3,200);
					isLevel3Show = false;
				}

			}else{
				// 如果第2级菜单是隐藏状态,那么就显示2级菜单
				MyUtils.startAnimIn(level2);
				isLevel2Show = true;
			}

			break;
		}
	}

	/**
	 * 改变第1级菜单的状态
	 */
	private void changeLevel1State() {
		//如果第1级菜单是显示状态,那么就隐藏 1,2,3级菜单
		if(isLevel1show){
			MyUtils.startAnimOut(level1);
			isLevel1show = false;

			if(isLevel2Show){ // 判断2级菜单是否显示
				MyUtils.startAnimOut(level2,100);
				isLevel2Show = false;
				if(isLevel3Show){ // 判断3级菜单是否显示
					MyUtils.startAnimOut(level3,200);
					isLevel3Show = false;
				}
			}

		}else{
			//如果第1级菜单是隐藏状态,那么就显示 1,2级菜单
			MyUtils.startAnimIn(level1);
			isLevel1show = true;

			MyUtils.startAnimIn(level2,200);
			isLevel2Show = true;

		}

	}

	@Override
	/**
	 * 响应按键的动作
	 */
	public boolean onKeyDown(int keyCode, KeyEvent event) {
	if(keyCode == KeyEvent.KEYCODE_MENU){ // 监听 menu 按键
		changeLevel1State();
	}
		return super.onKeyDown(keyCode, event);
	}

}

最后最后,感觉自定义组件还是很强大很炫的,明天继续学习总结这方面的知识。。睡觉。。

时间: 2024-10-03 23:06:58

Android优酷菜单组件自定义的相关文章

自定义View(一)-ViewGroup实现优酷菜单

自定义View的第一个学习案例 ViewGroup是自动以View中比较常用也比较简单的一种方式,通过组合现有的UI控件,绘制出一个全新的View 效果如下: 主类实现如下: package com.demo.youku; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.Toolbar; import android.view.K

android自定义控件之模仿优酷菜单

去年的优酷HD版有过这样一种菜单,如下图: 应用打开之后,先是三个弧形的三级菜单,点击实体键menu之后,这三个菜单依次旋转退出,再点击实体键menu之后,一级菜单会旋转进入,点击一级菜单,二级菜单旋转进入,点击二级菜单的menu键,三级菜单旋转进入,再次点击二级菜单的旋转键,三级菜单又会旋转退出,这时再点击一级菜单,二级菜单退出,最后点击实体menu键,一级菜单退出. 总体来说实现这样的功能: (1)点击实体menu键时,如果界面上有菜单显示,不管有几个,全部依次退出,如果界面上没有菜单显示,

模仿优酷菜单

转载注明出处:    http://blog.csdn.net/forwardyzk/article/details/42554691 在开发中,会使用菜单,现在模拟一下优酷的菜单效果. 其实效果都是由android基本的动画效果组成的,在合适的时间显示对应的动画,即可展示出不一样的效果. 思路: 1.自定义类RotateMenuView继承RelativeLayout. 2.在需要加载的布局文件中,添加对应的菜单View. 3.定义菜单进入和出去的动画效果,使用旋转动画,进来顺时针,出去的时候

[android] 优酷环形菜单-相对布局练习

优酷环形菜单 布局文件,使用<RelativeLayout/>控件作为第一级菜单,相对布局,位于父控件的底部,水平居中,因为图片不是特别的标准,因此宽度和高度都钉死,宽度是高度的两倍 二次菜单和三级菜单都一样的布局 小房子的图标<imageView/>控件,在父控件中居中 第二级搜索图标,位于父控件的底部,上下左右maigin10dp 第二级菜单图标,位于父控件的顶部,水平居中,marginTop 10dp 第二级叹号图标,位于父控件的底部,右边,margin 10dp 第三级的图

[android] 优酷环形菜单-旋转动画

获取房子,菜单图标ImageView对象,获取三个圆环RelativeLayout对象 给菜单图标(icon_menu)设置点击事件 定义一个成员变量isLevel3Show来存储第三级菜单是否显示 判断上面的变量,来显示隐藏第三级菜单,定义一个类实现动画效果 切换变量,isLevel3Show=!isLevel3Show 定义一个工具类MyUtils,实现旋转动画 定义一个startAnimOut() 获取RotateAnimation对象,旋转对象的默认中心是左上角,开始度数默认是水平向右为

Android仿优酷菜单效果

一.效果图 二.主要的技术点 1.RelativeLayout布局 2.RotateAnimation旋转动画 三.需求 1.点击二级菜单中的“menu”键控制三级菜单的进入和退出动画效果: 2.点击一级菜单中的“home”键控制二级和三级菜单的进入和退出效果: 3.点击手机上的菜单键控制一级.二级和三级菜单的进入和退出效果. 四.实例代码 1.布局文件:activity_main.xml <RelativeLayout xmlns:android="http://schemas.andr

优酷菜单

Android中RelativeLayout各个属性的含义 android:layout_above="@id/xxx"  --将控件置于给定ID控件之上android:layout_below="@id/xxx"  --将控件置于给定ID控件之下 android:layout_toLeftOf="@id/xxx"  --将控件的右边缘和给定ID控件的左边缘对齐android:layout_toRightOf="@id/xxx"

Android自定义控件——仿优酷圆盘菜单

尊重作者劳动成果,转载时请标明该文章出自  http://blog.csdn.net/allen315410/article/details/39232535 最近学习的时候,看见一份资料上教怎么写自定义控件,上面的示例用的是优酷早期版本的客户端,该客户端的菜单就是一个自定义的组件(现在的版本就不清楚有没有了,没下载过了),好吧,废话不多说,先上优酷的原型图. 这个自定义组件感官上看是,里外三层设计,每一层上有布置不同的菜单按钮,每一层又设置了进入和退出的动画,来增强用户的体验效果.这种设计非常

android之官方导航栏ActionBar(三)之高仿优酷首页

一.问题概述 通过上两篇文章,我们对如何使用ActionBar大致都已经有了认识.在实际应用中,我们更多的是定制ActionBar,那么就需要我们重写或者定义一些样式来修饰ActionBar,来满足具体的需要.我们就以优酷首页为例,一起学习下ActionBar的综合应用. 二.Android系统ActionBar样式的定义 首先,我们先认识一下android系统中是如何定义ActionBar样式的,这里我们以Theme.Holo.Light主题为例,通过源码我们可以看到在该主题中关于Action