How to dismiss a pop_up window when clicking outside? - android

I want to know how to close a pop_up window once the user clicks outside it, I had a look at PopupWindow - Dismiss when clicked outside but without any luck, and I tried that code:
pw.setBackgroundDrawable(null);
pw.setOutsideTouchable(true);
pw.setTouchInterceptor(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE)
{
pw.dismiss();
return true;
}
return false;
}
});

Try this out.Hope it works :)
solution 1:
popupWindow.setFocusable(true);
popupWindow.update();
If this dont work.Then you can try this out.
solution 2:
You can use dialog.setCanceledOnTouchOutside(true); which will close the dialog if you touch outside of the dialog.
Something like,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Or if your Dialog in non-model then,
1 - Set the flag-FLAG_NOT_TOUCH_MODAL for your dialog's window attribute
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 - Add another flag to windows properties,, FLAG_WATCH_OUTSIDE_TOUCH - this one is for dialog to receive touch event outside its visible region.
3 - Override onTouchEvent() of dialog and check for action type. if the action type is 'MotionEvent.ACTION_OUTSIDE' means, user is interacting outside the dialog region. So in this case, you can dimiss your dialog or decide what you wanted to perform. view plainprint?
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog ******************** ");
this.dismiss();
}
return false;
}

Ok so fixed in the end.
First made the main layout which the popup sits on a relative layout. Then placed a full screen blank layout on top which I made invisible and transparent.
Then show when the popup is shown, set the full screen panel visible with setVisibility(View.VISIBLE); and hide when popup is hidden with setVisibility(View.GONE);
Also need to return true from an on touch listener for the layout with (To stop touch events passing back to the main layout):
blocker.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return true;
}
});
And give the popup window the properties:
setTouchable(true);
setOutsideTouchable(false);
Cheers

you should'nt set the BackgroundDrawable to null, because that kills the OnTouchListener ;
you should replace pw.setBackgroundDrawable(null); by pw.setBackgroundDrawable(new BitmapDrawable())

Better use a dialog Fragment for the same. It is made for the popup functionality and closes by default on pressing outside the dialog Fragment or using the hard back button.

Related

Prevent DialogFragment from dismissing when clicking outside/back button, and show a message asking for confirmation instead

I have a DialogFragment that allows the user to input long messages. By default, if the user clicks outside the DialogFragment or back button, the dialog is dismissed and the user inputs will be lost.
If I use "this.isCancelable = false", it entirely prevents the back button/outside click from firing, which I do not want.
Instead, I want to have a popup message to appear with "Are you sure you want to discard changes", and dismiss DialogFragment only if the user clicks yes then. How should I do this?
Edit: also tried to solve this with flags but still having issues.
Add to DialogFragment's "override fun OnResume()"
//FLAG_WATCH_OUTSIDE_TOUCH requires FLAG_NOT_TOUCH_MODAL to work
dialog?.window?.addFlags(
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
)
dialog?.window?.addFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
)
dialog?.window?.decorView?.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_OUTSIDE) {
//action to show a message
}
true
}
Problem with this approach is due to FLAG_NOT_TOUCH_MODAL, I can now click items behind the dialog, which messes up the navigation controller and breaks the app. Is it possible to monitor MotionEvent.ACTION_OUTSIDE, but prevents any actual clicks outside the dialog?
You can set setCanceledOnTouchOutside boolean to true and use the below method for events.
dialog.setOnCancelListener(
new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
//When you touch outside of dialog bounds,
//the dialog gets canceled and this method executes.
}
}
);
Show toast or dialog which you want for user confirmation in this onCancel method.
Hope this helps!
OR
1 Set the flag-FLAG_NOT_TOUCH_MODAL for your dialog's window attribute
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
2 Add another flag to windows properties, FLAG_WATCH_OUTSIDE_TOUCH - this one is for dialog to receive touch event outside its visible region.
3 Override onTouchEvent() of dialog and check for action type. if the action type is 'MotionEvent.ACTION_OUTSIDE' means, the user is interacting outside the dialog region. So in this case, you can open another dialog for user confirmation.
public boolean onTouchEvent(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
System.out.println("TOuch outside the dialog");
this.dismiss();
}
return false;
}
Found the solution, credit to #Unknownweirdo, How to dismiss the dialog with click on outside of the dialog?
Kotlin code:
override fun onResume() {
super.onResume()
dialog?.window?.addFlags(
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
)
dialog?.window?.decorView?.setOnTouchListener { v, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
val dialogBounds = Rect()
v.getHitRect(dialogBounds)
if (!dialogBounds.contains(event.x.toInt(), event.y.toInt())) {
// You have clicked the grey area
logicToConfirmDiscardingChange()
false // stop activity closing
}
}
true
}
}

How to make Keyboard's POPUP window dismiss when not touching

