web-dev-qa-db-fra.com

Android Nougat PopupWindow showAsDropDown (...) La gravité ne fonctionne pas

J'ai ce code.

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

popUp.setContentView(anchorView);
popUp.showAsDropDown(anchorView);
popUp.update();

Et sa fonctionne parfaitement sur la version Android <Android Nougat. Mais dans Android Nougat, la fenêtre contextuelle est affichée en haut de l'écran au lieu d'être relative à la vue d'ancrage.

13
Jimson

Il semble un bug dans Android 7.0. Mais vous pouvez le résoudre avec une méthode compatible.

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 corrigera ce bogue lors de la prochaine version. Et il y a une solution de contournement finale. Vous devez donner la hauteur lors de la création de pop.

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

Init pop comme ci-dessus, et vous ne pouvez utiliser que popUp.showAsDropDown (anchorView) affiche cette fenêtre contextuelle. De cette manière, vous pouvez ignorer la version de l'API Android.

16
Liang Steve

7.0 et 7.1 pour atteindre différents, afin d'être traités séparément.

La méthode suivante que j'ai testée dans la machine virtuelle (7.0 et 7.1), pas de problème.

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);
        }
    }
5
x1876631

On dirait que ce problème n'apparaît que dans Android 7.0 (API 24). Dans 7.1.1 (API 25), tout est OK sur les mêmes appareils. Après quelques recherches défini que le problème causé par popUp.update(), comme il est déjà mentionné par Marilia . Mais si vous supprimez simplement popUp.update(), la fenêtre contextuelle n'apparaîtra pas dans les versions antérieures à l'API 24. Pour éviter cela, il ne reste plus qu'à utiliser le contrôle de version et à ne pas utiliser la méthode update() uniquement sur les périphériques dotés de l'API 24. Voici la solution qui a fonctionné pour moi:

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

Il a été testé sur différents périphériques et API et il fonctionne bien partout, de l’API 18 à l’API 25.

2
Volodymyr Buberenko

Avez-vous vraiment besoin de popUp.update(); dans votre code? J'avais un problème similaire, dans mon cas, je n'avais pas besoin de popUp.update(); et sa suppression faisait en sorte que la gravité contextuelle se comporte comme prévu.

En outre, il s'agit probablement d'un problème connexe, signalé à propos de PopupWindow.showAtLocation()

https://code.google.com/p/Android/issues/detail?id=221001

1
Marilia