【问题标题】:onBackPress not called when pop up window is displayed显示弹出窗口时未调用 onBackPress
【发布时间】:2013-07-15 13:20:17
【问题描述】:

我想在弹出窗口显示时处理后按。在某些情况下我想关闭它,在某些情况下我不想在弹出窗口中执行某些任务。

显示弹窗时,不会调用Activity onBackPress。那么如何在弹出窗口显示时捕捉回压事件呢?

【问题讨论】:

  • check here 也阅读了它的 cmets
  • 将背景可绘制设置为非 null 将始终关闭弹出窗口。在某些情况下,我不想关闭弹出窗口,而是在弹出窗口中执行一些任务。那么有什么方法可以在弹出窗口可见时捕获后按事件。

标签: android


【解决方案1】:

您需要在您的PopupWindow 上调用setBackgroundDrawable() 并将背景设置为非null。这听起来很奇怪,但如果 background 未设置为您的 PopupWindow 上的某些内容,那么它将无法检测来自 Activity 的事件,例如触摸窗口外部或按下后退按钮。

几天前我遇到了同样的问题。我会尝试找到 SO 答案,有人解释了为什么会这样,但这可能需要我一点时间。同时,试一试它应该可以工作。

Found it

我没有机会对其进行测试,但您可以尝试添加 keyEventListener 并执行类似的操作

public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if (keyCode == KeyEvent.KEYCODE_BACK)
    {
         // put your code here
    }

并将setOutsideTouchable(true) 添加到您的PopupWindow 对象并在其上调用update()。如果这不起作用,那么您可能只需要在显示弹出窗口时禁用后退按钮并将您自己的Button 添加到窗口中。我还没有找到任何其他东西可以让您从按下的后退按钮中获取事件。

【讨论】:

  • 将背景可绘制设置为非 null 将始终关闭弹出窗口。在某些情况下,我不想关闭弹出窗口,而是在弹出窗口中执行一些任务。那么有什么方法可以在弹出窗口可见时捕获后按事件。
  • 我已经更新了一些可以尝试的东西。我希望它会有所帮助,但我不确定使用 PopUpWindow 时您想要做什么
【解决方案2】:

像这样设置背景可绘制

popup.setBackgroundDrawable(new BitmapDrawable());

然后像这样设置 OnDismissListener

popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                //do your code here
            }
        });

【讨论】:

    【解决方案3】:
    final PopupWindow popup = new PopupWindow(context);
    ...
    popup.setFocusable(false); //Setting this to true will prevent the events to reach activity below
    popup.setBackgroundDrawable(new BitmapDrawable()); //Or anything else, not null!
    

    然后在你的活动中:

    @Override
     public void onBackPressed() {
        //your code
     }
    

    【讨论】:

      【解决方案4】:

      我知道为时已晚,但它可以帮助别人。 这样做有两种选择

      1) 如果弹出窗口焦点对你来说不重要,那么设置

      mPopupInfoWindow.setFocusable(false);
      

      因为如果您的弹出窗口处于焦点位置,那么它不会将按下事件传递回活动,这就是不调用 onBackPressed() 方法的原因

      2) 如果弹出窗口焦点适合您,那么让它为真并在弹出窗口中设置此侦听器。这段代码对我有用

       mPopupInfoWindow.getContentView().setFocusableInTouchMode(true);
          mPopupInfoWindow.getContentView().setOnKeyListener(new View.OnKeyListener() {
              @Override
              public boolean onKey(View v, int keyCode, KeyEvent event) {
      
                  if (keyCode == KeyEvent.KEYCODE_BACK) {
                      mPopupInfoWindow.dismiss();
                      return true;
                  }
                  return false;
              }
          });
      

      【讨论】:

        【解决方案5】:

        我建议您可以考虑一个更简单的替代方案。其他方法对我不起作用。

        解决原理:你的弹窗附近的所有按钮点击都会被拦截,但是任何BACK按钮都不会被拦截。因此,如果您的弹出窗口中有任何可以采取行动的内容,那么在您调用dismiss() 之前设置一个指示。在您的 setOnDismissListener() 中执行额外的操作(如 getActivity().popupBackStack())。

        此解决方案的优点是您可以创建自己的 CustomPopupWindow 并实施此策略。您可以在自定义弹出窗口中隐藏此实现。

        第 1 步:在弹出窗口的实例化附近添加:

        boolean isClickHandled = false; 
        popupWindow.setOutsideTouchable(true);
        popupWindow.setBackgroundDrawable(new ShapeDrawable());
        popupWindow.setTouchInterceptor(new View.OnTouchListener() { // or whatever you want
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                isClickHandled = true;
                return false;
            }
        });
        

        如果您的 popupWindow 中有按钮,请让 setOnClickListener.onClick 设置 isClickHandled = true 和 dismiss()。

        在您的 onDismissListener 中执行以下操作:

        popupWindow.setOnDismissListener(() -> {
                popupWindow.dismiss();
                if ( !isClickHandled) {
                    MainActivity.mainActivity.getSupportFragmentManager().popBackStack();
                }
            });
        

        【讨论】:

          猜你喜欢
          • 2014-09-02
          • 1970-01-01
          • 2018-12-12
          • 1970-01-01
          • 1970-01-01
          • 2022-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多