Android popup dismissal

I get a popup when I click an item in my list. The problem is that the rear key does not close it. I tried to catch the back key in my activity on the list, but he didn’t register it ... then I tried to register the onkeylistener for the view that I am sending to the popup. Like this:

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

which is passed to the popup as follows:

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

But this listener does not shoot. Can you help me? I have no ideas :)

+59
android popupwindow
Jun 25 '10 at 20:30
source share
9 answers

This is because the popup does not respond to onTouch or onKey events if it does not have a background that is = null. Check out the code I wrote to help with this. In the base case, you can call PopupWindow#setBackgroundDrawable(new BitmapDrawable()) to make it act as you expect. You will not need your own listener. You may also need to call PopupWindow#setOutsideTouchable(true) if you want it to leave when the user clicks outside the borders of the window.

Expanded esoteric response:

The reason the background cannot be null is due to what happens in PopupWindow#preparePopup . If it detects background != null , it creates an instance of PopupViewContainer and calls setBackgroundDrawable on it and puts its content into it. PopupViewContainer is basically a FrameLayout that listens for touch events and the KeyEvent.KEYCODE_BACK event to close the window. If background == null, it does nothing and just uses your content view. You can alternatively handle this depending on PopupWindow , expand your ViewGroup root to behave the way you want.

+144
Jun 26 '10 at 4:24
source share

Make it work fine:

 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); 
+35
Nov 16 2018-11-11T00:
source share

For new projects it is better to use

 popupWindow.setBackgroundDrawable(new ColorDrawable()); 

instead

 popupWindow.setBackgroundDrawable(new BitmapDrawable()); 

since BitmapDrawable is deprecated. Also, it is better than ShapeDrawable in this case. I noticed that when PopupWindow is a rounded rectangle, ShapeDrawable fills the corners with black.

+6
Aug 26 '14 at 2:31
source share

Actually, a simple solution is to write pw.setFocusable (true), but you probably do not want to do this because MapActivity will not handle touch events.

A better solution is to override the back key, for example:

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

Good luck

+5
Nov 08 '10 at 8:10
source share

just use it

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

which is not outdated. I would avoid the new ShapeDrawable (), as it would slowly display when it tries to draw a shape, when the screen needs to be redrawn.

+4
May 27 '14 at 2:46
source share

Hope this helps you.

  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; } }); 
+3
Nov 18 '11 at 7:25
source share

For new search engines , since the creation of new BitmapDrawable now not allowed ( The constructor BitmapDrawable() is deprecated ), so you need to change it to new ShapeDrawable() so that you change:

 pw.setBackgroundDrawable(new BitmapDrawable()); 

To:

 pw.setBackgroundDrawable(new ShapeDrawable()); 

And all the work will be like this:

 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); 
+3
May 22 '14 at 9:12
source share

you need to add setBackgroundDrawable(new BitmapDrawable()) for PopupWindow .

+1
Mar 13 '15 at 2:01
source share
  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,如果缺少这句将导致其他任何控件及监听都得不到响应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+""); } }); } 

This problem is popupwindow 底层 的 消息 机制 决定 的, 因为 它 是 阻塞 式 的. Good luck

0
Aug 22 '13 at 2:48 on
source share



All Articles