In my app (general construction described below), I have a timer, which the user can start by clicking an in-app button.
When the timer starts, a notification is shown. In the notification, there's a "STOP" button, which when clicked is supposed to open the app (if closed or killed) and then show a custom dialog.
The custom dialog is built of a bunch of views and a blur-background view.
There are two ways to open that dialog:
Clicking an in-app button triggers the method that opens this dialog.
Clicking the "STOP" button in the notification also triggers the same method (By calling a BroadcastReceiver that lives in the same fragment as the dialog, and in the BroadcastReceiver I call the method that opens the dialog - it all happens after the app opens (if it was closed or killed)).
The first method works - clicking the button opens the dialog when it's supposed to.
The second, however, opens the app but not the dialog (To clarify - opening the dialog means changing its views visibility to View.VISIBLE).
To check what goes wrong, I used a Toast message that shows the visibility of the dialog every time the method that opens the dialog gets called. The Toast message shows "VISIBLE", so that means the Views visibility is set to View.VISIBLE indeed - but the dialog is not shown, nor the blur-background.
General Construction: The app has multiple Fragments, stored inside a view pager, inside the MainActivity and the dialog lives in the main fragment.
Might Be Relevant: when clicking the notifications button, the app opens, but the notification panel stays fully opened. The Toast message shows behind the notification panel.
Also might be worth mentioning, that when I click the notification button while I didn't yet leave the app, the dialog pops up. Only after I leave the app and then come back (manually or by clicking the notification button) the dialog doesn't pop up.
dialog's XML: (stored inside of fragment_main.xml)
<com.google.android.material.circularreveal.CircularRevealFrameLayout
android:id="#+id/dialog_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
app:layout_behavior="com.google.android.material.transformation.FabTransformationSheetBehavior">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardPreventCornerOverlap="true">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="15.0dip">
//Here is the content of the dialog, textviews and custom buttons
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
</com.google.android.material.circularreveal.CircularRevealFrameLayout>
dialog opening method:
private void openDialog() {
//while "dialog" refers to the "dialog_container" in the dialog xml
dialog.setVisibility(View.VISIBLE);
fadeBlurIn(); //fades the blur-background view in
dialog.setClickable(true);
}
calling the method in the BroadcastReceiver: (stored inside MainFragment.java)
private final BroadcastReceiver endTimerReceiver = new BroadcastReceiver() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onReceive(Context context, Intent intent) {
.
.
.
boolean openDialog = {gets a boolean extra, works fine};
if (openDialog){
openDialog();
}
}
}
};
this BroadcastReceiver is attached to this fragment and works fine.
Why doesn't the dialog show?
And how can I fix it?
Problem Solved
What was the issue all about?
The problem was when re-opening the app after closing or leaving it, the main-fragment was re-created, and with it a new blur-background and a new custom dialog.
The BroadcastReceiver was stored in the old main-fragment, and so it referred to the old views (the old blur and dialog views)
The old views' visibility has changed, but the new ones didn't, so the visibility state change wasn't visible to the user.
But that's not all. Later on, I discovered that in addition to all that, even if I refer to the right view and try to display it, it's not displaying, and I found another problem - I try to change its visibility state too early.
Solution
Solving it was quite simple.
All I had to do was make the blur-background and the custom dialog static, so they'll not re-create every time a main-fragment is created. Then Their visibility state changes were visible to the user.
And the solution for the second half of the problem was even easier - all I had to do is put the command calling the method to show the dialog inside a Runnable, running in delay by a Handler. 10 ms of delay has done the job.
Although this thread's issue is solved by now, this issue still isn't.
Note to self
A good habit is to think ahead, knowing what objects I should set static, so that stuff like this won't happen frequently
By notification panel, do you mean it's a bar on top of the app activity?
If so, my guess is that opening the notification panel pushes the dialog outside the device screen. Perhaps the dialog is constrained to the notification panel?
I'm not very sure about this, so sorry if this turns out to be incorrect!
Also, posting some code might help.
You have made the view invisible and shown when clicked on either button or notification bar.
You can do is
Make the view visible and add the condition if called by Notification bar it remains as it is, if not then hide it and make it visible again on call on button.
Give the fix height and width to dialog
box and set the visibilty to "Gone".
android:visibility="gone"
After that call open dialog function and setVisibility to Visible.
I have an Activity, and inside that activity, i have several dialogs popup at unknown times. I would like the user to still be able to interact with the current activity (Press Buttons etc) whilst the dialog is being displayed. Is this possible or would there be an alternative solution to this? I have setup my dialog like so, to prevent it from closing on outside touch:
achievDialog = new Dialog(this);
achievDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
achievDialog.setContentView(R.layout.achiev_get);
achievDialog.setCanceledOnTouchOutside(false);
I am using a dialog themed activity in android to show a popup from a application context. The dialog has a transparent theme, but the issue is that I want the underlying activity to have focus and not the popup though the popup must be visble. How do I achieve this in android?
I think you would have to use a Fragment and just make it look like a popup dialog.
You can not switch focus between activities. There's only one activity "on focus" at the time, and is the one that is being displayed at that point. The transparent background doesn't mean you can access the activity below.
If i don't get it wrong, you want to be able to interact with the activity's controls while having a "Dialog" on the screen. Any sort of Dialog class from Android will not help, since they take the focus away. Not really sure about PopupWindow, but i'm guessing will be the same thing as the documentation says "that appears on top of the current activity."
You are going to have to create a custom dialog using a RelativeLayout/FrameLayout within your activity.
I have tabs that when tapped will show a view for each tab. Is it possible to create an AlertDialog that is specific to a particular view and only shows when the view is shown? So if the user taps on one tab, they would see an AlertDialog but if they tap on a different tab, the AlertDialog will not show. I don't believe its possible because I believe an AlertDialog is global within the app and when shown comes to the foreground making it impossible to tap on anything else until the dialog is dismissed. But maybe I'm wrong.
No, it is not. You may try to switch to Fragments and FragmentDialog as that would allow you to 'bind' dialog to a fragment, and each fragment can sit on separate 'tab' of your app (yet, you'd need to rework your app anyway). If you want to use 'traiditional' dialog, then you have to add a logic yourself, and not show it if different than expected tab is visible.
My application displays alert dialogs in some cases. Also, it is possible for a user to launch my application using the VIEW/SEND intent. The scenario I am considering is, the dialog is visible, the user presses 'Home' & selects my application to View/Share a file.
I would want to dismiss the dialog before beginning with the view/share operation. Although I can maintain which dialog is visible and hide it before the operation begins, I was wondering if there is a conventional/recommended way or API, something like activity.dismissAnyVisibleDialog() that can come in handy.
Thanks a lot,
Akshay
I finally myself maintained which dialog is visible & dismissed it before displaying the next one.
-Akshay
Just close the dialog in the onPause() method (override in your activity).
This way it will be dismissed when the activity is no longer visible i.e if you switch to the home screen.