Android简易实战教程--第二十三话《绚丽的菜单项》
转载本博客请注明出处:点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52327456
今天这篇稍微增强点代码量,可能要多花上5分钟喽。
本篇完成一个稍微显得绚丽的菜单项,模仿优酷选择菜单。如果想对其中的任意一项实现点击功能,自行加入即可。
现在就一步一步做出这个小案例:
在实现功能前,先看一下完成的结果,可能能对代码更好的理解。
效果演示:
PS:由于代码中做出了详细的解释,不再做过多的赘述。
首先自定义组合控件布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" > <RelativeLayout
android:id="@+id/rl_level3"
android:layout_width="320dip"
android:layout_height="160dip"
android:layout_alignParentBottom="true"
android:background="@drawable/level3" > <ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dip"
android:background="@drawable/channel4" /> <ImageButton
android:id="@+id/iv_channel1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dip"
android:layout_marginLeft="12dip"
android:background="@drawable/channel1" /> <ImageButton
android:id="@+id/iv_channel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/iv_channel1"
android:layout_marginBottom="16dip"
android:layout_marginLeft="35dip"
android:background="@drawable/channel2" /> <ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/iv_channel2"
android:layout_marginBottom="16dip"
android:layout_marginLeft="70dip"
android:background="@drawable/channel3" /> <ImageButton
android:id="@+id/iv_channel7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="5dip"
android:layout_marginRight="12dip"
android:background="@drawable/channel7" /> <ImageButton
android:id="@+id/iv_channel6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/iv_channel7"
android:layout_alignParentRight="true"
android:layout_marginBottom="16dip"
android:layout_marginRight="35dip"
android:background="@drawable/channel6" /> <ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/iv_channel6"
android:layout_alignParentRight="true"
android:layout_marginBottom="16dip"
android:layout_marginRight="70dip"
android:background="@drawable/channel5" />
</RelativeLayout> <RelativeLayout
android:id="@+id/rl_level2"
android:layout_width="200dip"
android:layout_height="100dip"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level2" > <ImageButton
android:id="@+id/ib_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dip"
android:background="@drawable/icon_menu" /> <ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="5dip"
android:layout_marginLeft="12dip"
android:background="@drawable/icon_search" /> <ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="5dip"
android:layout_marginRight="12dip"
android:background="@drawable/icon_myyouku" />
</RelativeLayout> <RelativeLayout
android:id="@+id/rl_level1"
android:layout_width="100dip"
android:layout_height="50dip"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/level1"
android:gravity="center" > <ImageButton
android:id="@+id/ib_home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/icon_home" />
</RelativeLayout> </RelativeLayout>
因为动画不断地使用,选择定义一个动画效果的utils类:
package com.itydl.yukudemo.Utils; import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout; /**
* 这是专门设置动画操作的工具类
* @author lenovo
*
*/ public class MyAnimationUtils { private static int runningAnimation = 0;//是否存在动画播放的标志位 public static boolean isRunningAnimation(){
return runningAnimation!=0;
} /**
* 开始旋转隐藏的动画
* @param v
* 要给哪个view加动画
*/
public static void startRotateHindeAnimation(RelativeLayout v){
//复用动画方法,这里是不延时动画 startRotateHindeAnimation(v,0);
} /**
* 带有延时效果的动画
* @param v
* 要给哪个组件加入动画
* @param startOffset
* 延时时间,传递过来
*/
public static void startRotateHindeAnimation(RelativeLayout v,long startOffset){
//如果当前的动画隐藏了,该view动画上边的控件的事件也要阉割掉
for(int i = 0 ;i< v.getChildCount(); i ++){
v.getChildAt(i).setEnabled(false);//view.getChildAt(i)获取索引位置的子控件实例;setEnabled(false);禁用事件
}
RotateAnimation ra = new RotateAnimation(
0, -180,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 1f);
ra.setDuration(500);
ra.setFillAfter(true);//设置动画执行完毕,控件状态停留在结束状态
//设置动画监听状态
ra.setAnimationListener(animationListener);
//加入延时
ra.setStartOffset(startOffset);
//给哪个view加动画,传递过来这个view
v.startAnimation(ra); } /**
* 旋转显示的动画
* @param v
* 要给哪个view加动画
*/
public static void startRotateShowAnimation(RelativeLayout v){
startRotateShowAnimation(v, 0);
} /**
* 延时显示动画
* @param v
* 要给哪个view加动画
* @param startOffset
* 设置动画延时时间,传递过来
*/
public static void startRotateShowAnimation(RelativeLayout v,int startOffset){ //设置如果当前的view显示,让该view子控件也都重新获取事件
for(int i = 0 ;i< v.getChildCount(); i ++){
v.getChildAt(i).setEnabled(true);//view.getChildAt(i)获取索引位置的子控件实例;setEnabled(true);启动事件
}
RotateAnimation ra = new RotateAnimation(
-180, 0,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 1f);
ra.setDuration(500);
ra.setFillAfter(true);//设置动画执行完毕,控件状态停留在结束状态
//设置动画监听状态
ra.setAnimationListener(animationListener);
//延时播放动画
ra.setStartOffset(startOffset);
//给哪个view加动画,传递过来这个view
v.startAnimation(ra);
} static AnimationListener animationListener = new AnimationListener() { //开始播放
@Override
public void onAnimationStart(Animation animation) {
// 播放一个动画,说明存在一个动画在播放
runningAnimation ++ ; } @Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub } //播放结束
@Override
public void onAnimationEnd(Animation animation) {
// 动画播放完毕
runningAnimation -- ; }
}; }
MainActivity的代码如下:
package com.itydl.yukudemo; import com.itydl.yukudemo.Utils.MyAnimationUtils; 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.ImageButton;
import android.widget.RelativeLayout; public class MainActivity extends Activity { private RelativeLayout mRl_Level1;
private RelativeLayout mRl_Level2;
private RelativeLayout mRl_Level3;
private ImageButton mIb_Home;
private ImageButton mIb_Menu; private boolean level3 = true;//设置标志位,对状态改变标记;三级菜单默认状态为显示。(注意这种编程思想)
private boolean level2 = true;//设置标志位,对状态改变标记;二级菜单默认状态为显示。(注意这种编程思想)
private boolean level1 = true;//设置标志位,对状态改变标记;一级菜单默认状态为显示。(注意这种编程思想) @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
} /**
* 初始化事件
*/
private void initEvent() { // 对menu和home按钮加入点击事件
OnClickListener listener = new OnClickListener() { @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ib_home:// 点击的是home键
//解决连续点击按钮,动画播放不完
if(MyAnimationUtils.isRunningAnimation()){
return;
}
int longTime = 0;
if(level2){
if(level3){
//如果三级菜单显示,点击home键,应该让其也消失
MyAnimationUtils.startRotateHindeAnimation(mRl_Level3);
level3 = false;
//进入这里,说明开始三级菜单为显示状态。延时增加
longTime = 200;
}
//显示,点击应该隐藏
MyAnimationUtils.startRotateHindeAnimation(mRl_Level2,longTime);
//修改状态值
level2 = false;
}else{
//隐藏状态,应该显示
MyAnimationUtils.startRotateShowAnimation(mRl_Level2);
//修改状态值
level2 = true;
} break;
case R.id.ib_menu:// 点击的是menu键
if(MyAnimationUtils.isRunningAnimation()){
//保证动画播放完毕再播放一次播放
return;
}
//判断三级菜单的状态
if(level3){
//显示,点击应该隐藏
MyAnimationUtils.startRotateHindeAnimation(mRl_Level3);
//修改状态值
level3 = false;
}else{
//隐藏状态,应该显示
MyAnimationUtils.startRotateShowAnimation(mRl_Level3);
//修改状态值
level3 = true;
}
break; default:
break;
} }
}; mIb_Home.setOnClickListener(listener);
mIb_Menu.setOnClickListener(listener); } //手机的menu键按下的时候调用事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(level1){
int longTime = 0;
//判断二级菜单是否显示
if(level2){
//判断三级菜单是否显示
if(level3){
//隐藏三级菜单
MyAnimationUtils.startRotateHindeAnimation(mRl_Level3);
level3 = false;
longTime = 200;//延时标记
}
//隐藏二级菜单
MyAnimationUtils.startRotateHindeAnimation(mRl_Level2,longTime);
level2 = false;
longTime += 200;
}
//一级菜单显示状态
//隐藏一级菜单
MyAnimationUtils.startRotateHindeAnimation(mRl_Level1,longTime);
level1 = false;
}else{
//一次显示
MyAnimationUtils.startRotateShowAnimation(mRl_Level1);
MyAnimationUtils.startRotateShowAnimation(mRl_Level2,200);
MyAnimationUtils.startRotateShowAnimation(mRl_Level3,400);
level1 = true;
level2 = true;
level3 = true;
}
// 交由父类去处理逻辑,自己不做处理
return super.onKeyDown(keyCode, event);
} /**
* 初始化界面
*/
private void initView() { mRl_Level1 = (RelativeLayout) findViewById(R.id.rl_level1);
mRl_Level2 = (RelativeLayout) findViewById(R.id.rl_level2);
mRl_Level3 = (RelativeLayout) findViewById(R.id.rl_level3); mIb_Home = (ImageButton) findViewById(R.id.ib_home);
mIb_Menu = (ImageButton) findViewById(R.id.ib_menu); }
}
好啦,赶快把代码复制到您的IDE中把效果跑起来吧!
欢迎关注本博客点击打开链接 http://blog.csdn.net/qq_32059827,每天花上5分钟,阅读一篇有趣的安卓小文哦。
Android简易实战教程--第二十三话《绚丽的菜单项》的更多相关文章
- Android简易实战教程--第二十七话《自定义View入门案例之开关按钮详细分析》
转载此博客请注明出处点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52444145 对于自定义view,可能是一个比较大的 ...
- Android简易实战教程--第二十话《通过广播接收者,对拨打电话外加ip号》
没睡着觉,起来更篇文章吧哈哈!首先祝贺李宗伟击败我丹,虽然我是支持我丹的,但是他也不容易哈哈,值得尊敬的人!切入正题:这一篇来介绍个自定义广播接收者. 通常我们在外拨电话的时候,一般为使用网络电话.如 ...
- Android简易实战教程--第十三话《短信备份和还原~三》
之前写过短信备份的小案例,哪里仅仅是虚拟了几条短信信息.本篇封装一个业务类,且直接通过内容提供者,访问本系统的短信信息,再提供对外接口.如果想要短信备份和短信还原,直接复制这段代码即可.对于您调用这个 ...
- Android简易实战教程--第二十九话《创建图片副本》
承接第二十八话加载大图片,本篇介绍如何创建一个图片的副本. 安卓中加载的原图是无法对其修改的,因为默认权限是只读的.但是通过创建副本,就可以对其做一些修改,绘制等了. 首先创建一个简单的布局.一个放原 ...
- Android简易实战教程--第二十六话《网络图片查看器在本地缓存》
本篇接第二十五话 点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52389856 上一篇已经把王略中的图片获取到了.生活中有这么 ...
- Android简易实战教程--第二话《两种进度条》
点击按钮模拟进度条下载进度,"下载"完成进度条消失. 代码如下: xml: <?xml version="1.0" encoding="utf- ...
- Android简易实战教程--第二十八话《加载大图片》
Android系统以ARGB表示每个像素,所以每个像素占用4个字节,很容易内存溢出.假设手机内存比较小,而要去加载一张像素很高的图片的时候,就会因为内存不足导致崩溃.这种异常是无法捕获的 内存不足并不 ...
- Android简易实战教程--第二十五话《网络图片查看器》
访问网络已经有了很成熟的框架.这一篇只是介绍一下HttpURLConnection的简单用法,以及里面的"注意点".这一篇可以复习或者学习HttpURLConnection.han ...
- Android简易实战教程--第二十四话《画画板》
今天完成一个画画板. 首先来个布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android ...
随机推荐
- [HNOI2008]遥远的行星
题目描述 直线上N颗行星,X=i处有行星i,行星J受到行星I的作用力,当且仅当i<=AJ.此时J受到作用力的大小为 Fi->j=Mi*Mj/(j-i) 其中A为很小的常量,故直观上说每颗行 ...
- ●POJ 1259 The Picnic
题链: http://poj.org/problem?id=1259 题解: 计算几何,凸包,DP 题意:给出N($N\leq100$)个点,求出最大的凸包使得凸包里面不存在点(边上可以有).输出最大 ...
- 计蒜客NOIP2017提高组模拟赛(三)day2-直线的交点
传送门 简单几何+逆序对 发现当两条直线甲乙与平板的交点在上面甲在较左的位置,那么下面甲在较右的位置就可以相交 然后把上面的位置排下序,下面离散化+树状数组即可 #include<cstdio& ...
- 51 nod 1515 明辨是非(并查集合并)
1515 明辨是非题目来源: 原创基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 给n组操作,每组操作形式为x y p. 当p为1时,如果第x变量和第y个变量可以 ...
- hdu 1130 How Many Trees?(Catalan数)
How Many Trees? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- bzoj3786星系探索 splay
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1314 Solved: 425[Submit][Status][Discuss ...
- Python中list的功能介绍
List的功能介绍 1. 列表的两种方法 1. 列表的内置方法 列表的相加 格式:x.__add__(y)等同于x+y 例如:list1 = [1,2,3] print(list1.__add__([ ...
- Mysql锁机制--读锁
Mysql 系列文章主页 =============== 1 准备数据 1.1 建表 1.1.1 建立 Employee表 DROP TABLE IF EXISTS employee; CREATE ...
- python学习之路网络编程篇(第四篇)
python学习之路网络编程篇(第四篇) 内容待补充
- HTTP与TCP的关系
一直比较想写TCP与HTTP之间的关系,HTTP报文是如何通过tcp发送的,HTTP报文形式内容如何. HTTP请求包含请求行,请求头,请求体 HTTP响应包含响应头,响应头,响应体 下面我准备通过J ...