Android之用PopupWindow实现弹出菜单

转载:http://blog.csdn.net/kkfdsa132/article/details/6403404

 在使用UC-WebBrowser时,你会发现它的弹出菜单跟系统自带的菜单不一样。它实现更多菜单选项的显示和分栏。其实,它的本身是PopupWindow或者是AlertDialog对话框,在里面添加两个GridView控件,一个是菜单标题栏,一个是菜单选项。菜单选项视图的切换可以通过适配器的变换,轻松地实现。该实例下载路径:http://download.csdn.net/source/3275759

一、运行截图:


 二、实现要点:

        (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)布局:

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

(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<String> titles;	//标题栏
	private List<List<String>> item_names;	//选项名称
	private List<List<Integer>> 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<List<Integer>>();
        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<List<String>>();
        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<String>
     * @param values
     * @return
     */
    private List<String> addItems(String[] values) {
    	
    	List<String> list = new ArrayList<String>();
    	for (String var : values) {
			list.add(var);
		}
    	
    	return list;
    }
    
    /**
     * 转换为List<Integer>
     * @param values
     * @return
     */
    private List<Integer> addItems(Integer[] values) {
    	
    	List<Integer> list = new ArrayList<Integer>();
    	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<String> titles, 
			List<List<String>> item_names, List<List<Integer>> 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<String> titles;
	private Context context;
	private final TextView[] tv_titels;
	
	
	public TitleAdatper(Context context, List<String> 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<String> item_names;
	private List<Integer> item_images;
	private Context context;
	
	
	public BodyAdatper(Context context, List<String> item_names,
			List<Integer> 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,一个作为菜单栏,一个作为菜单项视图。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值