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
Related
I am showing a toast in my app. The problem is that in some devices (Samsung galaxy s6) the toast is cancelled when touching the screen. This problem doesn't happens in other devices (Nexus 5)
This is my code
LayoutInflater li = getLayoutInflater();
View layout = li.inflate(R.layout.popup_tutorial_privado, (ViewGroup)findViewById(R.id.popup));
toast = new Toast(getApplicationContext());
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
Take a step back
Avoid using Toast altogether if you need more control and use a Dialog that dismisses itself after n time. You could write a method as simple as this one, that would produce something functionally equivalent to a Toast but with the added freedom of controlling when and how it's dismissed.
public void customToast(String message, int duration){
final Dialog dialog = new Dialog(MainActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.custom_toast);
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
dialog.setCancelable(false);
//Customize the views, add actions, whatever
((TextView)dialog.findViewById(R.id.message)).setText(message);
dialog.show();
//Auto cancel the dialog after `duration`
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
dialog.cancel();
}
},duration);
}
Demo
Note
If you want the dialog to be shown for the exact amount of time a long toast lasts, use 3500 since private static final int LONG_DELAY = 3500;
But wait! The dialog takes focus and I need to retain it!
Ok, ok, you may be writing inside an EditText and the Dialog acting like a Toast takes control of your focus and your keyboard hides and everything is lost. To prevent this, simply set an extra flag, that will tell the Dialog that it's not focusable, and that it should not attempt to request it.
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
Keep in mind that if you're showing the Toast by watching text changes in an EditText you should keep a flag of some sort, to know whether it's being shown, or is already shown, or whatever, otherwise you'll end up with multiple dialogs.
A toast provides simple feedback about an operation in a small popup. It only fills the amount of space required for the message and the current activity remains visible and interactive.
the toast does not interact with user, it just like "comes and go" you can not set it cancelable true or false.
you should use Dialogs to achieve what you want.
As suggested by the documentation:
A toast provides simple feedback about an operation in a small popup. It only fills the amount of space required for the message and the current activity remains visible and interactive. For example, navigating away from an email before you send it triggers a "Draft saved" toast to let you know that you can continue editing later. Toasts automatically disappear after a timeout.
For the behavior your explain, you do use snackbar with infinite time
Snackbar documentation
As the title says I'd like to know the best method for generating a button upon some condition being fulfilled in my code. In this case, I'd like clicking on a particular imageView "s02" to make a button appear in my activity.
I know that you can make AlertDialogs appear using code like this:
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Title");
alertDialog.setMessage("Message");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// code code code code code }
});
I tried substituting Button for AlertDialog on the first line but I couldn't use Builder on Button.
Also, should I create the button in a separate section of code then simply make it appear when the condition is set, or should I put the button's functionality in the code creating the button?
Putting your button in the xml layout and just making it appear when needed is the easiest route. If that isn't good enough, you can create a Button via new Button(Context), set all the parameters you need, then add it to the parent layout.
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 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.