Android自定义控件4--优酷菜单的菜单键及细节补充
在上篇文章中实现了优酷菜单执行动画,本文接着完善已经实现的动画功能
本文地址: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--优酷菜单的菜单键及细节补充的更多相关文章
- android自定义控件之模仿优酷菜单
去年的优酷HD版有过这样一种菜单,如下图: 应用打开之后,先是三个弧形的三级菜单,点击实体键menu之后,这三个菜单依次旋转退出,再点击实体键menu之后,一级菜单会旋转进入,点击一级菜单,二级菜单旋 ...
- 自定义View(一)-ViewGroup实现优酷菜单
自定义View的第一个学习案例 ViewGroup是自动以View中比较常用也比较简单的一种方式,通过组合现有的UI控件,绘制出一个全新的View 效果如下: 主类实现如下: package com. ...
- Android自定义控件系列(四)—底部菜单(下)
转载请注明出处:http://www.cnblogs.com/landptf/p/6290862.html 在app中经常会用到底部菜单的控件,每次都需要写好多代码,今天我们用到了前几篇博客里的控件来 ...
- Android自定义控件3--优酷菜单执行动画
在上篇文章中实现了优酷菜单的布局,本文接着实现动画功能 本文地址:http://www.cnblogs.com/wuyudong/p/5914901.html,转载请注明源地址. 新建动画工具类Ani ...
- Android自定义控件2--优酷菜单界面初始化
本文开始将逐步去实现下面优酷菜单的效果: 本文地址:http://www.cnblogs.com/wuyudong/p/5912538.html,转载请注明源地址. 本文首先来实现优酷菜单界面初始化工 ...
- android 使用WebView 支持播放优酷视频,土豆视频
看了很多文章和所谓的解决android WebView播放优酷,土豆等视频的办法,都是什么 setPluginsEnabled,在android 4.x之后都不好使,压根就没这函数,因为android ...
- Android笔记——Android自定义控件
目录: 1.自定义控件概述 01_什么是自定义控件 Android系统中,继承Android系统自带的View或者ViewGroup控件或者系统自带的控件,并在这基础上增加或者重新组合成我们想要的效果 ...
- [android] 优酷环形菜单-相对布局练习
优酷环形菜单 布局文件,使用<RelativeLayout/>控件作为第一级菜单,相对布局,位于父控件的底部,水平居中,因为图片不是特别的标准,因此宽度和高度都钉死,宽度是高度的两倍 二次 ...
- android之官方导航栏ActionBar(三)之高仿优酷首页
一.问题概述 通过上两篇文章,我们对如何使用ActionBar大致都已经有了认识.在实际应用中,我们更多的是定制ActionBar,那么就需要我们重写或者定义一些样式来修饰ActionBar,来满足具 ...
随机推荐
- Struts.xml中Action的method与路径的三种匹配方法
原文 http://blog.csdn.net/woshixuye/article/details/7734482 首先我们有一个Action——UserAction public class Us ...
- 新作《ASP.NET Web API 2框架揭秘》正式出版
我觉得大部分人都是“眼球动物“,他们关注的往往都是目光所及的东西.对于很多软件从业者来说,他们对看得见(具有UI界面)的应用抱有极大的热忱,但是对背后支撑整个应用的服务却显得较为冷漠.如果我们将整个“ ...
- ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
前言 事情不太多时,会时不时去看项目中同事写的代码可以作个参考或者学习,个人觉得只有这样才能走的更远,抱着一副老子天下第一的态度最终只能是井底之蛙.前两篇写到关于断点传续的文章,还有一篇还未写出,后续 ...
- android app反编译
最新在反编译别人的apk,有时候看到别人的app有很炫的效果,就想知道别人是怎么样实现的,顺便自己参考,借鉴一下,下一次如果工作中碰到这个问题就知道怎么实现了.最近恰好放假三天,就研究了一下,一般别人 ...
- LVS+Keepalived搭建MyCAT高可用负载均衡集群
LVS+Keepalived 介绍 LVS LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统.本项目在1998年5月由章文嵩博士成立,是中国 ...
- MySQL监控利器-Innotop
Innotop是一款十分强大的MySQL监控工具,用perl所写,通过文本模式展示MysQL服务器和Innodb的运行状况. 安装innotop 下载地址:https://github.com/inn ...
- c# 实现简单udp数据的发送和接收
服务端代码 static void Main(string[] args) { UdpClient client = null; string receiveString = null; byte[] ...
- 【Java心得总结七】Java容器下——Map
我将容器类库自己平时编程及看书的感受总结成了三篇博文,前两篇分别是:[Java心得总结五]Java容器上——容器初探和[Java心得总结六]Java容器中——Collection,第一篇从宏观整体的角 ...
- Mono.Cecil 初探(一):实现AOP
序言 本篇文章介绍基于Mono.Cecil实现静态AOP的两种方式:无交互AOP和交互式AOP. 概念介绍 Mono.Cecil:一个可加载并浏览现有程序集并进行动态修改并保存的.NET框架. AOP ...
- BizTalk动手实验(十七)ODBC适配器使用
更多内容请查看:BizTalk动手实验系列目录 BizTalk 开发系列 1 课程简介 通过本课程熟悉ODBC适配器的的使用,本练习采用BizTalk 20 ...