二、实现要点:(1)屏蔽系统弹出的菜单:1、首先创建至少一个系统的菜单选项

@Override

public boolean onCreateOptionsMenu(Menu menu) {

menu.add("menu");

return super.onCreateOptionsMenu(menu);

}

2、在onMenuOpened方法里显示自己的菜单视图,并返回FALSE。

@Override

public boolean onMenuOpened(int featureId, Menu menu) {

myMenu.showAtLocation(findViewById(R.id.layout), Gravity.BOTTOM, 0,0);

return false; // true--显示系统自带菜单;false--不显示。

}

(2)点击菜单栏,切换菜单视图时,只要重新设置当前的适配器对象就可以。

gv_body.setAdapter(bodyAdapter[arg2]); //改变选项视图

(3)继承PopupWindow,重写一个类实现弹出对话框,主要是为了更好更简便实现弹出菜单的样式和事件响应等等。

public class MyDefinedMenu extends PopupWindow { 。。。}

三、 具体代码如下:(1)布局:

android:id="@+id/layout"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

(2)程序代码1、主类:MyMenu

package com.myandroid.test;

import java.util.ArrayList;

import java.util.List;

import android.app.Activity;

import android.os.Bundle;

import android.view.Gravity;

import android.view.Menu;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.Toast;

public class MyMenu extends Activity {

private List titles; //标题栏

private List> item_names; //选项名称

private List> item_images; //选项图标

private MyDefinedMenu myMenu; //弹出菜单

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//弹出菜单标题栏

titles = addItems(new String[]{"菜单一", "菜单二", "菜单三"});

//选项图标

item_images = new ArrayList>();

item_images.add(addItems(new Integer[]{R.drawable.bag,

R.drawable.bluetooth, R.drawable.earth, R.drawable.email}));

item_images.add(addItems(new Integer[]{R.drawable.map,

R.drawable.news, R.drawable.reader, R.drawable.sound, R.drawable.tape}));

item_images.add( addItems(new Integer[]{R.drawable.telephone,

R.drawable.bluetooth, R.drawable.earth, R.drawable.email}));

//选项名称

item_names = new ArrayList>();

item_names.add(addItems(new String[]{"购物", "蓝牙", "游览器", "邮件"}));

item_names.add(addItems(new String[]{"地图", "新闻", "阅读器", "音箱", "录音"}));

item_names.add(addItems(new String[]{"电话", "蓝牙", "阅读器", "邮箱"}));

//创建弹出菜单对象

myMenu = new MyDefinedMenu(this, titles, item_names,

item_images, new ItemClickEvent());

}

/**

* 转换为List

* @param values

* @return

*/

private List addItems(String[] values) {

List list = new ArrayList();

for (String var : values) {

list.add(var);

}

return list;

}

/**

* 转换为List

* @param values

* @return

*/

private List addItems(Integer[] values) {

List list = new ArrayList();

for (Integer var : values) {

list.add(var);

}

return list;

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

menu.add("menu");

return super.onCreateOptionsMenu(menu);

}

@Override

public boolean onMenuOpened(int featureId, Menu menu) {

myMenu.showAtLocation(findViewById(R.id.layout), Gravity.BOTTOM, 0,0);

return false; // true--显示系统自带菜单;false--不显示。

}

/**

* 菜单选项点击事件

* @author Kobi

*

*/

class ItemClickEvent implements OnItemClickListener {

@Override

public void onItemClick(AdapterView> arg0, View arg1, int arg2,

long arg3) {

//显示点击的是哪个菜单哪个选项。

Toast.makeText(MyMenu.this, "Menu: " +

titles.get(myMenu.getTitleIndex()) +

" Item: " + item_names.get(myMenu.getTitleIndex()).get(arg2),

Toast.LENGTH_SHORT).show();

myMenu.dismiss(); //菜单消失

}

}

}

2、弹出菜单类:MyDefinedMenu、

package com.myandroid.test;

import java.util.List;

import com.myandroid.test.MyMenu.ItemClickEvent;

import android.content.Context;

import android.graphics.Color;

import android.util.Log;

import android.view.View;

import android.view.ViewGroup.LayoutParams;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.GridView;

import android.widget.LinearLayout;

import android.widget.PopupWindow;

