How to stack toasts in Android? - java

A friend is writing an Android app for school and I'm helping him a bit. There is one question that I was not able to solve for like an hour.
He is trying to show 2 toasts after each other, but we were not able to stack them, or even show them at the same time. All we see is the second Toast.
We tried showing it for a shorter time, than the first, to see if it was hiding behind the second, it was not. Then we placed the second in the middle of the screen, but it didn't help either. He said it just works for his friend (I can't confirm that, but also couldn't google anyone having the same issue)
Toast t1 = Toast.makeText(getApplicationContext(), "first", Toast.LENGTH_LONG);
t1.show();
Toast t2 = Toast.makeText(getApplicationContext(), "second", Toast.LENGTH_SHORT);
t2.setGravity(0, 50, 0);
t2.show();
Are we totally missing something? Is it even designed to show two toasts the same time, or stack them?

Use postDelayed(). Show the first Toast and after sometime show the second one:
final Handler handler = new Handler();
handler.postDelayed(
() -> //show the toast here,
1200);
handler.postDelayed(() -> //show second toast,
2400);
}
https://developer.android.com/reference/android/os/Handler

Try a snackbar (They look way better too!)
protected ArrayList<Snackbar> mSnackbarList = new ArrayList<>();
protected Snackbar.Callback mCallback = new Snackbar.Callback() {
#Override
public void onDismissed(Snackbar snackbar, int event) {
mSnackbarList.remove(snackbar);
if (mSnackbarList.size() > 0)
displaySnackbar(mSnackbarList.get(0));
}
};
public void addQueue(Snackbar snackbar){
setLayoutParams(snackbar);
snackbar.setCallback(mCallback);
mSnackbarList.add(snackbar);
if(mSnackbarList.size() == 1)
displaySnackbar(snackbar);
}
public void displaySnackbar(Snackbar snackbar){
snackbar.show();
}

Related

how to show pop up or custom toast in onStop() or onDestroy()?

I have an app how to make some notification when reaching specific time ...
I would to show some pop-up or custom layout when my app is onStop or onDestroy.
I would like this photo.
(click to enlarge)
If you just want to give a message then Toast is enough and easy.
#override
public void onStop() {
Toast.MakeText(context, "Your message here", Toast.LENGTH_LONG).show();
}
#override
public void onDestroy() {
Toast.MakeText(context, "Your message here", Toast.LENGTH_LONG).show();
}
EDIT: I won't recommend you to write long messages in Toast and show it for longer durations, instead consider a Statusbar Notification. Status Bar Notifications can be programmatically canceled when they are no longer relevant.
BUT If you still want to increase the duration of Toast message then here is a workaround.
private Toast mToastToShow;
public void showToast(View view) {
// Set the toast and duration
int toastDurationInMilliSeconds = 10000;
mToastToShow = Toast.makeText(this, "Hello world, I am a toast.", Toast.LENGTH_LONG);
// Set the countdown to display the toast
CountDownTimer toastCountDown;
toastCountDown = new CountDownTimer(toastDurationInMilliSeconds, 1000 /*Tick duration*/) {
public void onTick(long millisUntilFinished) {
mToastToShow.show();
}
public void onFinish() {
mToastToShow.cancel();
}
};
// Show the toast and starts the countdown
mToastToShow.show();
toastCountDown.start();
}
Here is how it works: the countdown has a notification time shorter than the duration for which the toast is displayed according to the flag, so the toast can be shown again if the countdown is not finished. If the toast is shown again while it is still on screen, it will stay there for the whole duration without blinking. When the countdown is finished, the toast is canceled to hide it even if its display duration is not over.
Simplest way would be to use a Toast (easy and immediate). More complex way is that you've to grant 2 special permissions "draw over other apps" and "app with usage access" (which are special permissions, so you need to create your own page to prompt the user to grant it), after which you can add your custom view directly to the windows manager of the system. Last but not least, you should seriously think if there's any benefit for the user to be notified on main screen about something after your main page has been stopped or destroyed, because that goes against the system design quite a lot.

