去年的优酷HD版有过这样一种菜单,如下图:

应用打开之后,先是三个弧形的三级菜单,点击实体键menu之后,这三个菜单依次旋转退出,再点击实体键menu之后,一级菜单会旋转进入,点击一级菜单,二级菜单旋转进入,点击二级菜单的menu键,三级菜单旋转进入,再次点击二级菜单的旋转键,三级菜单又会旋转退出,这时再点击一级菜单,二级菜单退出,最后点击实体menu键,一级菜单退出。

总体来说实现这样的功能:
(1)点击实体menu键时,如果界面上有菜单显示,不管有几个,全部依次退出,如果界面上没有菜单显示,则显示一级菜单。
(2)点击一级菜单的home键时,如果此时界面只有一级菜单,则显示二级菜单,否则让除了一级菜单外的菜单全都依次退出。
(3)点击二级菜单的menu键时,如果三级菜单已经显示,则让它旋转退出,如果三级菜单未显示则让它旋转进入。

好了,今天我们主要实现上述效果。

先来看布局文件

<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.example.customwidget.MainActivity" ><RelativeLayoutandroid:id="@+id/menu_level1"android:layout_width="100dp"android:layout_height="50dp"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:background="@drawable/level1" ><ImageButtonandroid:id="@+id/level1_home"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:layout_marginBottom="10dp"android:background="@drawable/icon_home"android:onClick="myClick" /></RelativeLayout><RelativeLayoutandroid:id="@+id/menu_level2"android:layout_width="200dp"android:layout_height="100dp"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:background="@drawable/level2" ><ImageButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="10dp"android:layout_marginLeft="15dp"android:background="@drawable/icon_search" /><ImageButtonandroid:id="@+id/level2_menu"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_marginTop="7dp"android:background="@drawable/icon_menu"android:onClick="myClick" /><ImageButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_marginBottom="10dp"android:layout_marginRight="15dp"android:background="@drawable/icon_myyouku" /></RelativeLayout><RelativeLayoutandroid:id="@+id/menu_level3"android:layout_width="320dp"android:layout_height="162dp"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:background="@drawable/level3" ><ImageButtonandroid:id="@+id/level3_channel1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_marginBottom="10dp"android:layout_marginLeft="12dp"android:background="@drawable/channel1" /><ImageButtonandroid:id="@+id/level3_channel2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@id/level3_channel1"android:layout_marginBottom="17dp"android:layout_marginLeft="-5dp"android:layout_toRightOf="@id/level3_channel1"android:background="@drawable/channel2" /><ImageButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@id/level3_channel2"android:layout_marginBottom="15dp"android:layout_marginLeft="13dp"android:layout_toRightOf="@id/level3_channel2"android:background="@drawable/channel3" /><ImageButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_marginTop="10dp"android:background="@drawable/channel4" /><ImageButtonandroid:id="@+id/level3_channel7"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_marginBottom="10dp"android:layout_marginRight="12dp"android:background="@drawable/channel7" /><ImageButtonandroid:id="@+id/level3_channel6"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@id/level3_channel7"android:layout_marginBottom="17dp"android:layout_marginRight="-5dp"android:layout_toLeftOf="@id/level3_channel7"android:background="@drawable/channel6" /><ImageButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@id/level3_channel6"android:layout_marginBottom="15dp"android:layout_marginRight="13dp"android:layout_toLeftOf="@id/level3_channel6"android:background="@drawable/channel5" /></RelativeLayout></RelativeLayout>

这里是一个相对布局中嵌套了三个相对布局,嵌套的第一个相对布局负责显示一级菜单,嵌套的第二个相对布局负责显示二级菜单,嵌套的第三个相对布局负责显示三级菜单。三个不同层次的菜单的背景都是弧形。我们通过指定具体的宽高来使三个层次的菜单具有不同的大小。

效果如下:

再看看MainActivity.java

