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

本文地址: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. .Net 转战 Android 4.4 日常笔记(1)--工具及环境搭建

    闲来没事做,还是想再学习一门新的技术,无论何时Android开发比Web的开发工资应该高40%,我也建议大家面对移动开发,我比较喜欢学习最新版本的,我有java的基础,但是年久,已经淡忘,以零基础学习 ...

  2. 【原创】.NET平台机器学习组件-Infer.NET连载(二)贝叶斯分类器

                本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html 微软Infer.NET机器学习组件文章目录:http:/ ...

  3. javascript之一切皆为对象2

    其实呢,“函数function”和“对象object”之间还有这么一句话:对象是通过函数来创建的,而函数却又是一种对象. 这个函数是一种对象,上节中“Javascript之一切皆为对象1”也清楚的阐述 ...

  4. Int,Long比较重使用equal替换==

    首先,==有很多限制,如Integer 类型的值在[-128,127] 期间,Integer 用 “==”是可以的(参考),超过范围则不行,那么使用equal则代替则完全ok public stati ...

  5. Spark计算均值

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 用spark来快速计算分组的平均值,写法很便捷,话不多说上代码 object ColumnVal ...

  6. Win10 UWP系列:更新UWP时注意的问题——TargetDeviceFamily

    前几天把CurrencyExchanger提交到微软参加Master认证,结果没有通过,反馈了一些错误,看来微软检查还是比较仔细的. 错误主要有: Visual feedback helps user ...

  7. ADO.NET数据访问技术

    ADO.NET数据访问技术 就是将C#和MSSQLl连接起来的纽带 可以通过ADO.NET将内存中的临时数据写入到数据库中,也可以将数据库中的数据提取到内存中供程序调用.是所有数据访问技术的基础. A ...

  8. Java 9将采用新的版本字符串格式

             在现有的版本编码格式使用了两年之后,从Java 9开始,Java版本方案将根据业内软件版本编码的最佳实践进行修改.使用或解析Java版本字符串的应用程序开发人员要注意了,因为这种变化 ...

  9. HTML5标签与HTML4标签的区别示例介绍_html5教程技巧

    (1)概念的变化: HTML5专注内容与结构,而不专注的表现 <header> <hgroup>导航相关数据</hgroup> </header> &l ...

  10. C++构造函数中不能调用虚函数

    在构造函数中调用虚函数,并不会产生多态的效果,就跟普通函数一样. c++ primer 第四版中497页15.4.5构造函数和析构中的虚函数讲到,如果在构造函数或析构函数中调用虚函数,则运行的是为构造 ...