Android编程自定义菜单实现方法详解

本文实例讲述了Android编程自定义菜单实现方法。分享给大家供大家参考,具体如下:

在android开发的过程中系统自带的菜单往往满足不了开发中的一些需求,比如说一排最多只能放置三个菜单,坐多只能放置6个,再多的话就会折叠起来,如果我们想再一排显示4个或5个菜单那么就要自己想办法处理。

这里我用布局的隐藏并加上动画来模拟菜单的效果。

要点:

1、隐藏和显示菜单,我使用了一个线性布局把菜单封装起来。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_alignParentBottom="true"
 android:background="@drawable/menubackground"
 android:layout_width="fill_parent"
 android:layout_height="144px"
 android:orientation="vertical"
 android:gravity="center"
 android:visibility="gone"
   android:id="@+id/lines">
   <LinearLayout android:orientation="horizontal"
   android:gravity="center"
   android:layout_width="fill_parent"
 android:layout_height="72px"
   >
 <ImageButton
   android:layout_marginLeft="8dip"
   android:id="@+id/menu_btn_index"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_index_selector"
   />
  <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_news_selector"
   android:id="@+id/menu_btn_news"
   />
  <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_lib_selector"
   android:id="@+id/menu_btn_lib"
   />
    <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_add_selector"
   android:id="@+id/menu_btn_add"
   />
 <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_set_selector"
   android:id="@+id/menu_btn_set"
   />
 </LinearLayout>
 <LinearLayout android:orientation="horizontal" android:gravity="center"
   android:layout_width="fill_parent"
   android:layout_height="72px">
 <ImageButton
   android:layout_marginLeft="8dip"
   android:id="@+id/menu_btn_index"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_index_selector"
   />
  <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_news_selector"
   android:id="@+id/menu_btn_news"
   />
  <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_lib_selector"
   android:id="@+id/menu_btn_lib"
   />
  <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_add_selector"
   android:id="@+id/menu_btn_add"
   />
 <ImageButton
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_quit_selector"
   android:id="@+id/menu_btn_quit"
   />
 </LinearLayout>
</LinearLayout>

2、模拟菜单的效果,增加动画,布局显示的时候增加一个渐渐底部生气的效果,隐藏的时候增加一个缓缓下落的效果,显示菜单动画文件:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <translate
    android:fromXDelta="0"
    android:toXDelta="0"
    android:fromYDelta="00"
    android:toYDelta="140"
    android:duration="200" />
</set>

隐藏菜单动画文件:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <translate
    android:fromXDelta="0"
    android:toXDelta="0"
    android:fromYDelta="140"
    android:toYDelta="00"
    android:duration="200" />
</set>

动画调用:

 /**
  * 显示菜单栏, 重新实现的Option menu.
  * */
 private void showAppMenu() {
   if (menuShowAnimation == null) {
     menuShowAnimation = AnimationUtils
         .loadAnimation(mContext, R.anim.menuhide);
   }
   myLayout.startAnimation(menuShowAnimation);
   myLayout.setVisibility(View.VISIBLE);
 }
 /**
  * 隐藏菜单栏, 重新实现的Option menu.
  * */
 private void hideAppMenu() {
   myLayout.setVisibility(View.GONE);
   if (menuHideAnimation == null)
     menuHideAnimation =AnimationUtils
         .loadAnimation(mContext, R.anim.menushow);
   myLayout.startAnimation(menuHideAnimation);
 }

3、控制菜单的隐藏和显示,需要重写三个方法public boolean onCreateOptionsMenu(Menu menu),
public boolean dispatchKeyEvent(KeyEvent event) 和public boolean dispatchTouchEvent(MotionEvent event)

@Override
  public boolean onCreateOptionsMenu(Menu menu) {
    if(mCustomMenu==null)
      mCustomMenu=new CustomMenu(CustomMenuActivity.this,CustomMenuActivity.this);
    mCustomMenu.CreateMenu();
    return false;
  }
  @Override
  public boolean dispatchKeyEvent(KeyEvent event) {
    if(mCustomMenu!=null)
      return mCustomMenu.dispatchKeyEvent(event,super.dispatchKeyEvent(event));
    return super.dispatchKeyEvent(event);
  }
  @Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    if(mCustomMenu!=null)
      return mCustomMenu.dispatchTouchEvent(event,super.dispatchTouchEvent(event));
    return super.dispatchTouchEvent(event);
  }

4、实现菜单点击时候被点击菜单状态的般变化,这里我使用了selector来实现,菜单我使用ImageButton将selector赋值给ImageButton 的background即可:

一个菜单项

<ImageButton
   android:layout_marginLeft="8dip"
   android:id="@+id/menu_btn_index"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/menu_index_selector"
   />

