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.
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 2 alert dialogs, dialog A and dialog B. Clicking on one of dialog A's buttons will bring up dialog B. I then want to have a button that will dismiss dialog B and return to dialog A.
Is there a way to do this apart from dialog B performing a showDialog(dialogA) ?
This works, but you can see the reload of dialog A, instead of just returning to an already existing dialog A. Performing a dismiss in dialog B just dismisses both of them.
A minor question, but I'd like to see if there is a way to stack them on top of one another.
Thanks
Using the basic dialog building blocks it is not possible to have them stack, you will need to re-show the first dialog.
The reason for this is that when you press a dialog button it internally will dismiss the dialog as part of the process for calling the click handler you assigned for each button in the dialog builder API.
One way around this is to make a custom dialog layout that doesn't have the dismiss behavior, by setting up your own buttons in the layout, rather than using those created by the dialog builder methods. Then in the click handler for you own buttons simply show the second dialog without dismissing the first.
http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog
As one reply mentioned, you cannot do this with standard dialogs. But you can do it by making the first dialog be an activity that is styled to look like a dialog, and the second is actually a dialog.
Just set the theme of the activity in your layout like so:
<activity android:theme="#android:style/Theme.Dialog">
See this topic on making an activity that looks like a dialog.
https://stackoverflow.com/a/1979631/602661
dismiss the dialog from within itself.
Edit, here is some clearer code.
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
return;
}
});
alertDialog.show();
You should use inside your custom layout one view/button and based on this view/button click you can create another dailog without cancel first one, if you use builder.setNegativeButton or builder.setPositiveButton your current dialog will be close, my working code like as,
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityAppImages.this,R.style.your_style);
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.your_custom_layout, null);
final Button mButtonCreateOtherDailog = (Button)dialoglayout.findViewById(R.id.txt_create_second_dailog);
mTextView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//create your other dailog here
}
});
builder.setView(dialoglayout);
builder.show();
through the help of various tutorials, I've managed to write a custom dialog that displays a listview populated by records from a local database. I have set click listeners and figured out how to retrieve the record at the listview item clicked by setting the cursor at the position returned and so on...Now what I want to do is, dismiss this dialog when an item is clicked, and automatically open a new dialog with this cursor's content as the name of the table from which to re-populate the new listview. I'd like to know if anyone knows the best way of doing this in terms of application structure.
Currently, I am calling my dialog to show in my Activity like this:
public void onClick(View view) {
switch(view.getId()) {
case R.id.pickerbutton:
showDialog(DIALOG_PICK_CATEGORY);
break;
}
}
protected Dialog onCreateDialog(int id) {
dialog = null;
switch(id) {
case DIALOG_PICK_CATEGORY:
CustomDialogList.Builder customBuilder = new
CustomDialogList.Builder(SendCookieActivity.this);
customBuilder.setTitle(R.string.category);
dialog = customBuilder.create();
break;
}
return dialog;
}
After this dialog is shown, the user picks a category from the CustomDialogList dialog. I am having a hard time thinking of how to make it so that after the category is picked, this dialog is dismissed (or looks like it's dismissed) and the same one with newly populated items appears (or can be a completely new dialog too). and when someone presses the back button, the previous dialog is shown. Think of it as a file explorer but with only two levels of depth. I'd like to keep using my CustomDialogList because I have customized its look to match everything else in my app. Perhaps what would help me with this problem besides or instead of code, would be some diagrams of how this type of UI flow has been implemented before along with some pseudo code.
Thanks.
Assuming your custom dialog extends Dialog (or one its sub-classes). Have your Activity implement DialogInterface.onDismissListener. Then after you create the dialog with...
dialog = customBuilder.create();
...use dialog.setOnDismissListener(this); before you show it.
Your Activity will have to implement...
#Override
public void onDismiss(DialogInterface dialog) {
// Identify which dialog was dismissed and do something
}
When I have had to do this in the past, I have the onCancel for the dialog open the new dialog.
I'm trying to create an introduction to my program with a helpful dialog message system.
I don't want to overload the user with too much text at once so I want to break up my dialog into parts.
Each part of course would have its own message.
I use a separate static class to handle message delivery and flow logic; and it's working fine.
I also actually use 3 Dialogs.
One for the first message (since you can't go back), one for the middle message and one for the final message (since you can't go forward).
I'm able to call the middle message from the first message with no problem. I'm also able to return to the first message. But when I try to reshow the middle message from the middle message dialog the new dialog doesn't appear.
Example:
Let's say I have 4 messages, so the middle message will need to appear twice:
First message appears: user clicks next
Middle message appears: user clicks previous
First message appears: user clicks next
Middle message appears: user clicks next
Middle message appears: user clicks next
Final message appears
The problem is that I get no dialog on step 5.
I'm using onPrepareDialog to reinitialize the dialogs as they're used. Right now it's basically a clone of onCreateDialog where each case in the switch calls the builder method appropriate for that dialog.
This is the code for my middle dialog method. (The other 2 are about the same. You can guess what they look like from this.)
protected AlertDialog buildMiddleNoticeDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setTitle(Notice.getTitle())
.setMessage(Notice.getMessage())
.setCancelable(false)
.setNegativeButton(resources.getString(R.string.notice_next_button),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
showDialog(Notice.next());
}
})
.setPositiveButton(resources.getString(R.string.notice_previous_button),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
showDialog(Notice.previous());
}
});
return builder.create();
}
I used a normal dialog with a TextSwitcher inside and two buttons to step forward or backward. The TextSwitcher simply changes the text and some animation are possible for text change. Try that!
The functionality of the two buttons simply depends on the position in my string array where all the messages are stored in ordered positions.
Thats my activity which is started with a dialog theme: http://saintfeintcity.org/projects/sfc/repository/entry/trunk/src/org/saintfeintcity/activities/TippsAndTricksActivity.java
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.