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

作者:蓝之风 时间:2022-08-25 18:16:08 

本文实例讲述了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程序设计有所帮助。

标签:Android,自定义,菜单
0
投稿

猜你喜欢

  • WinForm项目开发中Excel用法实例解析

    2022-07-11 10:23:03
  • java(jdk)环境变量配置(XP、win7、win8)图文教程详解

    2021-11-01 15:06:48
  • c# 如何实现图片压缩

    2022-02-10 00:46:31
  • Java 设计模式原则之迪米特法则详解

    2021-11-17 19:34:32
  • servlet异步请求的实现

    2023-07-14 17:11:38
  • Java实现线程安全单例模式的五种方式的示例代码

    2023-09-26 16:41:23
  • java学习之利用TCP实现的简单聊天示例代码

    2021-07-13 00:43:18
  • 浅析java修饰符访问权限(动力节点Java学院整理)

    2023-07-13 18:07:34
  • 每日六道java新手入门面试题,通往自由的道路--多线程

    2022-12-13 16:04:07
  • Java设计模式之装饰者模式详解

    2021-08-16 03:00:17
  • Java反射机制的实现详解

    2023-08-21 09:33:00
  • c#在WebAPI使用Session的方法

    2023-07-07 23:20:10
  • Java内存溢出实现原因及解决方案

    2022-10-19 09:07:42
  • Spring Boot环境下Mybatis Plus的快速应用操作

    2023-04-08 13:27:33
  • Java获取接口所有实现类的方式详解

    2022-06-11 14:44:27
  • C#设计模式实现之生成器模式和责任链模式

    2023-12-19 21:57:51
  • 一步步教你把SpringBoot项目打包成Docker镜像

    2022-01-10 12:21:02
  • C#开发windows服务实现自动从FTP服务器下载文件

    2022-08-26 04:11:41
  • Java实战之用Swing实现通讯录管理系统

    2021-08-15 08:24:09
  • C#快速排序算法实例分析

    2023-06-17 00:30:00
  • asp之家 软件编程 m.aspxhome.com