In my activity, I'd like to show simple info dialogs, stuff like:
new AlertDialog.Builder(context).setMessage(message).show();
if I do that, the dialog will leak when I rotate that phone (not to mention it will disappear as well, so the user may miss it). I can use the managed dialogs, but I'm not sure how you use it sensibly for these types of short messages? Looks like you have to do this:
showDialog(SOME_DLG_ID);
...
#Override
onCreateDialog(int id) {
if (id == SOME_DLG_ID) {
new AlertDialog.Builder(context).setMessage(message).show();
}
}
there's no way to pass what the message should be into onCreateDialog since its an override method. I'd hate to make a member variable of the parent activity that just stores whatever the current message should be. How do you all do it?
Thanks
if I do that, the dialog will leak
when I rotate that phone (not to
mention it will disappear as well, so
the user may miss it)
You can add
<activity
android:configChanges="orientation|keyboardHidden"
>
to your AndroidManifest.xml to prevent restarting the activity when the phone rotates. I am using it in my app and my AlertDialog survives the rotation of phone.
You can implement Activity.onPrepareDialog(int, Dialog) to switch out the message before the dialog is shown on the screen. So you could do something like:
#Override protected void onPrepareDialog(int id, Dialog dialog) {
if (id == SOME_DLG_ID) {
((AlertDialog) dialog).setMessage(message);
}
}
You'd still have to keep track of the message you're current showing in your activity, but at least this way, you're not creating a Dialog object for each message you want to show.
Using DialogFragment to manage the dialog ensures that it correctly handles lifecycle events such as when the user rotates the screen or presses the Back button.
Related
I have this function where I need to return a list depending of what user pressed in Alert Dialog (cancel or save).
But I have an issue, let's imagine we have a list with a size of 10. Then on the iteration of that list it will build 10 alert dialogs at the same time plus a dark black shadow at the background caused by these.
So I'd like to "pause" until user pressed or find a way to don't pop up all these alert dialog at the same time and just appear one by one once pressed a button.
A quick reminder: I need to return a list after all dialogs have been pressed.
Question: How could I do that?
It would be better if you provided some code with this. Anyway, even though this is not something I would do and create 10 dialogs in the for loop, this can be done.
Just create a Boolean inside your for loop which will be used to check if the dialog is dismissed.
for(int i = 0; i < list.size(); ++i) {
Boolean isDismissed = false;
AlertDialog d = new AlertDialog(getBaseContext());
d.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
isDismissed = true;
}
});
//start your dialog
while(!isDismissed) {
//do nothing
}
}
As I said, I wouldn't do this.
Because I evaluate first a list of items, then I set on a new list of items that will require user to confirm about what to do with that, so I loop that with alert dialogs waiting for user to tell me what to do with those items
There is a much better way to do this. Why not starting one CustomDialog which will ask the user what to do with those items. He could choose options for each item with a spinner or if options are KEEP or DELETE just use checkbox or something.
So as people said, creating Alert Dialogs in a loop is a bad practice so my solution into this is just setting a view on Fragment that acts like a Dialog but I just turn it visible and gone whenever I need. This seems a proper solution for my case.
When user accept or cancel the view (clicking on button) just send it to the viewmodel and the viewmodel will evaluate if there are still items on the list. If there are items then show again this "view" on Fragment asking to user what to do :)
I don't have code to show because I haven't done it yet but I have thought for a while and this is the best I can think about. Hope it helps for someone who is in the same situation!
I have an extended DialogFragment which is opening from current Fragment.
Recently I've found that it's possible to click on element which causes dialog opening two times in short time period and it will force to open two dialogs one above another. It's unexpected behavior for my app. I would like to make possible open only one dialog instance. What I'm doing wrong?
Below is my code for dialog opening.
public boolean onActionItemSelected(int menuId) {
switch (menuId) {
case R.id.action_change_passcode:
pinChangeFlag = true;
AbstractPinDialog pinChangeFirstDialog = new StandardPinDialog(this);
pinChangeFirstDialog.show(getFragmentManager(), StandardPinDialog.class.getName());
return true;
//... other cases
}
}
A simple way is to set a global boolean tag like
isDialogVisible=false;
when you show the dialog, set its value as true. before showing that dialog box check
if(! isDialogVisible){
dialog.show();
}
so only one dialog box will appear.
Or the second way is to check if view of the dialog box has been created or not, then use similar logic to not show the second dialog.
I've been poking around at this problem and I can't seem to figure it out. I have a simple app with a few normal views and a GL surface view, I make a few dialog boxes using onCreateDialog() and everything seems fine.
#Override
protected Dialog onCreateDialog(int id)
{
super.onCreateDialog(id);
Dialog m_Dialog = null;
// help dialog
if (id == HELP_DIALOG)
{
m_Dialog = new Dialog(this);
m_Dialog.setContentView(R.layout.help_dialog);
m_Dialog.setTitle("Instructions - Press BACK to close");
}
}
However if I use home to exit the app then go back into the app the dialogs no longer appear, however the screen dims as if the dialog was being displayed. I am getting the call to onPrepareDialog() even when the dialog does not show, I tried some things in there like calling show() off of the dialog. It gets a bit more strange, if I then switch to my GL surface view and back the dialogs work again. I am using a ViewAnimator to switch between my views. I am pretty sure I am handling the lifecycle correctly, over riding onPause() / onResume()
#Override
protected void onResume()
{
super.onResume();
m_Sensors.StartSensors();
m_GameThread.Pause(false);
glSurface.onResume();
}
As always, thanks for the help.
I haven't tried working with GL on android, but I have experienced some home button/re-open app weirdness myself recently - in my case it turned out to be connected to the issues below, which you might want to check out:
http://code.google.com/p/android/issues/detail?id=5277
http://code.google.com/p/android/issues/detail?id=2373
Hope it can help you get on the right track.
In my app when i do some long work i'm using a Progress Dialog while the work isn't finished.
I'm looking for it in every place but without sucess. Everything that i founded is all about saving user interface elements states.
Then, i would like to know how i can save progress dialog state correctly ?
I want this working because when the orientation screen change the app crashes.
Shoul i use onSaveInstanceState() method ? How ? I try using saving as a bundle but without succes...
Any advice would be nice...
thanks
I think, your dialog crashes on orientation change because you are not using
#Override
protected Dialog onCreateDialog(int dialogID, Bundle args)
and
showDialog(dialogID);
to show your dialog.
I had the same problem with an alert dialog. As I see it, if you don't create dialog that way, it becomes linked to your activity, and when activity is dead, the system finds that a dialog still try to access that dead activity, not new one.
You need to add this to the manifest file for the activity in which you are showing the dialog:
android:configChanges="keyboardHidden|orientation"
to handle the screen orientation you must use onRetainNonConfigurationInstance()
you can find a more extensive explanation about screen orientation here: Faster Screen Orientation.
The way I do this in my applications is overriding the onConfigurationChanged() method in the Activity like so:
#Override
public void onConfigurationChanged(Configuration config) {
//Just switch the layout without respawning the activity
super.onConfigurationChanged(config);
}
This hasn't given me any issues as of yet and my Activity doesn't reload or restart when the orientation is changed.
I have a class that extends android.app.Dialog, the layout is done in an xml file, and the setup (button listeners, etc) is done on the onCreate method. My problem is that whenever the dialog is displayed, then dismissed, and displayed again, the Editable TextViews are still populated with the information that was displayed previously. What is the common way to clear these text fields? Remember - this is a separate class that extends Dialog - so there is no 'onDialogCreate' like Activity has.
Or, perhaps I am extending the wrong class? There is just a lot of processing being done, and do not want to have all the code in the main Activity. I would like it to be in a separate Class. I tried to extend AlertDialog, but it does not create the border like Dialog does. Any help would be great.
The dialog is shown via the Activity:
protected Dialog onCreateDialog(int id) {
switch(id){
case DIALOG_NEW_SAFE:
return(new NewSafeDialog(this));
default:
return(null);
}
}
onCreateDialog(..) caches the dialog which means the same instance is reused.
3 ways to fix the undesired behavior off my head:
Override onPrepareDialog(..), use findViewById(..) to get whatever you want to clear, clear it.
Don't rely on managed dialogs at all, do new NewSafeDialog(this).show() each time you want to show the dialog.
Add onCancelListener(..), onDismissListener(..) inside your custom dialog that would call a method to clear itself.
The good way to create a dialog is by using showDialog() as you did so don't change it.
The good and easy way to force deletion of a dialog in order to make your creation code recalled again is:
void removeDialog (int id)
So if you simply do the following, it's gonna work ;)
removeDialog(DIALOG_NEW_SAFE);
showDialog(DIALOG_NEW_SAFE);
Try clearing the text in the constructor of the NewSafeDialog i.e. your dialog class.