使用PopupWindow实现全局自定义menu

工程中需要做一个较负责并比较美观的menu菜单,使用Android自带的menu是达不到设计要求的效果的,经过上网搜索,决定使用PopupWindow来实现自定义menu。


PopupWindow在android.widget包下,弹出窗口的形式展示。官方文档对该控件的描述是:“一个弹出窗口控件,可以用来显示任意视图(View),而且会浮动在当前 活动(activity)的顶部”。PopupWindow可以让我们实现多种自定义控件,例如:menu、alertdialog等弹窗似的View。


使用PopupWindow来做自定义menu,往PopupWindow增加一个子View,子View的布局就是menu的布局。

出现和退出的动画:可以给PopUpWindow或它的子view添加。

下面边贴代码边讲解具体实现


自定义menu类文件:该文件定义了menu的布局,popupwindow的属性,及控件响应事件。

public class BottomMenu  extends PopupWindow {

	private Context context;
	private View bottom_menu;
	private ImageButton menuButton1,menuButton2,menuButton3,menuButton4,menuButton9,menuButton0;
	private View parent;
	

	public BottomMenu(Context _context,View _parent,Activity activity)  {
		super(_context);		
		this.context = _context;
		this.parent = _parent;
		LayoutInflater mInflate = LayoutInflater.from(context);
		bottom_menu = mInflate.inflate(R.layout.menu_layout, null);		
		bottom_menu.setFocusableInTouchMode(true);
		bottom_menu.setOnKeyListener(new OnKeyListener() {
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				// TODO Auto-generated method stub
				if ((keyCode == KeyEvent.KEYCODE_MENU)&&(isShowing())) {
					dismiss();
					
				}else if((keyCode == KeyEvent.KEYCODE_BACK)&&(isShowing())) {
					dismiss();
				}
				
				return false;
			}
		});
		setContentView(bottom_menu);
		setWidth(LayoutParams.FILL_PARENT);
		setHeight(LayoutParams.WRAP_CONTENT);
		setBackgroundDrawable(null);
		setFocusable(true);
		setAnimationStyle(R.style.PopupAnimation);		
		
		menuButton1=(ImageButton) bottom_menu.findViewById(R.id.menuButton1);
		menuButton2=(ImageButton) bottom_menu.findViewById(R.id.menuButton2);
		menuButton3=(ImageButton) bottom_menu.findViewById(R.id.menuButton3);
		menuButton4=(ImageButton) bottom_menu.findViewById(R.id.menuButton4);
		menuButton9=(ImageButton) bottom_menu.findViewById(R.id.menuButton9);
		menuButton0=(ImageButton) bottom_menu.findViewById(R.id.menuButton0);
		
		MyListener mListener=new MyListener(context,activity);
		menuButton1.setOnClickListener(mListener);
		menuButton2.setOnClickListener(mListener);
		menuButton3.setOnClickListener(mListener);
		menuButton4.setOnClickListener(mListener);
		menuButton9.setOnClickListener(mListener);
		menuButton0.setOnClickListener(mListener);
		update();
		
	}

	public void setMenuEvent() {
		if ((this != null) && (!this.isShowing())) {
			Log.i("menu", "menu show");
			this.showAtLocation(parent, Gravity.BOTTOM, 0, 0);
			
		}
	}
	
	public void finishMenuEvent(){
		if ((this != null)&&(this.isShowing())) {
			dismiss();
		}
	}	
			
}


可以看到,在构造函数里,对布局和一些属性都进行了设置,下面的setMenuEvent()函数实现menu显示,finishMenuEvent()函数实现menu消失。

注意:

bottom_menu.setOnKeyListener(new OnKeyListener() 这个函数实现了对menu键和return键的响应,必须添加,同时
bottom_menu.setFocusableInTouchMode(true)也必须有,不然不会响应。

 

这里为了响应menu中的点击事件我在menu的类中重写了一个listener。

 class MyListener implements OnClickListener{
	 private Context context;
	 private Activity activity;
	 
	 public MyListener(Context _context,Activity _activity){
			super();
			this.context=_context;
			this.activity=_activity;
		}
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		int layoutId = v.getId();
		Intent intent = new Intent();
		switch (layoutId) {
		case R.id.menuButton1:
			Log.i("menu", "menu botton 1");
			Toast.makeText(context, "add menu 1", Toast.LENGTH_SHORT).show();			
			break;
		case R.id.menuButton2:
			Log.i("menu", "menu botton 2");
			Toast.makeText(context, "add menu 2", Toast.LENGTH_SHORT).show();
			break;
		case R.id.menuButton3:
			Log.i("menu", "menu botton 3");
			Toast.makeText(context, "add menu 3", Toast.LENGTH_SHORT).show();
			break;
		case R.id.menuButton4:
			Log.i("menu", "menu botton 4");
			Toast.makeText(context, "add menu 4", Toast.LENGTH_SHORT).show();
			break;
		
		case R.id.menuButton9:
			Log.i("menu", "menu botton setting");
			Toast.makeText(context, "add menu setting", Toast.LENGTH_SHORT).show();
			break;
		case R.id.menuButton0:
			Log.i("menu", "menu botton exit");
			activity.finish();
			break;
		}
	
	} 
	 
 }


接下来在要实现menu的Activity里面加入如下几段代码

bottomMenu=new BottomMenu(getBaseContext(), findViewById(R.id.linearLayout), this);
这段代码是创建menu,其中三个参数分别是context,父layout,Activity。

@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add("menu");
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onMenuOpened(int featureId, Menu menu) {
		bottomMenu.setMenuEvent();
		return false;
		
	}	
	@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		// TODO Auto-generated method stub
		Log.v("Tinker", "test");
		return super.dispatchKeyEvent(event);
	}

可以看出以上代码其实是Android原生menu的实现形式,其实是进行了拦截,这里必须有一个 menu.add()


protected void onStop() {  
        super.onStop();  
        bottomMenu.finishMenuEvent();   
    }
以上,控制Activity进入休眠时使menu消失,这个函数是为了以防万一,并不一定是必要的。


XML布局的代码这里不再详述,下面的demo里有。

这里简要介绍下弹出和消失的动画效果。

第一段代码中有一行是设置动画效果的。

setAnimationStyle(R.style.PopupAnimation);

在style中:

<style name="PopupAnimation" parent="android:Animation"> 
        <item name="android:windowEnterAnimation">@anim/menu_in</item>  
        <item name="android:windowExitAnimation">@anim/menu_out</item>   
    </style>


menu_in.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">    
    <translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="200" />    
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="500" />    
</set>

第一行设置弹出的快慢

第二项设置淡入淡出的快慢


demo下载:BottomMenuDemo















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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值