Android Nougat PopupWindow showAsDropDown(...) Gravity not working

7.0 and 7.1 to achieve different, so to be dealt with separately.

The following method I tested in the virtual machine(7.0 and 7.1), no problem.

public void showFilterWindow(Context context, PopupWindow popupWindow,View showView, int xoff, int yoff) {
        if (Build.VERSION.SDK_INT < 24) {
            //7.0 The following system is used normally
            popupWindow.showAsDropDown(showView, xoff, yoff);
        } else {
            int[] location = new int[2];
            showView.getLocationOnScreen(location);
            int offsetY = location[1] + showView.getHeight() + yoff;
            if (Build.VERSION.SDK_INT == 25) {
                //【note!】Gets the screen height without the virtual key
                WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
                int screenHeight = wm.getDefaultDisplay().getHeight();
                /*
                 * PopupWindow height for match_parent,
                 * will occupy the entire screen, it needs to do special treatment in Android 7.1
                */
                popupWindow.setHeight(screenHeight - offsetY);
            }
            //Use showAtLocation to display pop-up windows
            popupWindow.showAtLocation(showView, Gravity.NO_GRAVITY, 0, offsetY);
        }
    }

Looks like this problem appears only in Android 7.0 (API 24). In 7.1.1 (API 25) everything is OK on same devices. After some research defined that the problem caused by popUp.update(), like it is already mentioned by Marilia. But if you just remove popUp.update(), the popup won't appear in versions prior to API 24. In order to avoid this the only way now is to use version check and don't use update() method only on devices with API 24. Here is the solution, which worked for me:

if (Build.VERSION.SDK_INT != 24) {
   popup.update(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
}

Tested it on different devices and APIs and it works well everywhere from API 18 and up to API 25.


It seems a bug in android 7.0. But you can solve it with a compatible way.

PopupWindow popUp = new PopupWindow();
popUp.setFocusable(true);
popUp.setOutsideTouchable(true);        
popUp.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
popUp.setHeight(600);

popUp.setContentView(anchorView);
  if (android.os.Build.VERSION.SDK_INT >=24) {
     int[] a = new int[2]; //getLocationInWindow required array of size 2
     anchorView.getLocationInWindow(a);
     popUp.showAtLocation(((Activity) mContext).getWindow().getDecorView(), Gravity.NO_GRAVITY, 0 , a[1]+anchorView.getHeight());
    } else{
     popUp.showAsDropDown(anchorView);
}

popUp.update();

Google will fix this bug in the future build. And there is a final workaround. You need give the height when creating pop.

PopupWindow popup = new PopupWindow(contentView, with, height);

Init pop as above, and you can only use popUp.showAsDropDown(anchorView) show this popup. In this way, you can ignore the version of the Android API.