Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PopupWindow z ordering

I play with menus using PopupWindow, which overlap EditText.

It works fine, except that my PopupWindow is overlapped by some items from EditText IME system (selection marks, Paste button).

My question is: how do I force z-ordering of my PopupWindow so that it appears above those decorations?

Here's image of what's happening. I need my PopupWindow (the menu) be drawn on top of everything, thus somehow tell WindowManager how to order windows. Thanks.

enter image description here

like image 612
Pointer Null Avatar asked Jun 15 '12 20:06

Pointer Null


3 Answers

Found anwer myself.

Those decorations are normal PopupWindow-s, managed by EditText.

Z-ordering of any Window is defined by WindowManager.LayoutParams.type, actually it defines purpose of Window. Valid ranges are FIRST_SUB_WINDOW - LAST_SUB_WINDOW for a popup window.

App typically can't change "type" of PopupWindow, except of calling hidden function PopupWindow.setWindowLayoutType(int) using Java reflection, and setting desired window type.

Result:

enter image description here

EDIT: Code that does that:

  Method[] methods = PopupWindow.class.getMethods();
  for(Method m: methods){
     if(m.getName().equals("setWindowLayoutType")) {
        try{
           m.invoke(getPopupWindow(), WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
        }catch(Exception e){
           e.printStackTrace();
        }
        break;
     }
  }
like image 184
Pointer Null Avatar answered Nov 12 '22 09:11

Pointer Null


import android.support.v4.widget.PopupWindowCompat;

PopupWindowCompat.setWindowLayoutType(popupWindow, WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
like image 4
TalkLittle Avatar answered Nov 12 '22 11:11

TalkLittle


public void compatibleSetWindowLayoutType(int layoutType) {
    if (Build.VERSION.SDK_INT >= 23) {
        setWindowLayoutType(layoutType);
    } else {
        try {
            Class c = this.getClass();
            Method m = c.getMethod("setWindowLayoutType", Integer.TYPE);
            if(m != null) {
                m.invoke(this, layoutType);
            }
        } catch (Exception e) {
        }
    }
}
like image 2
hakka Avatar answered Nov 12 '22 11:11

hakka