Avoiding PopupWindow dismissal after touching outside

后端 未结 8 2020
灰色年华
灰色年华 2020-12-31 05:07

I would like to use a PopupWindow with following behaviours/features:

  • It is focusable (has interactive controls inside eg. buttons)
  • The View \'under\'
8条回答
  •  無奈伤痛
    2020-12-31 06:03

    it is possible to setFocusable(false) for PopupWindow

    buttons still be clickable, but without visual clicking behaviour (some custom handler to force show click?)

    below is sample for floating window with "always on top" option

    original layout near floating window is fully operational in both cases, moreover, it is possible to use dialogs and other popups when window is still floating

    also the window is reusable

    final static int buttonAlpha = 0xDF;
    final static float buttonTextSize = 12f;
    
    public final void addPopupButton(LinearLayout linearLayout, String title, android.view.View.OnClickListener onClickListener)
    {
        Button button = new Button(this.getContext());
        button.setText(title);
        button.setTextSize(buttonTextSize);
        button.getBackground().setAlpha(buttonAlpha);
        button.setOnClickListener(onClickListener);
        linearLayout.addView(button, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    }
    
    public final Button addPopupCheckbox(LinearLayout linearLayout, String title, boolean isChecked, android.view.View.OnClickListener onClickListener)
    {
        final Button button = new Button(getContext());
        button.setText(title);
        button.setTextSize(buttonTextSize);
        final int buttonHeight = button.getHeight();
        setButtonChecked(button, isChecked);
        button.setHeight(buttonHeight);
        button.getBackground().setAlpha(buttonAlpha);
        button.setOnClickListener(onClickListener);
        linearLayout.addView(button, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
        return button;
    }
    
    public final void setButtonChecked(Button button, boolean isChecked)
    {
        button.setCompoundDrawablesWithIntrinsicBounds(Resources.getSystem().getIdentifier(isChecked ? "android:drawable/btn_check_on" : "android:drawable/btn_check_off", null, null), 0, 0, 0);
    }
    
    private boolean isMenuAlwaysOnTop = true;
    private PopupWindow popupWindowMenuV2 = null;
    
    public final void popupMenuNav2()
    {
        if (popupWindowMenuV2 == null)
        {
            // [start] layout
    
            ScrollView scrollView = new ScrollView(this.getContext());
    
            final LinearLayout linearLayoutNavigation = new LinearLayout(this.getContext());
            linearLayoutNavigation.setOrientation(LinearLayout.VERTICAL);
            linearLayoutNavigation.setBackgroundColor(0x7FFFFFFF);
            linearLayoutNavigation.setPadding(20, 10, 20, 10);
    
            scrollView.addView(linearLayoutNavigation, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    
            popupWindowMenuV2 = new PopupWindow(this);
            popupWindowMenuV2.setBackgroundDrawable(new BitmapDrawable());
            popupWindowMenuV2.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
            popupWindowMenuV2.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
            popupWindowMenuV2.setTouchable(true);
            popupWindowMenuV2.setOutsideTouchable(!isMenuAlwaysOnTop);
            popupWindowMenuV2.setFocusable(!isMenuAlwaysOnTop);
            popupWindowMenuV2.setTouchInterceptor(new OnTouchListener()
            {
                @Override
                public boolean onTouch(View v, MotionEvent event)
                {
                    if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_OUTSIDE)
                    {
                        if (!isMenuAlwaysOnTop)
                            popupWindowMenuV2.dismiss();
                        else
                            return false;
                        return true;
                    }
                    return false;
                }
            });
            popupWindowMenuV2.setContentView(scrollView);
    
            // [end] layout
    
            // [start] always on top checkbox
    
            final Button buttonMenuAlwaysOnTop = addPopupCheckbox(linearLayoutNavigation, "always on top", isMenuAlwaysOnTop, null);
            buttonMenuAlwaysOnTop.setOnClickListener(
                    new OnClickListener()
                    {
                        @Override
                        public void onClick(View vv)
                        {
                            isMenuAlwaysOnTop = !isMenuAlwaysOnTop;
                            setButtonChecked(buttonMenuAlwaysOnTop, isMenuAlwaysOnTop);
                            popupWindowMenuV2.dismiss();
                            popupWindowMenuV2.setOutsideTouchable(!isMenuAlwaysOnTop);
                            popupWindowMenuV2.setFocusable(!isMenuAlwaysOnTop);
                            popupWindowMenuV2.showAtLocation(((Activity) getContext()).getWindow().getDecorView(), Gravity.CENTER_VERTICAL + Gravity.RIGHT, 0, 0);
                        }
                    });
    
            // [end] always on top checkbox
    
            addPopupButton(linearLayoutNavigation, "some button",
                    new OnClickListener()
                    {
                        @Override
                        public void onClick(View vv)
                        {
                            if (!isMenuAlwaysOnTop)
                                popupWindowMenuV2.dismiss();
                            someAction();
                        }
                    });
    
        }
    
        popupWindowMenuV2.showAtLocation(((Activity) getContext()).getWindow().getDecorView(), Gravity.CENTER_VERTICAL + Gravity.RIGHT, 0, 0);
    }
    
    // somewhere in handler:
                if (someCondition)
                {
                    if (popupWindowMenuV2 != null && popupWindowMenuV2.isShowing())
                        popupWindowMenuV2.dismiss();
                    else
                        popupMenuNav2();
                    return true;
                }
    

提交回复
热议问题