返回顶部
首页 > 资讯 > 移动开发 >Android自定义控件之仿优酷菜单
  • 440
分享到

Android自定义控件之仿优酷菜单

菜单Android 2022-06-06 08:06:42 440人浏览 泡泡鱼
摘要

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

去年的优酷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" >
 <RelativeLayout
  android:id="@+id/menu_level1"
  android:layout_width="100dp"
  android:layout_height="50dp"
  android:layout_alignParentBottom="true"
  android:layout_centerHorizontal="true"
  android:background="@drawable/level1" >
  <ImageButton
   android: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>
 <RelativeLayout
  android:id="@+id/menu_level2"
  android:layout_width="200dp"
  android:layout_height="100dp"
  android:layout_alignParentBottom="true"
  android:layout_centerHorizontal="true"
  android:background="@drawable/level2" >
  <ImageButton
   android: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" />
  <ImageButton
   android: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" />
  <ImageButton
   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="15dp"
   android:background="@drawable/icon_myyouku" />
 </RelativeLayout>
 <RelativeLayout
  android:id="@+id/menu_level3"
  android:layout_width="320dp"
  android:layout_height="162dp"
  android:layout_alignParentBottom="true"
  android:layout_centerHorizontal="true"
  android:background="@drawable/level3" >
  <ImageButton
   android: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" />
  <ImageButton
   android: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" />
  <ImageButton
   android: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" />
  <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerHorizontal="true"
   android:layout_marginTop="10dp"
   android:background="@drawable/channel4" />
  <ImageButton
   android: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" />
  <ImageButton
   android: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" />
  <ImageButton
   android: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



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;
 @Override
 protected 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);
 }
 @Override
 public 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);
      //三级菜单退出动画执行完毕之后,动画的启动时间延迟500ms
      startOffset += 500;
      isDisplaylv3 = !isDisplaylv3;
     }
     //二级菜单退出,此时startOffset=500,即动画启动时间延迟500ms
     exitAnimation(lv2, startOffset);
     //二级菜单退出动画执行完毕之后,动画的启动时间延迟500ms
     startOffset += 500;
     isDisplaylv2 = !isDisplaylv2;
    }
    //一级菜单退出,此时startOffset=1000,即动画启动时间延迟1000ms
    exitAnimation(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()) {
  
  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;
  }
 }
 
 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);
 }
 
 public void enterAnimation(RelativeLayout layout) {
  animation = AnimationUtils.loadAnimation(this, R.anim.enter_menu);
  animation.setFillAfter(true);
  animation.setAnimationListener(new MyAnimationListener());
  layout.startAnimation(animation);
 }
 
 private class MyAnimationListener implements AnimationListener {
  //动画开始执行
  @Override
  public void onAnimationStart(Animation animation) {
   isAnimationRunning = true;
  }
  //动画执行结束
  @Override
  public void onAnimationEnd(Animation animation) {
   isAnimationRunning = false;
  }
  @Override
  public 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动画效果

源码下载:http://xiazai.jb51.net/201606/yuanma/Androidyouku(jb51.net).rar

原文链接:http://blog.csdn.net/u012702547/article/details/45842963

您可能感兴趣的文章:Android编程实现仿优酷圆盘旋转菜单效果的方法详解【附demo源码下载】Android仿优酷圆形菜单学习笔记分享Android编程实现仿优酷旋转菜单效果(附demo源码)Android 带有弹出收缩动画的扇形菜单实例Android菜单(动画菜单、360波纹菜单)Android实现360手机助手底部的动画菜单Android程序开发之使用Design包实现QQ动画侧滑效果和滑动菜单导航Android利用属性动画实现优酷菜单


--结束END--

本文标题: Android自定义控件之仿优酷菜单

本文链接: https://lsjlt.com/news/24853.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作