menu_index_selector 文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
   http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_window_focused="false"
  android:drawable="@drawable/menu_index" />
 <item android:state_pressed="true"
  android:drawable="@drawable/menu_index1" />
 <item android:state_focused="true"
  android:drawable="@drawable/menu_index1" />
 <item
   android:drawable="@drawable/menu_index" />
</selector>

5、页面的调用使用:<include>标签来进行引用:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <include layout="@layout/menu_layout"/>
 </RelativeLayout>

这样的话一个模拟的自定义菜单就基本完成了,菜单控制完整代码java类:

package com.demo.utils;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import com.demo.HelloWorld.R;
/**
 * @author Administrator
 *   xsl xushilin@kingtoneinfo.com
 * @version: 创建时间:2011-8-30 上午11:16:19
 * 说   明:
 * 修改历史:
 */
public class CustomMenu {
  private LinearLayout myLayout;
  private Context mContext;
  private Activity mActivity;
  private Animation menuShowAnimation = null;
  private Animation menuHideAnimation = null;
  private Resources res;
  public int screen_height;
  private ImageButton imgIndex,imgSet,imgNews,imgAdd,imgQuit,imgLib;
  public CustomMenu(Context context,Activity activity){
    mContext=context;
    mActivity=activity;
    res = mContext.getResources();
    screen_height = res.getDisplayMetrics().heightPixels;
    myLayout=(LinearLayout)activity.findViewById(R.id.lines);
    imgIndex=(ImageButton)activity.findViewById(R.id.menu_btn_index);
    imgSet=(ImageButton)activity.findViewById(R.id.menu_btn_set);
    imgNews=(ImageButton)activity.findViewById(R.id.menu_btn_news);
    imgAdd=(ImageButton)activity.findViewById(R.id.menu_btn_add);
    imgQuit=(ImageButton)activity.findViewById(R.id.menu_btn_quit);
    imgLib=(ImageButton)activity.findViewById(R.id.menu_btn_lib);
    //返回首页
    imgIndex.setOnClickListener(new OnClickListener(){
      public void onClick(View v) {
        //TODO do somthing
      }
    });
    //设置
    imgSet.setOnClickListener(new OnClickListener(){
      public void onClick(View v) {
        //TODO do somthing
      }
    });
    //查询
    imgNews.setOnClickListener(new OnClickListener(){
      public void onClick(View v) {
        //TODO do somthing
      }
    });
    //编辑
    imgAdd.setOnClickListener(new OnClickListener(){
      public void onClick(View v) {
        //TODO do somthing
      }
    });
    //退出系统
    imgQuit.setOnClickListener(new OnClickListener(){
      public void onClick(View v) {
        //TODO do somthing
      }
    });
    //素材库
    imgLib.setOnClickListener(new OnClickListener(){
      public void onClick(View v) {
        //TODO do somthing
      }
    });
  }
  public void CreateMenu(){
    if(myLayout.getVisibility()==View.GONE)
      showAppMenu();
      //myLayout.setVisibility(View.VISIBLE);
    else
      hideAppMenu();
      //myLayout.setVisibility(View.GONE);
  }
   /**
  * 显示菜单栏, 重新实现的Option menu.
  * */
 private void showAppMenu() {
   if (menuShowAnimation == null) {
     menuShowAnimation = AnimationUtils
         .loadAnimation(mContext, R.anim.menuhide);
   }
   myLayout.startAnimation(menuShowAnimation);
   myLayout.setVisibility(View.VISIBLE);
 }
 /**
  * 隐藏菜单栏, 重新实现的Option menu.
  * */
 private void hideAppMenu() {
   myLayout.setVisibility(View.GONE);
   if (menuHideAnimation == null)
     menuHideAnimation =AnimationUtils
         .loadAnimation(mContext, R.anim.menushow);
   myLayout.startAnimation(menuHideAnimation);
 }
 public boolean dispatchTouchEvent(MotionEvent event,boolean b) {
    if (myLayout.getVisibility() == View.VISIBLE) {
      int y = (int) event.getRawY();
      if (y < screen_height - myLayout.getHeight()) {
        hideAppMenu();
        return true;
      }
    }
    return b;
 }
 public boolean dispatchKeyEvent(KeyEvent event,boolean b) {
   int act = event.getAction();
   int code = event.getKeyCode();
   // app menu like option menu
   if (code == KeyEvent.KEYCODE_MENU){
     if (act == KeyEvent.ACTION_DOWN){
       if (myLayout.getVisibility() == View.VISIBLE) {
         hideAppMenu();
       } else {
         showAppMenu();
       }
       return true;
     }
   }else if (code == KeyEvent.KEYCODE_BACK){
     if (myLayout.getVisibility() == View.VISIBLE) {
       hideAppMenu();
       return true;
     }
   }
   return b;
 }
}