I'm creating a custom soft keyboard, and created a PopupWindow to show when a key is long pressed, like when you long press E and it shows E, É, È for you to choose one. The popup has a key to close him, but I want to remove this key and make him shows just while the user is touching, then the user long press, drag to the key that he want and release.
I'm using android API 8.
The popup is created in a KeyboardView class in the onLongPress method.
final View custom = LayoutInflater.from(context)
.inflate(R.layout.popup_layout, new FrameLayout(context));
final PopupWindow popup = new PopupWindow(context);
popup.setContentView(custom);
popup.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
popup.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
popup.showAtLocation(this, Gravity.NO_GRAVITY, popupKey.x, popupKey.y-50);
The button for close the popup:
buttonCancel.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
popup.dismiss();
}
});
I think can use something with the onTouch method, but how to identify the event of releasing? And where use it? On the keyboardView, or maybe on the popup window?
I managed to do this with:
#Override
public boolean onTouchEvent(MotionEvent me){
if(popup != null && me.getAction() == MotionEvent.ACTION_UP){
popup.dismiss();
}
}
I first created a method to show on logcat the code of every touch event, then I got the code that appeared when I release the touch and compared with the documentation, and it it the code for MotionEvent.ADCTION_UP.
With this, it's just put a dismiss on the popup.
I saw that there is a private function called KeyboardView.dismissPopupKeyboard().
This is ugly, but because I am using the default PopupWindow (I didn't overrided OnLongPress()) and I saw thata KeyboardView.onClick() calls dismissPopupKeyboard() and that's it, what I did was:
#Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP){
getOnKeyboardActionListener().onKey('1', null);
dismissPopupKeyboard();
}
return true; // Required for recieving subsequent events (ACTION_MOVE, ACTION_UP)
}

PopUpWindow dismissal by back press key

I have created a popUpwindow which contains this properties:
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setFocusable(true);
popupWindow.setOutsideTouchable(false);
After mentioning this also there is a dismissal of popUpwindow when clicked outside the popUpWindow. Can anybody tell me what can be done to avoid this.
And also i have a music getting played in popUpwindow but when it plays i am not able to increase or decrease volume for the same.
I am not able to access media volume controls when there is popUpwindow in focus. I have read that if there is overidden method onKeydown / up then setVolumeControlsStream(AudioManager.Stream_Music) will not work. But i have used keyDown method to handle backpress rest i am returning return super.onKeyDown(keyCode, event);
Please suggest method to overcome this.
Try this
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Rect dialogBounds = new Rect();
getWindow().getDecorView().getHitRect(dialogBounds);
if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {
return false;
}else{
return super.dispatchTouchEvent(ev);
}
}
May this help you. i used this to avoid dismissal of Dialog when clicked outside the Dialog.
Try this-
put below line end of your class
#Override
public void onBackPressed() {
if (popupWindow != null)
popupWindow.dismiss();
else
super.onBackPressed();
finish();
}
Set focusable to false for popup window. It will avoid dismissal of popUpwindow when clicked outside the popUpWindow.
popupWindow.setFocusable(false);

Display and Hide alternatively a dialog on touching anywhere on screen in android

I am developing a small app wherein a dialog must popup when the user touches anywhere on the screen and if the dialog is already being displayed then on clicking anywhere outside the dialog box it must disappear. Someone plz give suggestions as to how to go about doing this.
This is possibly duplicate of link
if you want to hide dialog box after touch event then
Dialog dialog = new Dialog(context);
dialog.setCanceledOnTouchOutside(true);
and by overriding the onTouch listener as
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
dialog.dismiss();
}
return false;
}

How to make popupwindow size exceed dialog window size?

I have use Popupwindow for auto-suggestion popup in a dialogFragment. On portrait, that popup doesn't reach soft keyboard (popup look small), it seem like its size is limited by dialog windown size. I want the popup reach soft keyboard (look bigger). How to make popupwindow exceed dialog window?
Note : I have try to setClippingEnable to fasle, but popup is growth exceed keyboard and screen.
Set this boolean for your popup window object and the pop up size will exceed the dialog size.
popupWindow.setClippingEnabled(false);
Here are my code
popUp = new PopupWindow(view, w, h);
popUp.setBackgroundDrawable(new BitmapDrawable());
popUp.setOutsideTouchable(true);
popUp.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
popUp.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popUp.setTouchInterceptor(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
popUp.dismiss();
return true;
}
return false;
}
});
private void updatePopUp(EditText input) {
popUp.setWidth(input.getWidth());
popUp.showAsDropDown(input);
popUp.update();
}
I think this code don't have problem because I have use it in other class, but the problem is when I implement it in dialog Fragment.
try this
PopupWindow mPop=new PopupWindow("View for popup","hgt(int)","width(int)","focusable(boolean)");

Categories

Resources