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

本文地址: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. 【开源】OSharp框架解说系列(6.1):日志系统设计

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  2. [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证

    很多情况下目标Action方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前请求者是一个经过授权的用户.授权的本质就是让用户在他许可的权限范围内做他能够做的事情,授权的前提是请求者 ...

  3. NFS Volume Provider(Part I) - 每天5分钟玩转 OpenStack(62)

    cinder-volume 支持多种 volume provider,前面我们一直使用的是默认的 LVM,本节我们将增加 NFS volume provider. 虽然 NFS 更多地应用在实验或小规 ...

  4. ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

    为了加强安全性,MySQL5.7为root用户随机生成了一个密码,在error log中,关于error log的位置,如果安装的是RPM包,则默认是/var/log/mysqld.log. 一般可通 ...

  5. 深入理解 OWIN 中的 Host 和 Server

    The Open Web Interface for .NET (OWIN),注意单词为大写,之前好像都写成了 Owin,但用于项目的时候,可以写成:Microsoft.Owin.*. OWIN 体系 ...

  6. 【转】 个人认为,这是最详细的 android------HttpURLConnection 类用法详解。一些教材没讲到的,它讲到了

    站在巨人的肩膀上,渐渐进步. 原文链接:http://www.blogjava.net/supercrsky/articles/247449.html 针对JDK中的URLConnection连接Se ...

  7. Cesium应用篇:2影像服务(上)

    文章中相关范例下载路径:https://yunpan.cn/cByQqkANWN7Pu 访问密码 823d        Cesium中提供了多种ImageryProvider方式,来满足用户的实际需 ...

  8. Cesium原理篇:6 Render模块(4: FBO)

    Cesium不仅仅提供了FBO,也就是Framebuffer类,而且整个渲染过程都是在FBO中进行的.FBO,中文就是帧缓冲区,通常都属于高级用法,但其实,如果你了解了它的基本原理后,用起来还是很简单 ...

  9. composer安装yii2问题总结

    今天周六,在家安装yii2的advanced版本, 过程有些坎坷, 不过最后总算安装好了. 总结一下, 主要遇到下面两个问题: 1, 下载速度慢, 主要原因是网络问题 下载yii2时, 模板(除了ve ...

  10. null和undefined的一些区别

    读了阮一峰的博客,自己总结一下,便记录一篇博客 在javacript的基本类型中,有2种基本类型,只有1个值,便是null和undefined,都表示的是"无".在一定程度上是相等 ...