web-dev-qa-db-ja.com

Android Nougat PopupWindow showAsDropDown(...)重力が機能しない

私はこのコードを持っています。

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();

そして、それは完全にAndroidバージョン<Android Nougatで動作します。しかし、Android Nougatでは、ポップアップはアンカービューではなく、画面の上部。

13
Jimson

Android 7.0のバグのようですが、互換性のある方法で解決できます。

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は将来のビルドでこのバグを修正します。そして、最終的な回避策があります。ポップを作成するときに高さを指定する必要があります。

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

上記のようにpopを初期化すると、popUp.showAsDropDown(anchorView)のみを使用して、このポップアップを表示できます。このように、Android APIのバージョンを無視できます。

16
Liang Steve

7.0と7.1は異なるため、別々に処理されます。

仮想マシン(7.0および7.1)でテストした次の方法は問題ありません。

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

この問題はAndroid 7.0(API 24)でのみ発生するようです。7.1.1(API 25)では、同じデバイス上ですべて問題ありません。調査の結果、popUp.update()は、すでに Marilia で言及されているように、popUp.update()を削除するだけでは、ポップアップはAPI 24より前のバージョンでは表示されません。これが唯一の方法は、バージョンチェックを使用し、API 24のデバイスでのみupdate()メソッドを使用しないことです。これは私のために働いた解決策です:

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

さまざまなデバイスとAPIでテストし、API 18からAPI 25までのあらゆる場所で問題なく機能しました。

2

あなたのコードに本当にpopUp.update();が必要ですか?私は同様の問題を抱えていました。私の場合、popUp.update();は必要ありませんでした。それを削除すると、ポップアップ重力が期待どおりに動作しました。

また、これはおそらく関連する問題であり、PopupWindow.showAtLocation()について報告されています。

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

1
Marilia

このコードは私のために働いた。やってみてください

    protected void showSortPopup(View anchorView) {


    if (Build.VERSION.SDK_INT >= 25) {
        Rect rectf = new Rect();
        anchorView.getGlobalVisibleRect(rectf);
        int offsetY = (rectf.top + anchorView.getHeight());
        WindowManager wm = (WindowManager) Manager.getInstance().getCurrentActivity().getSystemService(Context.WINDOW_SERVICE);
        int screenHeight = wm.getDefaultDisplay().getHeight();
        mPopup.setHeight(screenHeight - offsetY);
    }
    mPopup.showAsDropDown(anchorView);

}
0
NhatVM

Android API 29では、ポップアップの幅と高さをWRAP_CONTENTKotlinの私のコードのように。

private fun createSpinnerLikePopUp() {
        val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val vw = inflater.inflate(R.layout.dialog_window, null, false)
            popUp = PopupWindow(context).apply {
            isFocusable = true
            width = WindowManager.LayoutParams.WRAP_CONTENT
            height = WindowManager.LayoutParams.WRAP_CONTENT
            contentView = vw
            setBackgroundDrawable(null)
        }
        vw!!.recyclerView.apply {
            layoutManager = LinearLayoutManager(context)
            adapter = RecyclerAdapter(context, myArray)
        }
    }

次のようにボタンをクリックします。

displayPopupBtn.setOnClickListener { view ->
            if (popUp != null) {
                if (popUp.isShowing) {
                    popUp.dismiss()
                } else {
                    popUp.showAsDropDown(view)
                }
            }
        }
0
Kalu Khan Luhar