I was reading about Dialogs in Android site and I came across a section that saying "Avoid ProgressDialog".
Here is the link: http://developer.android.com/guide/topics/ui/dialogs.html
does that means they recommend not to use it? I really need a popup with showing progress while my app is doing background work.
Does that means I have to build my own Progress Dialog using ProgressBar class? How would one build it by the way? Any help is appreciated.
Edit:
With Android O, ProgressDialog is now officially deprecated. An alternative is approach is suggested
This class was deprecated in API level O.
Use a progress indicator such as ProgressBar inline inside of an activity rather than using this modal dialog.
Original answer:
This is all from a design & user interaction perspective, not a code perspective.
The UI guidelines are telling you to avoid using a ProgressDialog not because the class is deprecated (it is not at the time of writing this answer), but rather because it forces the user to avoid interacting with the application and merely stare at the screen.
Take the Google Play app as an example. While it downloads an application/update, you can still swipe, navigate, etc. You can still be involved with the app while it is doing something.
If you absolutely need the user to cease interaction until the progress bar finishes, by all means do so. The docs are merely saying you may be able to find better ways of doing it (hence the link to Progress & Activity).
With ProgressDialog being deprecated in Android O. You should create a ProgressBar and show it by setting it's visibility. I use DelayedProgressDialog from https://github.com/Q115/DelayedProgressDialog It does the same as ProgressDialog with the added benefit of a delay if necessary.
Usage:
DelayedProgressDialog progressDialog = new DelayedProgressDialog();
progressDialog.show(getSupportFragmentManager(), "tag");
Related
I've been recently trying out Android's in-app-update API here https://developer.android.com/guide/playcore/in-app-updates and calling appUpdateManager.completeUpdate() this method after successfully downloading the update seems to work, if I stay put on the view (fragment / activity) or rest my app in the background, but if I move to my app's other view it crashes, This is similar to Snackbar implementation trying to find views when the update fails or is cancelled but I move to a different fragment / activity. Is there a more efficient way to handle this globally throughout the app? It's really hard to debug it since you need an internal production build to test it out.
A similar solution I can think of is how toast behaves, even if you kill the view / activity, the toast will still show to the user, but I still want to use Snackbar and also need to call completeUpdate() if download is finished, where my user still has the freedom to browse the app and not crash.
Snackbar needs CoordinatorLayout to be shown (most common usage), it's just a View, so when you want to show it, you need active GUI on foreground. when you start app update and move somewhere where Snackbar can't be shown then your Exception occurs
Toast is kind of system service with possibility to be shown on top of everything, completely different approach. for showing Toast you need only Context
I am creating an app MainActivity that can calculate a report from its database to be shown in ReportActivity. All report calculation is done in ReportActivity.onCreate().
When the user click on MainActivity-s menu "generate report" the menĂ¼ remains open for 2 secs until ReportActivity.onCreate() has finished and the report becomes visible.
What is the easiest way to give the user some visual feedback?
I already found ProgressDialog onCreate that shows a progressdialog while doing all calculation in an AsyncTask.
I wonder if there is some easier way to give the user some visual feedbak that the menue was successfully clicked and that the device has not crashed.
in ms windows i would use a waitcursor (hour-glass)
I already tried to open a ProgressDialog() in oncreate of the ReportActivity
final ProgressDialog progressDialog = ProgressDialog.show(this, "MY Dialog", "Please wait...");
but it is not shown at all.
Update final solution:
As the answerss suggested I implemented an AsyncTask for the processing following this tutorial
based on this codesample
You need to move your long-running code into a background thread. Long-running code on the UI thread will lock up the UI, which causes the user to think the app is frozen/crashing. Look into using AsyncTask. This allows you to run a process on a background thread and also give visual feedback to let the user know that your app is working.
Design a layout with ProgressDialog. Use setContentView(Progressdialog). Count time for 2-4 seconds (you choice) again set your older layout in setContentView. Why don't you use AsyncTask?
Use a bar or circle activity indicator. From the official design guide:
Activity indicators are for operations of an indeterminate length.
They ask users to wait a moment while something finishes up, without
getting into specifics about what's happening behind the scenes.
I want to launch a dialog from a service that hovers over whatever the user is currently looking at. The dialog gets launched like this: service gets trigger to open dialog > start transparent activity > transparent activity shows dialog.
My problem is when the user opens the app, launches into the main menu, and then presses HOME to leave. By pressing HOME, it leaves the main menu activity on pause, not destroyed, and when the service starts the dialog, the main menu gets shown underneath the transparent activity; causing the dialog to loose the affect of hovering over whatever the user is looking at.
How can make it so that the transparent activity gets opened independently of any other activities in the app? The only way to prevent this currently is to finish all the activities when they are paused; but this is impractical.
This is the last thing we want. :-)
1. Dialog boxes from Services
One of the best experiences in mobile devices, IMHO, and Android in particular, is that after decades, we got rid of system-wide, pesky alert dialogs. Finally, best practices [1, 2] for user interaction gave us a way to avoid the infamous disseminate use of MessageBox(hwnd, lpText, lpCaption, uType), competing for focus and for the attention of the poor user. See video parody above.
The reason it feels awkward to start a dialog from a Service is exactly because it is supposed to be a background task, without user interaction. By concept, you shouldn't be doing this. That's the reason why we see these tricks (transparent activities, what a silly thing) to cheat the design guidelines in the first place. They are bad, they disrupt the user experience, they steal focus and attention. They disrupt our work.
2. Use notifications instead
Whenever you want to notify a user of something from the background, when the user is somewhere else, you use a notification. It's the default pattern, and it doesn't bother the user.
Therefore, you should be sending notifications from your Service.
From there, if the user is interested, then he will touch the notification and you start your own activity, possibly resuming your activity, creating a new one, and then using a dialog requesting action to be performed, or whatever you want to do.
3. Finally, do NOT use FLAG_ACTIVITY_MULTIPLE_TASK
You should not, ever, use this flag unless you have carefully read and fully understood the documentation, and the implications of using that flag.
Do not use this flag unless you are implementing your own top-level application launcher.
(...)
Because the default system does not include graphical task management, you should not use this flag unless you provide some way for a user to return back to the tasks you have launched.
Really. In this case, just don't.
You may consider using alertDialog with TYPE_SYSTEM_ALERT instead of activity:
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("Are you sure?")
.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
Please note that you have to use the following permission:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Found this out myself, just add the Intent.FLAG_ACTIVITY_MULTIPLE_TASK flag to the launch Intent; of course in conjunction with the Intent.FLAG_ACTIVITY_NEW_TASK flag.
I have an activity with in which there is a async task that will do some download stuff. AT the time of downlaoding it will show a loading dialog.
My problem is, it worked fine for me when me doing it in only one orentiaon. But when i rotate at the time of download, it shows window leaked and will crash at the
dialog.cancel in my post excute.
From my study on it more i understood it due the change in the context when device is rotated.
That is when a device is rotated the activity will be recreated so the context will be changed.
But i have created the dialog with old one and that wasn't the current context. So when i cancel it it shows error
What is the solution for this, any idea frnds.
Me using honeycomb, me tried but with fragment but didnt get a good sample for that. Me now mainly trying that,
if anyone can give me some links for that it will be
great
First of all: open your dialog using the showDialog method (there are a lot of examples in the official documentation). If you do so, the activity will take care of dismissing the dialog on destroy, and re-showing it after the activity has been recreated.
Also... if the dialog shows a progress bar (not a wheel), you will want to update the progress of the dialog after orientation changes. In order to do so, I recommend to use the onRetainNonConfigurationInstance to return the current state of the dialog and/or the activity itself. Then, you can use getLastNonConfigurationInstance to recover that state. Google about those two methods if you want to see examples.
Another thing to keep in mind: if you are updating the state of the dialog an/or any other UI element from the AsyncTask, you must be aware that after the activity is recreated, the AsyncTask may be pointing to the wrong UI references. In order to handle this, you can create a proxy class (Proxy design pattern) to detach the AsyncTask progress notifications from the current UI elements.
When is it preferable to use a Dialog box as opposed to an Activity in Android? From my understanding, anything you can do with a Dialog box you can also accomplish with an Activity. Are there any tasks that can only be accomplished by an Activity or a Dialog?
Is what you're doing worth a new Activity? Do you need to be able to start it through an intent? Do you really need to create a new Java class for it?
If it's a straightforward dialog that displays a text and has simple hooks for positive/negative/dismissal functions, definitely use a dialog.
If you have something complex, you may want to go for a full-blown activity.
Well why exactly would you want to start a new activity just to ask the user "Are you sure? Y/N"? Dialogs generally run on top of the activity, and are usually smaller activities or notifications for the user. They also usually have something to do with the process of the app running. It helps make things simpler to open a dialog to prompt the user on top of your activity, than to start a new activity atop your current activity.
I went for Activities when I needed an user interaction that needs backstack, navigation, lifecycle and callable features.. else with dialogs. Being from the WebApp world I ask whether I would have needed a new server page or a pop window for an interaction and the decision in Andoird world becomes easier!
If newServer page then mostly Activity
elseIf popUpWindow then dialog
I created my android application in one fragment with nested alert dialog, so far my application still running well in handle those nested dialog, and I think dialog is less consuming memory than an activity