/*** 模仿优酷菜单* 2015年5月19日*/
public class MainActivity extends Activity {//分别拿到不同等级的菜单private RelativeLayout lv1;private RelativeLayout lv2;private RelativeLayout lv3;private Animation animation;//各级菜单是否显示,默认全都显示private boolean isDisplaylv1 = true;private boolean isDisplaylv2 = true;private boolean isDisplaylv3 = true;//动画是否正在执行,默认动画没有执行private boolean isAnimationRunning = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);lv1 = (RelativeLayout) this.findViewById(R.id.menu_level1);lv2 = (RelativeLayout) this.findViewById(R.id.menu_level2);lv3 = (RelativeLayout) this.findViewById(R.id.menu_level3);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {//如果动画正在执行,则不处理此事件if (isAnimationRunning)return super.onKeyDown(keyCode, event);//如果点击的是菜单键if (keyCode == KeyEvent.KEYCODE_MENU) {//如果一级菜单已经显示,判断二级菜单是否显示if (isDisplaylv1) {//设置动画启动延迟时间int startOffset = 0;//如果二级菜单已经显示,判断三级菜单是否显示,然后退出二级菜单if (isDisplaylv2) {if (isDisplaylv3) {//如果三级菜单已经显示,执行退出动画exitAnimation(lv3, startOffset);//三级菜单退出动画执行完毕之后,动画的启动时间延迟500msstartOffset += 500;isDisplaylv3 = !isDisplaylv3;}//二级菜单退出,此时startOffset=500,即动画启动时间延迟500msexitAnimation(lv2, startOffset);//二级菜单退出动画执行完毕之后,动画的启动时间延迟500msstartOffset += 500;isDisplaylv2 = !isDisplaylv2;}//一级菜单退出,此时startOffset=1000,即动画启动时间延迟1000msexitAnimation(lv1, startOffset);//如果一级菜单未显示,则一级菜单进入} else {enterAnimation(lv1);}isDisplaylv1 = !isDisplaylv1;return true;}return super.onKeyDown(keyCode, event);}public void myClick(View v) {//如果动画正在执行,则不处理此事件if (isAnimationRunning)return;switch (v.getId()) {/*** 当点击二级菜单的menu时,如果三级菜单已经显示,则执行退出动画,* 否则执行进入动画*/case R.id.level2_menu:if (isDisplaylv3) {exitAnimation(lv3, 0);} else {enterAnimation(lv3);}isDisplaylv3 = !isDisplaylv3;break;case R.id.level1_home:// 如果二级菜单已经显示,再判断三级菜单是否显示if (isDisplaylv2) {//通过设置动画启动延迟时间,来实现动画依次退出效果int startOffset = 0;// 如果三级菜单也显示了,则让他们依次退出if (isDisplaylv3) {exitAnimation(lv3, startOffset);startOffset = 700;isDisplaylv3 = !isDisplaylv3;}exitAnimation(lv2, startOffset);isDisplaylv2 = !isDisplaylv2;// 如果二级菜单没有显示,就让二级菜单显示出来} else {enterAnimation(lv2);isDisplaylv2 = !isDisplaylv2;}break;}}/*** 退出动画* @param layout 执行动画的布局文件* @param startOffset 动画启动的延迟时间*/public void exitAnimation(RelativeLayout layout, long startOffset) {animation = AnimationUtils.loadAnimation(this, R.anim.exit_menu);animation.setFillAfter(true);animation.setStartOffset(startOffset);animation.setAnimationListener(new MyAnimationListener());layout.startAnimation(animation);}/*** 进入动画* @param layout 执行动画的布局文件*/public void enterAnimation(RelativeLayout layout) {animation = AnimationUtils.loadAnimation(this, R.anim.enter_menu);animation.setFillAfter(true);animation.setAnimationListener(new MyAnimationListener());layout.startAnimation(animation);}/*** 判断动画是否正在执行* @author 王松**/private class MyAnimationListener implements AnimationListener {//动画开始执行@Overridepublic void onAnimationStart(Animation animation) {isAnimationRunning = true;}//动画执行结束@Overridepublic void onAnimationEnd(Animation animation) {isAnimationRunning = false;}@Overridepublic void onAnimationRepeat(Animation animation) {}}
}

代码中注释已经写的很详细了,这里不再赘述。最后在给大家看看两个动画文件:

enter_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:shareInterpolator="true"><rotate
        android:duration="1000"android:fromDegrees="-180"android:toDegrees="0"android:pivotX="50%"android:pivotY="100%" />
</set>

exit_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:shareInterpolator="true"><rotate
        android:duration="1000"android:fromDegrees="0"android:toDegrees="-180"android:pivotX="50%"android:pivotY="100%" />
</set>

关于动画如果不太懂可以看这里android之tween动画详解,android之frame动画详解。。

本项目完整代码下载

