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 ...
随机推荐
- [自用]数论和组合计数类数学相关(定理&证明&板子)
0 写在前面 本文受 NaVi_Awson 的启发,甚至一些地方直接引用,在此说明. 1 数论 1.0 gcd 1.0.0 gcd $gcd(a,b) = gcd(b,a\;mod\;b)$ 证明:设 ...
- [ZJOI 2006]物流运输
Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...
- 计蒜客NOIP模拟赛(2) D2T3 银河战舰
[问题描述] 瑞奥和玛德利德是非常好的朋友.瑞奥平时的爱好是吹牛,玛德利德的爱好是戳穿瑞奥吹的牛. 这天瑞奥和玛德利德来到了宇宙空间站,瑞奥向玛德利德炫耀这个空间站里所有的银河战舰都是自己 ...
- TopCoder SRM 561 Div 1 - Problem 1000 Orienteering
传送门:https://284914869.github.io/AEoj/561.html 题目简述: 题外话: 刚开始看题没看到|C|<=300.以为|C|^2能做,码了好久,但始终解决不了一 ...
- [UOJ UNR#1]奇怪的线段树
来自FallDream的博客,未经允许,请勿转载, 谢谢. 原题可以到UOJ看,传送门 如果存在一个点是白的,却有儿子是黑的,显然无解. 不然的话,只要所有黑色的“黑叶子”节点,即没有黑色的儿子的节点 ...
- HDU5339——Untitled
Problem Description There is an integer a and n integers b1,…,bn. After selecting some numbers from ...
- 关于快速沃尔什变换(FWT)的一点学习和思考
最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...
- bzoj 3673&3674: 可持久化并查集 by zky
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- 本地缓存,Redis缓存,数据库DB查询(结合代码分析)
问题背景 为什么要使用缓存?本地缓存/Redis缓存/数据库查询优先级? 一.为什么要使用缓存 原因:CPU的速度远远高于磁盘IO的速度问题:很多信息存在数据库当中的,每次查询数据库就是一次IO操作所 ...
- C语言预备作业
一.关于师生关系 第一种:我认为师生关系不是仅仅的餐馆与食客的关系,因为食客可以给餐馆评分,也可以选择是否继续在这里吃,但是学生却不可以选择老师,因为老师是传授知识的,无法由自己来选择.而学生是需要完 ...