上篇文章中实现了优酷菜单执行动画,本文接着完善已经实现的动画功能

本文地址:http://www.cnblogs.com/wuyudong/p/5915958.html ,转载请注明源地址。

已经实现的菜单动画功能存在一点BUG,那就是当快速连续点击menu或home按钮的时候,动画出现进入和退出不定操作现象

下面来解决这一问题,可以通过监听事件来判断当前是否正在执行进入或进出操作,代码如下:

package com.wuyudong.youkumenu.utils;

import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout; public class AnimationUtils { public static int runningAnimationCount = 0; // 旋转出去的动画
public static void rotateOutAnim(RelativeLayout layout, long delay) {
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 rotateInAnim(RelativeLayout layout) {
RotateAnimation ra = new RotateAnimation(
-180f, 0f, //开始,结束的角度, 顺时针
Animation.RELATIVE_TO_SELF, 0.5f, //相对的x坐标点(指定旋转中心x值)
Animation.RELATIVE_TO_SELF, 1.0f); //相对的y坐标点(指定旋转中心y值)
ra.setDuration(500);
ra.setFillAfter(true);
ra.setAnimationListener(new MyAnimationListener());
layout.startAnimation(ra); } static class MyAnimationListener implements AnimationListener { @Override
public void onAnimationStart(Animation animation) {
runningAnimationCount++; } @Override
public void onAnimationEnd(Animation animation) {
runningAnimationCount--;
} @Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub } } }

在点击事件中添加一小段判断的代码即可

    public void onClick(View v) {
if (AnimationUtils.runningAnimationCount > 0) {
//当前有动画正在执行,不执行当前事件
return;
}
.......

问题搞定

接下来还要进一步完善,当用户点击手机menu的时候,同样能得到点击优酷菜单同样的动画效果

这样需要判断用户的点击本机menu按键事件:

    public boolean onKeyDown(int keyCode, KeyEvent event) {
// keyCode 事件码
if(keyCode == KeyEvent.KEYCODE_MENU) {
if (AnimationUtils.runningAnimationCount > 0) {
//当前有动画正在执行,不执行当前事件
return true;
}
if (islevel1Display) {
long delay = 0;
//隐藏三级菜单
if(islevel3Display) {
AnimationUtils.rotateOutAnim(rl_level3, 0);
islevel3Display = false;
delay += 200;
} //隐藏二级菜单
if(islevel2Display) {
AnimationUtils.rotateOutAnim(rl_level2, delay);
islevel2Display = false;
delay += 200;
} //隐藏二级菜单
AnimationUtils.rotateOutAnim(rl_level1, delay);
} else {
AnimationUtils.rotateInAnim(rl_level1, 0);
AnimationUtils.rotateInAnim(rl_level2, 200);
AnimationUtils.rotateInAnim(rl_level3, 400); islevel3Display = true;
islevel2Display = true;
}
islevel1Display = !islevel1Display;
return true; //消费当前事件
}
return super.onKeyDown(keyCode, event);
}

完整的AnimationUtils代码如下:

package com.wuyudong.youkumenu.utils;

import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout; public class AnimationUtils { public static int runningAnimationCount = 0; // 旋转出去的动画
public static void rotateOutAnim(RelativeLayout layout, long delay) {
int childCount = layout.getChildCount();
//如果隐藏,则找到所有的子View,禁用
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 rotateInAnim(RelativeLayout layout, long delay) {
int childCount = layout.getChildCount();
//如果隐藏,则找到所有的子View,启用
for (int i = 0; i < childCount; i++) {
layout.getChildAt(i).setEnabled(true);
}
RotateAnimation ra = new RotateAnimation(
-180f, 0f, //开始,结束的角度, 顺时针
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); } static class MyAnimationListener implements AnimationListener { @Override
public void onAnimationStart(Animation animation) {
runningAnimationCount++; } @Override
public void onAnimationEnd(Animation animation) {
runningAnimationCount--;
} @Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub } } }

完整的MainActivity代码如下:

package com.wuyudong.youkumenu;

import com.wuyudong.youkumenu.utils.AnimationUtils;

import android.os.Bundle;
import android.app.Activity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout; public class MainActivity extends Activity implements OnClickListener { private RelativeLayout rl_level1;
private RelativeLayout rl_level2;
private RelativeLayout rl_level3;
private boolean islevel1Display = true;
private boolean islevel2Display = true;
private boolean islevel3Display = true; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
initViews();
} private void initViews() {
// 添加点击事件
findViewById(R.id.ib_home).setOnClickListener(this);
findViewById(R.id.ib_menu).setOnClickListener(this);
rl_level1 = (RelativeLayout) findViewById(R.id.rl_level1);
rl_level2 = (RelativeLayout) findViewById(R.id.rl_level2);
rl_level3 = (RelativeLayout) findViewById(R.id.rl_level3); } @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// keyCode 事件码
if(keyCode == KeyEvent.KEYCODE_MENU) {
if (AnimationUtils.runningAnimationCount > 0) {
//当前有动画正在执行,不执行当前事件
return true;
}
if (islevel1Display) {
long delay = 0;
//隐藏三级菜单
if(islevel3Display) {
AnimationUtils.rotateOutAnim(rl_level3, 0);
islevel3Display = false;
delay += 200;
} //隐藏二级菜单
if(islevel2Display) {
AnimationUtils.rotateOutAnim(rl_level2, delay);
islevel2Display = false;
delay += 200;
} //隐藏二级菜单
AnimationUtils.rotateOutAnim(rl_level1, delay);
} else {
AnimationUtils.rotateInAnim(rl_level1, 0);
AnimationUtils.rotateInAnim(rl_level2, 200);
AnimationUtils.rotateInAnim(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 = 200;
// 如果当前三级菜单已经显示,先转出去
if (islevel3Display) {
AnimationUtils.rotateOutAnim(rl_level3, 0);
islevel3Display = false;
delay += 200;
}
// 如果当前二级菜单已经显示,转出去
AnimationUtils.rotateOutAnim(rl_level2, delay); } else {
// 如果当前二级菜单没有显示,转出来
AnimationUtils.rotateInAnim(rl_level2, 0);
}
islevel2Display = !islevel2Display;
break;
case R.id.ib_menu:
if (islevel3Display) {
// 如果当前三级菜单已经显示,转出去
AnimationUtils.rotateOutAnim(rl_level3, 0);
} else {
AnimationUtils.rotateInAnim(rl_level3, 0);
}
islevel3Display = !islevel3Display;
break; default:
break;
} } }