activity调用菜单完整代码:

package com.demo.ui;
import com.demo.HelloWorld.R;
import com.demo.utils.CustomMenu;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MotionEvent;
/**
 * @author XSL
 *   xsl xushilin@kingtoneinfo.com
 * @version: 创建时间:2011-8-30 上午11:13:14
 * 说   明:
 * 修改历史:
 */
public class CustomMenuActivity extends Activity {
  private CustomMenu mCustomMenu=null;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.custom_menu);
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    if(mCustomMenu==null)
      mCustomMenu=new CustomMenu(CustomMenuActivity.this,CustomMenuActivity.this);
    mCustomMenu.CreateMenu();
    return false;
  }
  @Override
  public boolean dispatchKeyEvent(KeyEvent event) {
    if(mCustomMenu!=null)
      return mCustomMenu.dispatchKeyEvent(event,super.dispatchKeyEvent(event));
    return super.dispatchKeyEvent(event);
  }
  @Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    if(mCustomMenu!=null)
      return mCustomMenu.dispatchTouchEvent(event,super.dispatchTouchEvent(event));
    return super.dispatchTouchEvent(event);
  }
}

实现的效果如下:

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android开发入门与进阶教程》、《Android布局layout技巧总结》、《Android视图View技巧总结》、《Android编程之activity操作技巧总结》、《Android操作json格式数据技巧总结》、《Android资源操作技巧汇总》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。

(0)

