转载本博客请注明出处:点击打开链接  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简易实战教程--第二十三话《绚丽的菜单项》的更多相关文章

  1. Android简易实战教程--第二十七话《自定义View入门案例之开关按钮详细分析》

    转载此博客请注明出处点击打开链接       http://blog.csdn.net/qq_32059827/article/details/52444145 对于自定义view,可能是一个比较大的 ...

  2. Android简易实战教程--第二十话《通过广播接收者,对拨打电话外加ip号》

    没睡着觉,起来更篇文章吧哈哈!首先祝贺李宗伟击败我丹,虽然我是支持我丹的,但是他也不容易哈哈,值得尊敬的人!切入正题:这一篇来介绍个自定义广播接收者. 通常我们在外拨电话的时候,一般为使用网络电话.如 ...

  3. Android简易实战教程--第十三话《短信备份和还原~三》

    之前写过短信备份的小案例,哪里仅仅是虚拟了几条短信信息.本篇封装一个业务类,且直接通过内容提供者,访问本系统的短信信息,再提供对外接口.如果想要短信备份和短信还原,直接复制这段代码即可.对于您调用这个 ...

  4. Android简易实战教程--第二十九话《创建图片副本》

    承接第二十八话加载大图片,本篇介绍如何创建一个图片的副本. 安卓中加载的原图是无法对其修改的,因为默认权限是只读的.但是通过创建副本,就可以对其做一些修改,绘制等了. 首先创建一个简单的布局.一个放原 ...

  5. Android简易实战教程--第二十六话《网络图片查看器在本地缓存》

    本篇接第二十五话  点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52389856 上一篇已经把王略中的图片获取到了.生活中有这么 ...

  6. Android简易实战教程--第二话《两种进度条》

    点击按钮模拟进度条下载进度,"下载"完成进度条消失. 代码如下: xml: <?xml version="1.0" encoding="utf- ...

  7. Android简易实战教程--第二十八话《加载大图片》

    Android系统以ARGB表示每个像素,所以每个像素占用4个字节,很容易内存溢出.假设手机内存比较小,而要去加载一张像素很高的图片的时候,就会因为内存不足导致崩溃.这种异常是无法捕获的 内存不足并不 ...

  8. Android简易实战教程--第二十五话《网络图片查看器》

    访问网络已经有了很成熟的框架.这一篇只是介绍一下HttpURLConnection的简单用法,以及里面的"注意点".这一篇可以复习或者学习HttpURLConnection.han ...

  9. Android简易实战教程--第二十四话《画画板》

    今天完成一个画画板. 首先来个布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android ...

随机推荐

  1. [HNOI 2002]营业额统计

    Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...

  2. [HZOI 2015]疯狂的机器人

    [题目描述] 现在在二维平面内原点上有一只机器人 他每次操作可以选择向右走,向左走,向下走,向上走和不走(每次如果走只能走一格) 但是由于本蒟蒻施展的大魔法,机器人不能走到横坐标是负数或者纵坐标是负数 ...

  3. 2015 多校联赛 ——HDU5353(构造)

    Each soda has some candies in their hand. And they want to make the number of candies the same by do ...

  4. hdu 5464(dp)

    题意: 给你n个数,要求选一些数(可以不选),把它们加起来,使得和恰好是p的倍数(0也是p的倍数),求方案数. - - 心好痛,又没想到动规 #include <stdio.h> #inc ...

  5. [BZOJ]2594 水管局长数据加强版(Wc2006)

    失踪人口回归. LCT一直是小C的弱项,特别是这种维护链的信息的,写挂了就会调代码调到心态爆炸. 不过还好这一次的模板练习没有出现太多的意外. Description SC省MY市有着庞大的地下水管网 ...

  6. udacity/CarND-Path-Planning-Project 工程详细配置过程——吐血整理

    本人原创,转载请注明地址 学习udacity/CarND-Path-Planning-Project 工程过程 1.首先登陆 jeremy-shannon/CarND-Path-Planning-Pr ...

  7. 使用Aes对称加密解密Web.Config数据库连接串

    现在很多公司开始为了保证数据库的安全性,通常会对Web.Config的数据库连接字符串进行加密.本文将介绍学习使用Aes加密解密数据库连接字符串.本文采用MySql数据库. AES概念简述 AES 是 ...

  8. Dapper.Contrib拓展及数据库生成实体

    1.关于Dapper.Contrib Dapper.Contrib是Dapper的一个拓展类库,Dapper是一个轻量级ORM框架,这个不了解的请自行收集资料,本文主要讲讲,数据库生成实体,并通过实体 ...

  9. 实现一个ordeeddict

    class MyOrderdict(): def __init__(self, mydict): self._cur = 0 self._mykeys = [] self._myvalues = [] ...

  10. log4j日志的基本使用方法(1)——概述、配置文件

    一.概述 Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式.日志信息的优先级从高到低有ERROR.WARN.INFO.DEBUG,分别用来指定这条日志信息的重 ...