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
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.
Ist there a possibility to do something like that:
int selected_value = Dialog("This dialog show a combobox, i want to know which item is selected")
Or
String typed_chars = Dialog("This Dialog show a TextBox, i want to know the typed chars")
It is strongly recommended, that the code will stop while the dialog is shown and resume after dismissing the dialog, like the "showdialogforresult" method in c# or vb.net, I have to show lots of Dialogs and every dialog depends on former choices, I will become crazy if i have to code this with listener or callbacks...
While I don't think this is exactly possible like you do it, you do not need to code an anonymous class per Button callback.
Instead you can designate one class that implements DialogInterface.OnClickListener() and which you specify for all of the buttons. Its onClick() callback gets the information about which Dialog was invoked and which button was clicked. So you can operate within this onClick() method with some switch/case or if/else cascades.
Not perfect, but won't make you crazy :)
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.