android自定义控件之模仿优酷菜单相关推荐

  1. android仿优酷菜单,Android自定义控件之仿优酷菜单

    去年的优酷HD版有过这样一种菜单,如下图: 应用打开之后,先是三个弧形的三级菜单,点击实体键menu之后,这三个菜单依次旋转退出,再点击实体键menu之后,一级菜单会旋转进入,点击一级菜单,二级菜单旋 ...

  2. Android自定义控件:优酷菜单

    优酷菜单 常用控件回顾 布局文件实现 代码处理逻辑 解决bug的两种方法(ViewGroup和属性动画) 常用控件回顾 按钮控件(Button和ImageButton) ImageButton继承自I ...

  3. Android优酷菜单组件自定义

    主要做的就是模仿优酷手机客户端的底部菜单控件的实现.先来几张图片,点击中间的home,显示二级菜单,点击二级菜单的menu,显示三级菜单. 这是实现起来最简单的一个布局,但是从中学会了自定义动画和一些 ...

  4. android仿优酷菜单,Android编程实现仿优酷旋转菜单效果(附demo源码)

    本文实例讲述了Android编程实现仿优酷旋转菜单效果.分享给大家供大家参考,具体如下: 首先,看下效果: 不好意思,不会制作动态图片,只好上传静态的了,如果谁会,请教教我吧. 首先,看下xml文件: ...

  5. android的优酷菜单,Android利用属性动画实现优酷菜单

    利用属性动画实现优酷菜单,供大家参考,具体内容如下 布局文件 xmlns:tools="http://schemas.android.com/tools" android:layo ...

  6. android 优酷 自动全屏播放,Android如何实现仿优酷视频的悬浮窗播放效果

    Android如何实现仿优酷视频的悬浮窗播放效果 发布时间:2020-07-11 10:24:43 来源:亿速云 阅读:228 作者:清晨 这篇文章主要介绍Android如何实现仿优酷视频的悬浮窗播放 ...

  7. android 双层旋转菜单,Android 高仿【优酷】圆盘旋转菜单的实现

    目前,用户对安卓应用程序的UI设计要求越来越高,因此,掌握一些新颖的设计很有必要. 比如菜单,传统的菜单已经不能满足用户的需求. 其中优酷中圆盘旋转菜单的实现就比较优秀,这里我提供下我的思路及实现,仅 ...

  8. Android 高仿【优酷】圆盘旋转菜单的实现

    目前,用户对安卓应用程序的UI设计要求越来越高,因此,掌握一些新颖的设计很有必要. 比如菜单,传统的菜单已经不能满足用户的需求. 其中优酷中圆盘旋转菜单的实现就比较优秀,这里我提供下我的思路及实现,仅 ...

  9. android imageview 图片切换动画,模仿优酷Android客户端图片左右滑动(自动切换)效果...

    本例是用ViewPager去做的实现,支持自动滑动和手动滑动,不仅优酷网,实际上有很多商城和门户网站都有类似的实现: 具体思路: 1. 工程中需要添加android-support-v4.jar,才能 ...

最新文章

  1. pythonsvc_sklearn-SVC实现与类参数详解
  2. 冲刺一阶段———个人总结04
  3. SAP创建基于Lead的OData服务,BO列表里只有一个Lead BO可选
  4. Session,Cookie,jsessionid,Url重写
  5. java getparameter 乱码_request.getParameter(“参数名”) 中文乱码解决方法
  6. 理论基础 —— 查找 —— 平衡二叉树
  7. (19)Zynq FPGA TTC定时器介绍
  8. Javascript设置定时请求
  9. treemap底层结构_HashMap面试必问的数据结构相关知识总结
  10. LeetCode ZigZag Conversion(将字符串排成z字型)
  11. Java数据结构与算法——哈希表
  12. 数据读取入门——xlsread
  13. java导出excel图片,数据库中图片如何导出到excel表格-Java 怎么把服务器中的图片导出到excel(图片的路......
  14. 吹气球--记忆化搜索
  15. 如何正确理解商业智能BI的实时性?
  16. 第一章:python入门储备知识
  17. 用python爬取前程无忧网大数据岗位信息并分析
  18. 会声会影2023中文旗舰版新增功能讲解及下载更新教程
  19. React Native 启动流程 源码剖析
  20. 如何获取用户的openid

热门文章

  1. (附源码)php社区果蔬网站的开发 毕业设计211548
  2. 用HTML和CSS编辑的简历模板
  3. php生成二维码的几种方式,超级实用
  4. html怎么使图片自动填充,CSS怎么将img图片填满父容器div自适应容器大小
  5. 多线程的三种实现方法、线程类的常见方法、线程安全问题:synchronized和Lock锁、生产者和消费者问题
  6. 一加9pro怎么样 哈苏摄像引领智能手机新潮流
  7. 推荐一些适合学习的官网
  8. 魅蓝metal android底层,集体去YunOS化:魅蓝2\魅蓝Metal更换安卓底层
  9. 搭建华为FusionCompute虚拟化平台
  10. php 可以编辑treegrid,TreeGrid 实现增删改查