Откройте PopupWindow вверху представления - PullRequest
0 голосов
/ 12 декабря 2018

Я хочу, чтобы при нажатии кнопки «Показать больше» открывалось всплывающее окно с 3 вариантами по умолчанию, но, согласно некоторой логике, параметры будут меняться, т.е.скрыть один из параметров, основанных на каком-либо условии.

enter image description here

Я пытался добавить всплывающее меню:

popup = new PopupMenu(this, _showMore, GravityFlags.Top);

popup.MenuInflater.Inflate(Resource.Menu.showMoreMenu, popup.Menu);
if (!string.IsNullOrEmpty(someValue))
{
    popup.Menu.FindItem(Resource.Id.ABC1).SetVisible(false);
}

popup.MenuItemClick += Popup_MenuItemClick;
popup.Show();

Но вв этом случае изначально, когда у меня есть все 3 варианта, всплывающее окно отображается над кнопкой, так как под кнопкой «показать больше» остается меньше места.Но если я скрываю один из вариантов, моё всплывающее меню открывается внизу кнопки.Я хочу, чтобы мое всплывающее меню всегда открывалось над кнопкой привязки.

Затем я также попытался

PopupWindow popupWindow = new PopupWindow(this); // inflet your layout or diynamic add view

LayoutInflater inflater = (LayoutInflater)GetSystemService(Context.LayoutInflaterService);
View view = inflater.Inflate(Resource.Layout.TestLayout, null, false);

TextView abc1 = (TextView)view.FindViewById(Resource.Id.abc1);
TextView abc2 = (TextView)view.FindViewById(Resource.Id.abc2);
TextView abc3 = (TextView)view.FindViewById(Resource.Id.abc3);
abc1.Click += abc1_Click;
abc2.Click += abc2_Click;
if (!string.IsNullOrEmpty(somecondition))
{
    abc1.Visibility = ViewStates.Gone;
}
else
{
    abc2.Visibility = ViewStates.Gone;
}

popupWindow.Focusable = (true);
popupWindow.Width = (WindowManagerLayoutParams.WrapContent);
popupWindow.Height = (WindowManagerLayoutParams.WrapContent);
popupWindow.ContentView = (view);
popupWindow.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));

/*
//tried
var tttt= (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, Resource.Dimension._15sdp, Resources.DisplayMetrics);

//tried
int test=(int)(Resource.Dimension._15sdp * Resources.DisplayMetrics.Density);

//tried
float scale = Resources.DisplayMetrics.Density;
test= (int)(Resource.Dimension._15sdp * scale + 0.5f);

//tried
var dp = Resource.Dimension._15sdp;
int pixel = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dp, Resources.DisplayMetrics);
*/

popupWindow.ShowAsDropDown(_showMore, -220, -570); <-- fixed offset which works for 3 options

Приведенный выше код работает, но я установил фиксированные значения смещения, которые, как я предполагаю, не будут отображаться.это правильно на разных разрешениях телефона, а также когда я скрываю один из параметров в меню.

Я также пытался использовать ListPopupWindow, но та же проблема установки местоположения.Может кто-нибудь, пожалуйста, помогите мне в настройке смещения динамически.

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Вы можете попробовать следующий код:

fun showPopupAbove(anchor: View) {
        viewAnchor = anchor
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) {
            popupWindow.showAsDropDown(anchor)
        } else {
            popupWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, 0, 0)
        }
        measureSizeThenUpdatePopupWindowPosition()
    }


private fun measureSizeThenUpdatePopupWindowPosition() {
        val viewTreeObserver = rootView.viewTreeObserver
        if (!viewTreeObserver.isAlive) {
            return
        }
        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                rootView.viewTreeObserver.removeOnGlobalLayoutListener(this)
                val anchorRect = getRectFromView(viewAnchor)
                // calculate x,y position for display popup window above/below..ect anchor view
                var popupWinDownPositionX = (anchorRect.centerX() - rootView.width.toFloat() / 6).toInt()
                var popupWinDownPositionY = anchorRect.top

                // anchor view close to left
                if (popupWinDownPositionX < 0) {
                    popupWinDownPositionX = 0
                }
                // anchor view close to top
                if (popupWinDownPositionY < 0) {
                    popupWinDownPositionY = 0
                }
                // anchor view close to right
                if (popupMayExceedsTheScreen(popupWinDownPositionX,
                        rootView.width)) {
                    popupWinDownPositionX = (Resources.getSystem().displayMetrics.widthPixels - rootView.width.toFloat()).toInt()
                }
                popupWindow.update(popupWinDownPositionX, popupWinDownPositionY,
                    rootView.width, rootView.height)
                updateImageArrowMargin(popupWinDownPositionX)
            }
        })
    }

Вы можете изменить значения popupWinDownPositionX и popupWinDownPositionY, чтобы соответствовать вашей цели

0 голосов
/ 12 декабря 2018

Спасибо, @LeoZhu @ Ответ LeoZhu .Мне удалось заставить его работать, используя следующий код

PopupWindow popupWindow = new PopupWindow(this); // inflet your layout or diynamic add view

LayoutInflater inflater = (LayoutInflater)GetSystemService(Context.LayoutInflaterService);
View view = inflater.Inflate(Resource.Layout.TestLayout, null, false);

TextView abc1 = (TextView)view.FindViewById(Resource.Id.abc1);
TextView abc2 = (TextView)view.FindViewById(Resource.Id.abc2);
TextView abc3 = (TextView)view.FindViewById(Resource.Id.abc3);
abc1.Click += GenerateQR_Click;
abc2.Click += PrintQR_Click;
if (!string.IsNullOrEmpty(somecode))
{
abc1.Visibility = ViewStates.Gone;
}
else
{
abc2.Visibility = ViewStates.Gone;
}

int[] location = new int[2];
_showMore.GetLocationOnScreen(location);

popupWindow.Focusable = (true);
popupWindow.Width = (WindowManagerLayoutParams.WrapContent);
popupWindow.Height = (WindowManagerLayoutParams.WrapContent);
popupWindow.ContentView = (view);
popupWindow.SetBackgroundDrawable(new ColorDrawable(Color.Transparent));

view.Measure(View.MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified),
View.MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified));

int yOffset = location[1] - (int)(view.MeasuredHeight );

popupWindow.ShowAtLocation(_showMore, GravityFlags.NoGravity, location[0], yOffset); 
0 голосов
/ 12 декабря 2018

это может работать так:

int[] location = new int[2];
_showMore.getLocationOnScreen(location);
popupWindow.showAtLocation(_showMore,Gravity.NO_GRAVITY,location[0], location[1] - popupWindow.getHeight());
...