How to start and stop progressbar in android?

I have an activity that calls a second java class. I want after the second class is called to show a progressbar and then return to normal activity execution. I found some other threads but i couldn't make the progressbar to stop.
There's a full example over here.
Quote:
Declare your progress dialog:
ProgressDialog progress;
When you're ready to start the progress dialog:
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
and to make it go away when you're done:
progress.dismiss();
Here's a little thread example for you:
// Note: declare ProgressDialog progress as a field in your class.
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
new Thread(new Runnable() {
#Override
public void run()
{
// do the thing that takes a long time
runOnUiThread(new Runnable() {
#Override
public void run()
{
progress.dismiss();
}
});
}
}).start();
ProgressDialog is deprecated, so you might want to use a ProgressBar.
I've found this post about deleting one of them.
Well, I think this is rather ridiculous, but here is how I fixed it.
In my xml for the ProgressBar, I added android:visibility="gone"
to hide it by default. Then, in my code, I first told it to display
(View.VISIBLE) before it tried getting the server list, then I told
it to hide (View.GONE) after it was done. This worked (I could see
the progress indicator while the data loaded, then it went away). So
I suppose I couldn't get it to hide in the code because the code is
not what forced it to be visible to begin with... That seems like a
bug to me.
Its very Simple:
to show a Progress
ProgressDialog dialog = ProgressDialog.show(getContext(), "Title", "Message");
and to stop it:
dialog.dismiss();

If...Else Statement always diverts to "else".

I am trying to run a "presence check" on a radio group, to determine what happens if 1 of 2 radiobuttons are selected in the group (if statement), if the other of the 2 radiobuttons is selected instead (else if statement) or if neither are selected (else statement). The code for this is as follows:
if (rdbAM.isSelected()) {
strTime = rdbAM.getText().toString();
} else if(rdbPM.isSelected()){
strTime = rdbPM.getText().toString();
} else {
AlertDialog.Builder WrongDateFormat = new AlertDialog.Builder(this);
WrongDateFormat.setMessage("Please Select AM or PM");
WrongDateFormat.setNeutralButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertWrongDateFormat = WrongDateFormat.create();
alertWrongDateFormat.show();
return;
}
So basically, what this should do is either, set the variable called "strTime" to whatever the text of the selected radiobutton in the radiogroup is, or display an error message if neither are selected. It is instead always displaying this error message, regardless of whether either radiobutton is selected or not:
(As you can see above, the "AM" radiobutton is selected, but error is still being displayed).
Any suggestions as to why this may be would be appreciated. Please note that I am relatively new to Android development, so if it is clearly something obvious then I apologise, but I have been trying to get my head round this for several days now! If you would like to see any further code, please let me know and I'll be happy to provide it, but am trying to keep it as private as possible, so didn't want to post everything in the initial post if not necessary. Thanks in advance.
According the documentation the RadioButton extends the CompoundButton that offers the method isChecked(). However there is poorly described the difference from the method isSelected() from the extended class View that might be confusing.
Do the following and it should work:
rdbAM.isChecked();
Instead of using isSelected() go for isChecked().
A RadioButton is a two-states button that can be either checked or unchecked. For this compound button, you should use method isChecked() to know its current state.
See documentation.
Update your code as below:
if (rdbAM.isChecked()) {
strTime = rdbAM.getText().toString();
} else if(rdbPM.isChecked()){
strTime = rdbPM.getText().toString();
} else {
AlertDialog.Builder WrongDateFormat = new AlertDialog.Builder(this);
WrongDateFormat.setMessage("Please Select AM or PM");
WrongDateFormat.setNeutralButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alertWrongDateFormat = WrongDateFormat.create();
alertWrongDateFormat.show();
return;
}

Start and cancel a toast programmatically

