Menu键控制PopupMenu的相关bug及其避免方法

本文讨论了使用Menu键打开的PopupMenu在Android中出现的潜在问题,并提供了相关解决方案。当点击Menu键时,PopupMenu通常从底部弹出,如图1-1所示。为实现这一效果,开发者需正确调用Activity接口并配置xml菜单资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.通过menu键控制的菜单从下弹出,如图1-1所示:核心代码是调用Activity的接口以及xml文件的menu

public boolean onCreateOptionsMenu(Menu menu){
	getMenuInflater().inflate(R.menu.main, menu);
	return true;
}

public boolean onMenuItemSelected(intfeatureId, MenuItem item){
	witch(item.getItemId()) {
		case Item.ID1:
			//do something
			break;
		case Item.ID2:
			//do something
			break;
			//......
		default:
			break;
	}
	return super.onMenuItemSelected(featureId, item);
}



2.通过屏幕上某个按钮调用下拉框式的popupmenu,如图1-2所示:(下图使用的是自定义的actionbar,不能使用menu键来控制这个的Popupmenu。如果是系统默认的actionbar则可以通过menu键直接控制一个默认样式的下拉式menu)
故该图中样式的menu核心代码是使用Popupmenu类来实现。
btn_popUp = (Button) findViewById(R.id.btn_popUp);
btn_popUp.setOnClickListener(newOnClickListener(){
	public void onClick(View v) {
		PopupMenu popup = newPopupMenu(MenuActivity2.this, v);
		popup.getMenuInflater().inflate(R.menu.menu_activity2);
		popup.getMenu());
		popup.setOnMenuItemClickListener(MenuActivity2.this);    //设置点击菜单选项事件
		popup.show();//显示菜单
	}
});




3.那么问题来了:如果想用menu键实现控屏幕上某个按钮的下拉框式的popupmenu该怎么办呢?首先可以肯定的是调用了onKeyDown()。那如下代码就可以了?
public boolean onKeyDown(int keyCode, KeyEvent event) {
	if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) {
		if (mEnableMenu) {
			if (!mMenuExist) {
				createMenu(mSettingButton);
			}
			popup.show();//显示菜单
		}
	}
	return super.onKeyDown(keyCode, event);
}




实际尝试后并不行,为什么?因为在调用popup.show()的时候android居然会主动调用onKeyUp()事件,以至于当真正调用onKeyUp()的时候,同时执行了popup. Dismiss();此时产生bug,即手指按下,弹出popupmenu,手指抬起时popupmenu消失。
那么应该怎么做呢?应该使用PopupWindows类来自定义Popupmenu事件。核心代码如下:
public void createMenu(ImageButton settingButton) {
	mPopupMenu = new PopupWindow(getLayoutInflater().inflate(R.layout.listview_menu, null));
	menuList = (ListView) mPopupMenu.getContentView().findViewById(R.id.listview_menu);

	final ArrayList<String> menuStr = new ArrayList<String>();
	menuStr.add(mContext.getResources().getString(R.string.abc));
	menuStr.add(mContext.getResources().getString(R.string.bca));
	ArrayAdapter<String> menuAdapter = new ArrayAdapter<String>(mContext, R.layout.popupmenu_item,menuStr);
	menuList.setAdapter(menuAdapter);
	menuList.setOnItemClickListener(new OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
			//do something
		}
	});
	mPopupMenu.setWidth(LayoutParams.WRAP_CONTENT);
	mPopupMenu.setHeight(LayoutParams.WRAP_CONTENT);
	mPopupMenu.setFocusable(true);
	//只有设置了背景之后,点击popupwindows之外的空白处,popupwindows消失,否则绝不消失,试过其他正规非正规的手段。
	//如果不设置背景,那么即便监听back键事件主动调用dimission也不会消失。
	mPopupMenu.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.pupopmenu_bg));
	mPopupMenu.setOutsideTouchable(true);
	mMenuExist = true;
	//焦点在popupmenu中,此时若点击menu键无响应,故需要设置监听响应menu.disiss()事件
	menuList.setOnKeyListener(new OnKeyListener() {
		@Override
		public boolean onKey(View v, int keyCode, KeyEvent event) {
			// TODO Auto-generated method stub
			if (keyCode == KeyEvent.KEYCODE_MENU&& event.getAction() == KeyEvent.ACTION_DOWN) {
				mPopupMenu.dismiss();
			}
			return true;
		}
	});
}

Android中,PopupMenu是一种常用的弹出菜单,通常用于提供一些附加操作供用户选择。要控制PopupMenu的显示,你可以按照以下步骤操作: 1. **创建PopupMenu实例**: 首先,你需要创建一个`PopupMenu`对象,并指定其将显示的位置。这通常通过一个`Context`对象(如Activity、Fragment等)以及一个Point对象(表示屏幕坐标)来完成。 ```java PopupMenu popup = new PopupMenu(context, view); ``` 这里的`context`是你当前的活动环境,`view`是你想要从其位置弹出菜单的视图。 2. **添加选项**: 添加到PopupMenu的选项通常是通过`add()`方法,可以传入菜单项的文字和对应的监听器。例如: ```java popup.add(MenuInflater.inflate(R.menu.popup_menu_resource_id, menu), index, itemId); ``` 这里,`R.menu.popup_menu_resource_id`是一个资源ID,指向XML布局文件中定义的菜单项列表。 3. **设置显示与关闭**: 调用`show()`方法来实际显示菜单: ```java popup.show(); ``` 当用户选择了一个菜单项,`onMenuItemSelected()`方法会被回调,这是你处理用户选择的地方。关闭时,一般不需要显式地关闭,因为它会在用户点击外部区域或者选择其他菜单项时自动消失。 ```java @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // 处理每个菜单项的选择... } return super.onOptionsItemSelected(item); } popup.dismiss(); // 如果需要手动隐藏 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值