Android 9.0通过发menu键值,PopupWindow为什么只能显示则无法销毁
一、
1.首先是在andoridP上google新增一笔case,目的是为了能够在触摸模式下焦点能够集中在activity上,应用必须明确设置requestFocus标签才能生效;
ViewRootImpl.java
public ViewRootImpl(Context context, Display display) {
if (!sCompatibilityDone) {
// 在andorid P 上google对sdk进行了判断;
- sAlwaysAssignFocus = mTargetSdkVersion < Build.VERSION_CODES.P;
//修改为true则可获取焦点;
+ sAlwaysAssignFocus = true
sCompatibilityDone = true;
}
2.再往下看,如果当前sdk大于或小于才能重新requestFocus否则不会,因而在发送KeyEvent.KEYCODE_MENU事件时,只是show,则不会执行dismiss;
ViewRootImpl.java
public void focusableViewAvailable(View v) {
...
if (!mView.hasFocus()) {
//如果sAlwaysAssignFocus为false,则不会重新requestFocus;
if (sAlwaysAssignFocus || !mAttachInfo.mInTouchMode) {
v.requestFocus();
}
} else {
二、
还可以直接采用第二种方式,如果你那可以修改代码,则可以直接在dispatchKeyEvent事件直接处理;
PopupWindow.java
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
//直接增加KEYCODE_MENU判断即可;
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_MENU) {
if (getKeyDispatcherState() == null) {
return super.dispatchKeyEvent(event);
}
三、
如果是自定义的PopupWindow,则可以在setContentView(View)中的View里重写dispatchKeyEvent方法,直接对KEYCODE_MENU进行判断,从而进行销毁;
public class MyPopupList extends View {
public MyPopupList(Context context) {
super(context);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode()==KeyEvent.KEYCODE_MENU){
//处理你想要的逻辑
// ...
}
return super.dispatchKeyEvent(event);
}
}
以上做个笔记,希望对有遇到此问题的小伙伴有所帮助;