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 ...
随机推荐
- HDU 5909 Tree Cutting
传送门 题意: 有一棵n个点的无根树,节点依次编号为1到n,其中节点i的权值为vi, 定义一棵树的价值为它所有点的权值的异或和. 现在对于每个[0,m)的整数k,请统计有多少T的非空连通子树的价值等于 ...
- 绝世好题bzoj4300
Description 给定一个长度为n的数列ai,求ai的子序列bi的最长长度,满足bi&bi-1!=0(2<=i<=len). Input 输入文件共2行. 第一行包括一个整数 ...
- bzoj 4545: DQS的trie
Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符.并且,它拥有极强的生长力:某个i时刻 ...
- 【Codeforces Round 418】An impassioned circulation of affection DP
C. An impassioned circulation of affection ...
- poj2975 Nim 胜利的方案数
Nim Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5545 Accepted: 2597 Description N ...
- [Noi2016]网格
来自FallDream的博客,未经允许,请勿转载,谢谢. 跳蚤国王和蛐蛐国王在玩一个游戏. 他们在一个 n 行 m 列的网格上排兵布阵.其中的 c 个格子中 (0≤c≤nm),每个格子有一只蛐蛐, ...
- WPF 实现换肤功能
将所有控件的基本样式汇集到一个资源字典中,构成界面的基本样式文件,然后进行不同颜色皮肤的定制. 即在新的皮肤资源字典文件中引入基本样式文件,然后使用资源继承,并且只设置控件的颜色属性等,形成一个皮肤文 ...
- Windows转Linux总结(附带常用Linux命令-LinuxMint)
这是我在Linux系统下写的第一篇博客,花了一周的时间从Windows系统转到Linux并且可以完成日常操作,能在Linux系统下完成开发,运用各种开发工具,写各种语言小程序和JavaEE. 经过这一 ...
- 关于一些基础的Java问题的解答(六)
26. ThreadPool用法与优势 ThreadPool即线程池,它是JDK1.5引入的Concurrent包中用于处理并发编程的工具.使用线程池有如下好处: 降低资源消耗:通过重复利用已创建的线 ...
- Java8 按照类属性去重
测试po package com.shiwulian.test.po; public class Person {private String id;private String name;priva ...