Android自定义控件4--优酷菜单的菜单键及细节补充的更多相关文章

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

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

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

    自定义View的第一个学习案例 ViewGroup是自动以View中比较常用也比较简单的一种方式,通过组合现有的UI控件,绘制出一个全新的View 效果如下: 主类实现如下: package com. ...

  3. Android自定义控件系列(四)—底部菜单(下)

    转载请注明出处:http://www.cnblogs.com/landptf/p/6290862.html 在app中经常会用到底部菜单的控件,每次都需要写好多代码,今天我们用到了前几篇博客里的控件来 ...

  4. Android自定义控件3--优酷菜单执行动画

    在上篇文章中实现了优酷菜单的布局,本文接着实现动画功能 本文地址:http://www.cnblogs.com/wuyudong/p/5914901.html,转载请注明源地址. 新建动画工具类Ani ...

  5. Android自定义控件2--优酷菜单界面初始化

    本文开始将逐步去实现下面优酷菜单的效果: 本文地址:http://www.cnblogs.com/wuyudong/p/5912538.html,转载请注明源地址. 本文首先来实现优酷菜单界面初始化工 ...

  6. android 使用WebView 支持播放优酷视频,土豆视频

    看了很多文章和所谓的解决android WebView播放优酷,土豆等视频的办法,都是什么 setPluginsEnabled,在android 4.x之后都不好使,压根就没这函数,因为android ...

  7. Android笔记——Android自定义控件

    目录: 1.自定义控件概述 01_什么是自定义控件 Android系统中,继承Android系统自带的View或者ViewGroup控件或者系统自带的控件,并在这基础上增加或者重新组合成我们想要的效果 ...

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

    优酷环形菜单 布局文件,使用<RelativeLayout/>控件作为第一级菜单,相对布局,位于父控件的底部,水平居中,因为图片不是特别的标准,因此宽度和高度都钉死,宽度是高度的两倍 二次 ...

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

    一.问题概述 通过上两篇文章,我们对如何使用ActionBar大致都已经有了认识.在实际应用中,我们更多的是定制ActionBar,那么就需要我们重写或者定义一些样式来修饰ActionBar,来满足具 ...

随机推荐

  1. java中动态代理实现机制

    前言: 代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系 ...

  2. Neutron 如何支持多种 network provider - 每天5分钟玩转 OpenStack(70)

    Neutron 的架构是非常开放的,可以支持多种 network provider,只要遵循一定的设计原则和规范.本节我们将开始讨论这个主题. 先讨论一个简单的场景:在 Neutorn 中使用 lin ...

  3. Create Volume 操作(Part III) - 每天5分钟玩转 OpenStack(52)

    本节是创建 Volume 的第三部分,也是最后一部分:cinder-volume 的处理过程. 第一部分和第二部分可以参考前面两个小节.cinder-volume 通过 driver 创建 volum ...

  4. JSP页面静态化

    Ps:好久没写博客了,不是我太懒,是因为苦逼的我出差去上海了,天天加班 刚回成都.... 今天说说jsp页面静态化,知道静态化的朋友都不陌生,说白了就是访问后缀是html 而不是jsp. 没听说过静态 ...

  5. js 对cookie 的操作

    <!DOCTYPE html> <html> <head> <script> function setCookie(cname,cvalue,exday ...

  6. Microsoft Message Analyzer (微软消息分析器,“网络抓包工具 - Network Monitor”的替代品)官方正式版现已发布

    来自官方日志的喜悦 被誉为全新开始的消息分析器时代,由MMA为您开启,博客原文写的很激动,大家可以点击这里浏览:http://blogs.technet.com/b/messageanalyzer/a ...

  7. java 线程的开始、暂停、继续

    Android项目中的一个需求:通过线程读取文件内容,并且可以控制线程的开始.暂停.继续,来控制读文件.在此记录下. 直接在主线程中,通过wait.notify.notifyAll去控制读文件的线程( ...

  8. HTML5 Canvas 画布

    一.Canvas是什么? canvas,是一个画布,canvas元素用于在网页上绘制图形. canvas 拥有多种绘制路径.矩形.圆形.字符以及添加图像的方法. 二.创建Canvas元素 加上基本的属 ...

  9. CentOS 7.2 yum方式安装MySQL 5.7

    CentOS 7之后的版本yum的默认源中使用MariaDB替代原先MySQL,因此安装方式较为以往有一些改变: 下载mysql的源 wget http://dev.mysql.com/get/mys ...

  10. Oracle11g中数据的倒库和入库操作以及高版本数据导入低版本数据可能引发的问题

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在10g之前,传统的导出和导入分别使用EXP工具和IMP工具 ...