相关推荐

  • Android实现自定义滑动式抽屉效果菜单

    在Andoird使用Android自带的那些组件,像SlidingDrawer和DrawerLayout都是抽屉效果的菜单,但是在项目很多要实现的功能都收到Android这些自带组件的限制,导致很难完成项目的需求,自定义的组件,各方面都在自己的控制之下,从而根据需求做出调整.想要实现好的效果,基本上都的基于Android的OnTouch事件自己实现响应的功能. 首先,给大家先看一下整体的效果: 滑动的加速度效果都是有的,具体的体验,只能安装后才能查看. 接下来,看代码: 代码从MainActiv

  • Android编程实现自定义系统菜单背景的方法

    本文实例讲述了Android编程实现自定义系统菜单背景的方法.分享给大家供大家参考,具体如下: 不多说,上图,见代码. package lab.sodino.menutest; import android.content.Context; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.util.AttributeSet; import androi

  • Android自定义控件之仿优酷菜单

    去年的优酷HD版有过这样一种菜单,如下图: 应用打开之后,先是三个弧形的三级菜单,点击实体键menu之后,这三个菜单依次旋转退出,再点击实体键menu之后,一级菜单会旋转进入,点击一级菜单,二级菜单旋转进入,点击二级菜单的menu键,三级菜单旋转进入,再次点击二级菜单的旋转键,三级菜单又会旋转退出,这时再点击一级菜单,二级菜单退出,最后点击实体menu键,一级菜单退出. 总体来说实现这样的功能: (1)点击实体menu键时,如果界面上有菜单显示,不管有几个,全部依次退出,如果界面上没有菜单显示,

  • android自定义popupwindow仿微信右上角弹出菜单效果

    微信右上角的操作菜单看起来很好用,就照着仿了一下,不过是旧版微信的,手里刚好有一些旧版微信的资源图标,给大家分享一下. 不知道微信是用什么实现的,我使用popupwindow来实现,主要分为几块内容: 1.窗口布局文件:popwin_share.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com

  • Android实现自定义的卫星式菜单(弧形菜单)详解

    一.前言 Android 实现卫星式菜单也叫弧形菜单,主要要做的工作如下: 1.动画的处理 2.自定义ViewGroup来实现卫星式菜单View (1)自定义属性 a. 在attrs.xml中定义属性 b. 在布局中使用自定义属性 c. 在自定义View中读取布局文件中的自定义属性 (2)onMeasure 测量 child 即测量主按钮以及菜单项 (3)onLayout 布局 child 即布局主按钮以及菜单项 (4)设置主按钮的选择动画 a.为菜单项menuItem添加平移动画和旋转动画 b

  • Android使用自定义控件HorizontalScrollView打造史上最简单的侧滑菜单

    侧滑菜单在很多应用中都会见到,最近QQ5.0侧滑还玩了点花样~~对于侧滑菜单,一般大家都会自定义ViewGroup,然后隐藏菜单栏,当手指滑动时,通过Scroller或者不断的改变leftMargin等实现:多少都有点复杂,完成以后还需要对滑动冲突等进行处理~~今天给大家带来一个简单的实现,史上最简单有点夸张,但是的确是我目前遇到过的最简单的一种实现~~~ 1.原理分析 既然是侧滑,无非就是在巴掌大的屏幕,塞入大概两巴掌大的布局,需要滑动可以出现另一个,既然这样,大家为啥不考虑使用Android

  • Android自定义控件案例汇总2(自定义开关、下拉刷新、侧滑菜单)

    案例四 自定义开关: 功能介绍:本案例实现的功能是创建一个自定义的开关,可以自行决定开关的背景.当滑动开关时,开关的滑块可跟随手指移动.当手指松开后,滑块根据开关的状态,滑到最右边或者滑到最左边,同时保存开关的状态,将开关的状态回调给调用者.当然,上述功能系统给定的switch控件也可以实现. 实现步骤: 1. 写一个类继承view,重写两个参数的构造方法.在构造方法中指定工作空间,通过attrs.getAttributeResourceValue方法将java代码中的属性值和xml中的属性值联

  • android 自定义Android菜单背景的代码

    复制代码 代码如下: public class MenuEx extends Activity { private static final String TAG = "android123"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public b

  • Android自定义ViewGroup实现带箭头的圆角矩形菜单

    本文和大家一起做一个带箭头的圆角矩形菜单,大概长下面这个样子: 要求顶上的箭头要对准菜单锚点,菜单项按压反色,菜单背景色和按压色可配置. 最简单的做法就是让UX给个三角形的图片往上一贴,但是转念一想这样是不是太low了点,而且不同分辨率也不太好适配,干脆自定义一个ViewGroup吧! 自定义ViewGroup其实很简单,基本都是按一定的套路来的. 一.定义一个attrs.xml 就是声明一下你的这个自定义View有哪些可配置的属性,将来使用的时候可以自由配置.这里声明了7个属性,分别是:箭头宽

  • Android开发技巧之我的菜单我做主(自定义菜单)

    Android SDK本身提供了一种默认创建菜单的机制.但通过这种机制创建的菜单虽然从功能上很完备,但在界面效果上实在是有点"土".对于一个拥有绚丽界面的程序配上一个有点"土"的菜单,会使用户感觉很怪,甚至会使绚丽的界面大打折扣.实际上,对于如此灵活和强大的Android系统,修改菜单的样式只是小菜一碟.为程序加入漂亮菜单的方法很多.在本节先介绍一种比较常用的方法,就是通过onKeyDown事件方法和PopupWindow实现自定义的菜单.至于通过这种技术能否设计出

  • Android自定义控件简单实现侧滑菜单效果

    侧滑菜单在很多应用中都会见到,最近QQ5.0侧滑还玩了点花样~~对于侧滑菜单,一般大家都会自定义ViewGroup,然后隐藏菜单栏,当手指滑动时,通过Scroller或者不断的改变leftMargin等实现:多少都有点复杂,完成以后还需要对滑动冲突等进行处理~~今天给大家带来一个简单的实现,史上最简单有点夸张,但是的确是我目前遇到过的最简单的一种实现~~~ 1.原理分析 既然是侧滑,无非就是在巴掌大的屏幕,塞入大概两巴掌大的布局,需要滑动可以出现另一个,既然这样,大家为啥不考虑使用Android

  • Android自定义VIew实现卫星菜单效果浅析

     一 概述: 最近一直致力于Android自定义VIew的学习,主要在看<android群英传>,还有CSDN博客鸿洋大神和wing大神的一些文章,写的很详细,自己心血来潮,学着写了个实现了类似卫星效果的一个自定义的View,分享到博客上,望各位指点一二.写的比较粗糙,见谅.(因为是在Linux系统下写的,效果图我直接用手机拍的,难看,大家讲究下就看个效果,勿喷). 先来看个效果图,有点不忍直视: 自定义VIew准备: (1)创建继承自View的类; (2)重写构造函数; (3)定义属性. (

  • Android自定义view实现圆形与半圆形菜单

    前不久看到鸿洋大大的圆形菜单,就想开始模仿,因为实在是太酷了,然后自己根据别人(zw哥)给我讲的一些思路.一些分析,就开始改造自己的圆形菜单了. 文章结构:1.功能介绍以及展示:2.部分代码讲解:3.大致可以实现的UI效果展示讲解.4.源码附送. 一.功能介绍以及展示 第一个展示是本控件的原样.但是我们可以使用很多技巧去达到我们的商业UI效果嘛. 这里给出的是本博客作品demo的展示图以及第三点的联动展示,可见是一圆型菜单,相较于鸿洋大大的那个圆形菜单多了一些需求: 1.到时候展示只需要半圆的转

随机推荐