Android弹出窗口被解雇

Bos*_*jan 61 android popupwindow

当我单击列表活动中的项目时,我会显示一个弹出窗口.问题是后退键不会关闭它.我尝试在列表活动中捕获后退键但它没有注册它...然后我尝试将onkeylistener注册到我正在传递到弹出窗口的视图中.像这样:

pop.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            boolean res=false;
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
                // do something on back.
                Log.e("keydown","back");
                if (pw.isShowing()) {
                    Log.e("keydown","pw showing");
                    pw.dismiss();
                    res = true;
                }
            } else {
                res = false;
            }
            return res;
        }
    });
Run Code Online (Sandbox Code Playgroud)

传递给像这样的弹出窗口:

pw = new PopupWindow(
       pop, 
       240, 
       70, 
       true);
Run Code Online (Sandbox Code Playgroud)

但那个听众既不会开火也不会开火.你能帮助我吗?我没有想法:)

Ric*_*ler 148

这是因为弹出窗口不响应onTouch或onKey事件,除非它的背景为!= null.看看我写的一些代码来帮助解决这个问题.在基本情况下,您可以调用PopupWindow#setBackgroundDrawable(new BitmapDrawable())以强制它按您期望的方式运行.您不需要自己的onKey侦听器.PopupWindow#setOutsideTouchable(true)当用户在窗口边界外单击时,您可能还需要调用它.

扩展的深奥答案:

背景不能为空的原因是因为发生了什么PopupWindow#preparePopup.如果它检测到background != null它创建了一个实例PopupViewContainer并调用setBackgroundDrawable它并将内容视图放入其中.PopupViewContainer基本上是一个FrameLayout侦听触摸事件和KeyEvent.KEYCODE_BACK事件来解雇窗口.如果background == null,则不执行任何操作,只使用您的内容视图.作为替代PopupWindow处理方法的替代方法,您可以扩展根目录ViewGroup以按照您的方式运行.

  • 确保在显示对话框之前调用setBackgroundDrawable ...花了我一段时间才弄清楚那一个. (10认同)
  • @ScottW你真的觉得我不知道吗?提供资源不是编写不良文档的借口.当然,我确实有源,并经常使用我的调试器来理解为什么事情不能按预期工作.但这显然是Android**失败**.即使使用源代码和调试器,也很难解决这个问题,因为你不能触发问题,因为windows不响应触摸事件 (3认同)
  • 我可以问****你是怎么发现这个的?对我来说,这是不可能猜到的,所以要么你可以访问一些*隐藏文档*或者你是一个向导:) (2认同)
  • @Raffaele Android是开源的,这意味着您可以随时获取代码并在需要更多信息时自行深入了解.见http://source.android.com/ (2认同)

Sun*_*mar 39

按照以下方式工作正常:

PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT, true);
pw.setBackgroundDrawable(new BitmapDrawable());
pw.setOutsideTouchable(true);
pw.showAsDropDown(btnSelectWeight);
Run Code Online (Sandbox Code Playgroud)


Coo*_*ind 7

对于新项目,最好使用

popupWindow.setBackgroundDrawable(new ColorDrawable());
Run Code Online (Sandbox Code Playgroud)

代替

popupWindow.setBackgroundDrawable(new BitmapDrawable());
Run Code Online (Sandbox Code Playgroud)

不推荐使用BitmapDrawable.此外,在这种情况下,它比ShapeDrawable更好.我注意到当PopupWindow是一个带圆角的矩形时,ShapeDrawable用黑色填充角落.


Van*_*nja 5

一个非常简单的解决方案是编写pw.setFocusable(true),但可能你不想这样做,因为MapActivity不会处理触摸事件.

更好的解决方案是覆盖后退键,例如:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    // Override back button
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        if (pw.isShowing()) {
            pw.dismiss();
            return false;
        }
    }
    return super.onKeyDown(keyCode, event);
} 
Run Code Online (Sandbox Code Playgroud)

祝好运!


Muh*_*aat 5

对于新的搜索者,因为new BitmapDrawablenow( The constructor BitmapDrawable() is deprecated)不允许创建 a ,因此您必须将其更改为 a new ShapeDrawable(),以便您将更改:

pw.setBackgroundDrawable(new BitmapDrawable());
Run Code Online (Sandbox Code Playgroud)

到 :

pw.setBackgroundDrawable(new ShapeDrawable());
Run Code Online (Sandbox Code Playgroud)

整个工作将是这样的:

PopupWindow pw;
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.weight_popup, (ViewGroup)findViewById(R.id.linlay_weight_popup));
pw = new PopupWindow(layout,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT, true);
pw.setOutsideTouchable(true);
pw.setBackgroundDrawable(new ShapeDrawable());
pw.setTouchInterceptor(new OnTouchListener() { // or whatever you want
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            if(event.getAction() == MotionEvent.ACTION_OUTSIDE) // here I want to close the pw when clicking outside it but at all this is just an example of how it works and you can implement the onTouch() or the onKey() you want
            {
               pw.dismiss();
               return true;
            }
            return false;
        }

});
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);
Run Code Online (Sandbox Code Playgroud)