Androidpopup窗口解雇

我有一个popup窗口显示,当我点击我的列表活动中的项目。 问题是后退键不能closures它。 我试图捕获我的列表活动中的后退键,但它没有注册它…然后我试图注册一个onkeylistener我传递到我的popup窗口的视图。 喜欢这个:

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

这是传递给这样一个popup窗口:

 pw = new PopupWindow( pop, 240, 70, true); 

但那个听众也不会开火。 你可以帮我吗? 我没有想法:)

这是因为popup窗口不会响应onTouch或onKey事件,除非它具有!= null的背景。 看看我写的一些代码来帮助这个。 在基本的情况下,你可以调用PopupWindow#setBackgroundDrawable(new BitmapDrawable())来强制它按照你期望的方式工作。 你将不需要你自己的onKey监听器。 如果您希望在用户单击窗口边界之外时想离开,您可能还需要调用PopupWindow#setOutsideTouchable(true)

扩展深奥的答案:

背景不能为null的原因是PopupWindow#preparePopup发生了什么。 如果它检测到background != null它将创build一个PopupViewContainer的实例并调用setBackgroundDrawable ,并将其放入内容视图。 PopupViewContainer基本上是一个监听触摸事件的FrameLayout和一个closures窗口的KeyEvent.KEYCODE_BACK事件。 如果background == null,则不会执行任何操作,只是使用您的内容视图。 您可以根据PopupWindow来处理这个问题,扩展您的ViewGroup根据您的需要。

按照下面的方式工作正常:

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

对于新项目,最好使用

 popupWindow.setBackgroundDrawable(new ColorDrawable()); 

代替

 popupWindow.setBackgroundDrawable(new BitmapDrawable()); 

因为不推荐使用BitmapDrawable。 而且,在这种情况下,它比ShapeDrawable更好。 我注意到,当PopupWindow是一个带圆angular的矩形时,ShapeDrawable用黑色填充angular。

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

更好的解决scheme是覆盖后退键,例如像这样:

 @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); } 

祝你好运!

就用这个吧

 mPopupWindow.setBackgroundDrawable(new BitmapDrawable(null,"")); 

这不被弃用。 我会避免新的ShapeDrawable(),因为它将试图绘制一个形状,当屏幕需要重绘时缓慢渲染。

我希望这会对你有所帮助

  pw.setTouchInterceptor(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if (event.getAction() == MotionEvent.ACTION_DOWN) { pw.dismiss(); } return true; } }); 

对于新的search者来说 ,现在不允许创build一个new BitmapDrawableThe constructor BitmapDrawable() is deprecated ),所以你必须改变它到一个new ShapeDrawable() ,所以你会改变:

 pw.setBackgroundDrawable(new BitmapDrawable()); 

至 :

 pw.setBackgroundDrawable(new ShapeDrawable()); 

整个工作将如下所示:

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

你需要为你的PopupWindow添加setBackgroundDrawable(new BitmapDrawable())

  private void initPopupWindow() { // TODO Auto-generated method stub View view = getLayoutInflater().inflate(R.layout.main_choice, null); ListView main_menu_listview = (ListView) view.findViewById(R.id.main_menu_listview); ShowMainChoice madapter = new ShowMainChoice(context); main_menu_listview.setAdapter(madapter); int width = (int)getWindowManager().getDefaultDisplay().getWidth()/2; popupWindow = new PopupWindow(view, width,WindowManager.LayoutParams.WRAP_CONTENT); popupWindow.setBackgroundDrawable(new BitmapDrawable());//this is important,如果缺less这句将导致其他任何控件及监听都得不到响应popupWindow.setOutsideTouchable(true); popupWindow.setFocusable(true); main_menu_listview.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { // TODO Auto-generated method stub Log.e("++++++>", arg2+""); } }); } 

这个问题是popupwindow底层的消息机制决定的,因为它是阻塞式的。好运气