public class MyDefinedMenu extends PopupWindow {

private LinearLayout layout; //总的布局

private GridView gv_title;  //菜单栏

private GridView gv_body;  //选项视图

private BodyAdatper[] bodyAdapter; //选项适配器

private TitleAdatper titleAdapter; //标题适配器

private Context context;   //上下文

private int titleIndex;    //菜单序号

public MyDefinedMenu(Context context, List titles,

List> item_names, List> item_images,

ItemClickEvent itemClickEvent) {

super(context);

this.context = context;

//布局框架

layout = new LinearLayout(context);

layout.setOrientation(LinearLayout.VERTICAL);

layout.setLayoutParams(new LayoutParams(

LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

//菜单栏

titleIndex = 0;

gv_title = new GridView(context);

titleAdapter = new TitleAdatper(context, titles);

gv_title.setAdapter(titleAdapter);

gv_title.setLayoutParams(new LayoutParams(

LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

gv_title.setNumColumns(titles.size()); //菜单个数

gv_title.setBackgroundColor(Color.WHITE);

//选项视图

bodyAdapter = new BodyAdatper[item_names.size()]; //各个视图适配器

for (int i = 0; i < item_names.size(); i++) {

bodyAdapter[i] = new BodyAdatper(context, item_names.get(i), item_images.get(i));

}

gv_body = new GridView(context);

gv_body.setNumColumns(4); //每行显示4个选项

gv_body.setBackgroundColor(Color.TRANSPARENT);

gv_body.setAdapter(bodyAdapter[0]); //设置适配器

//菜单项切换

gv_title.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView> arg0, View arg1, int arg2,

long arg3) {

titleIndex = arg2; //记录当前选中菜单项序号

titleAdapter.setFocus(arg2);

gv_body.setAdapter(bodyAdapter[arg2]); //改变选项视图

}

});

//设置选项点击事件

gv_body.setOnItemClickListener(itemClickEvent);

//添加标题栏和选项

layout.addView(gv_title);

layout.addView(gv_body);

// 添加菜单视图

this.setContentView(layout);

this.setWidth(LayoutParams.FILL_PARENT);

this.setHeight(LayoutParams.WRAP_CONTENT);

this.setFocusable(true);// menu菜单获得焦点 如果没有获得焦点menu菜单中的控件事件无法响应

}

/**

* 获取当前选中菜单项

* @return 菜单项序号

*/

public int getTitleIndex() {

return titleIndex;

}

}

3、菜单栏适配器:TitleAdatper

package com.myandroid.test;

import java.util.List;

import android.content.Context;

import android.graphics.Color;

import android.view.Gravity;

import android.view.View;

import android.view.ViewGroup;

import android.view.ViewGroup.LayoutParams;

import android.widget.BaseAdapter;

import android.widget.GridView;

import android.widget.TextView;

public class TitleAdatper extends BaseAdapter {

private List titles;

private Context context;

private final TextView[] tv_titels;

public TitleAdatper(Context context, List titles) {

this.context = context;

this.titles = titles;

tv_titels = new TextView[titles.size()];

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return titles.size();

}

@Override

public Object getItem(int position) {

// TODO Auto-generated method stub

return position;

}

@Override

public long getItemId(int position) {

// TODO Auto-generated method stub

return position;

}

/**

* 选中后,改变菜单颜色。

* @param position

*/

public void setFocus(int position) {

for (int i = 0; i < titles.size(); i++) {

tv_titels[i].setBackgroundColor(Color.WHITE);

}

tv_titels[position].setBackgroundColor(Color.BLUE);

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

//菜单栏文字项

tv_titels[position] = new TextView(context);

tv_titels[position].setGravity(Gravity.CENTER);

tv_titels[position].setText(titles.get(position));

tv_titels[position].setTextSize(18);

tv_titels[position].setLayoutParams(new GridView.LayoutParams(

LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

return tv_titels[position];

}

}

4、菜单项视图适配器:BodyAdatper

package com.myandroid.test;

import java.util.List;

import android.content.Context;

import android.view.Gravity;

import android.view.View;

import android.view.ViewGroup;

import android.view.ViewGroup.LayoutParams;

import android.widget.BaseAdapter;

import android.widget.GridView;

import android.widget.ImageView;

import android.widget.LinearLayout;

import android.widget.TextView;

public class BodyAdatper extends BaseAdapter {

private List item_names;

private List item_images;

private Context context;

public BodyAdatper(Context context, List item_names,

List item_images) {

this.context = context;

this.item_names = item_names;

this.item_images = item_images;

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return item_images.size();

}

@Override

public Object getItem(int position) {

// TODO Auto-generated method stub

return position;

}

@Override

public long getItemId(int position) {

// TODO Auto-generated method stub

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

//总布局

LinearLayout layout = new LinearLayout(context);

layout.setOrientation(LinearLayout.VERTICAL);

layout.setGravity(Gravity.CENTER);

//选项名称

TextView tv_item = new TextView(context);

tv_item.setGravity(Gravity.CENTER);

tv_item.setLayoutParams(new GridView.LayoutParams(

LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

tv_item.setText(item_names.get(position));

//选项图表

ImageView img_item = new ImageView(context);

img_item.setLayoutParams(new LayoutParams(50, 50));

img_item.setImageResource(item_images.get(position));

//添加选项图标和名字

layout.addView(img_item);

layout.addView(tv_item);

return layout;

}

}

这里是用PopupWindow实现,当然也可以用AlertDialog或者其他自定义对话框等等,也可以改写Menu,还可以用Tab实现。实现的方法很多,但原理是相同的,例如用两个GridView,一个作为菜单栏,一个作为菜单项视图。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