In my app, I've got a procedure that can last between 2 and 15 seconds more or less. What I want is to set a kind of toast that when the procedure starts shows:
Loading values. Wait...
Just now, I've setted the toast duration to SHORT, because if the procedure lasts about 5 or less seconds, a LONG will be just that, very long. But having setted the duration to SHORT, when it lasts more than 10 seconds the toast dissapears and there is no message showing that the app is still processing so the user can start touching things.
What I want is to set something like a toast but that I can programmatically cancel when the procedure is finished. Any ideas?
I would recommend that you simply set the Toast duration to the maximum possible time and then use the Toast object returned from Toast.makeText(...) to cancel it when your process is finished.
Toast t = Toast.makeText(....., YERY_LONG_TOAST_TIME);
t.show();
public void onYourTaskFinished() {
t.cancel();
}
Something like that.
I personally would recommend using a ProgressDialog btw: http://developer.android.com/reference/android/app/ProgressDialog.html
Here's an example:
final Toast toast = Toast.makeText(ctx, "This message will disappear in 1 second", Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 1000); //specify delay here that is shorter than Toast.LENGTH_SHORT
final Toast toast = Toast.makeText(ctx, "hello android", Toast.LENGTH_SHORT);
Handler h= new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
toast.show();
}
}, 1000);
h.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 3000);
You can have a handler of the Toast when you create it, pass it to you job and call the show() method when the job starts and call the cancel() method when the job finish.
However, from your description, toast message might not be your best choice. Toast is more like a hint which has little impact if the user misses it. With little background infomation about your app, I think you might need a ProgressDialog if you do not want the user to touch anything while you are loading data, or a ProgressBar if you just want the user to know your job's progress.
Do not use Toast for this purpose. You should use progress dialog or you can add progress indicator to notification bar. So user will be able to see progress even not being inside your app.

App crash by showing Dialog in Timer (in runOnUiThread) after closing app.

I'm making a little game and in it I have to check if a value is zero every second. When it is zero the game should stop and show a dialog instead.
As from now the game never ever shoud work until the app is reinstalled.
So, I have an timer with an timertask which executes a runOnUiThread.
Timer:
private void update(){
Timer timer = new Timer();
timer.schedule(new TimerTask(){
#Override
public void run() {
onChange();
}
},0,(1000* getResources().getInteger(R.integer.remove_speed_inSecond)));
}
runOnUiThread: (with try/catch to catch the exeption at this point but i want to fix and not just ignore it.)
private void onChange(){
runOnUiThread(new Runnable() {
#Override
public void run() {
try{
checkupifexpire();
}
catch (Exception ex) {
}
}
});
}
The Method where i show the dialog:
private void checkupifexpire() {
if(eat == 0 || drink == 0 || wash == 0 || care == 0){
dialog = new Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener()
{
#Override
public void onCancel(DialogInterface dialog)
{
GameEngine.this.finish();
}
});
dialog.setContentView(R.layout.activity_rip);
dialog.show();
}
}
Always when I press the back button or just the home button then the App crashes.
Any Idea how to fix this?
So, the logcat tells us that is crashes on line 306 of GameEngine.java, in the method checkupifexpire, which looks like it is the dialog.show() line.
I'm not 100% sure, but from what you've said, it would seem to me that when back or home is pressed, the app will lose its UI thread. This means that checkuponexpire cannot do what it does.
To solve your crash problem, there are three obvious options:
You could use onPause in your main activity to catch when the app loses the screen. At this point you need to either stop the timer, or switch it to using Toast to communicate information.
Only use Toast in checkuponexpire
Decide that when the back or home is pressed the game is over anyway and cancel the Timer.
To Actually get the dialog, it may also be helpful to change the context you use to create the dialog with. Although it should be used sparingly, it may be that getApplicationContext() is what you need here (possibly this.getApplicationContext()).
Thanks to Neil Townsend and WELLCZECH. :)
My problem was the Lifecycles.
Mostly i had the App running in the onCreat() and had no onStart() method.
Just didn't know that thies methods were as much important as they are.
Also i didn't need a dialog shown. Instead i just have to start a new activity and cancel the old one.

Categories