问题
i have an app that contains a dialog
i want to close this dialog after x second, when user haven't any interact with app, like volume seekbar popup(that's open when the volume button clicked, and closed after 2 second of inactivity). what is the simplest way to implement this?
thank you
回答1:
You could for example use a Handler and call its .removeCallbacks() and .postDelayed() method everytime the user interacts with the dialog.
Upon an interaction, the .removeCallbacks() method will cancel the execution of .postDelayed(), and right after that, u start a new Runnable with .postDelayed()
Inside this Runnable, you could close the dialog.
// a dialog
final Dialog dialog = new Dialog(getApplicationContext());
// the code inside run() will be executed if .postDelayed() reaches its delay time
final Runnable runnable = new Runnable() {
@Override
public void run() {
dialog.dismiss(); // hide dialog
}
};
Button interaction = (Button) findViewById(R.id.bottom);
final Handler h = new Handler();
// pressing the button is an "interaction" for example
interaction.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
h.removeCallbacks(runnable); // cancel the running action (the hiding process)
h.postDelayed(runnable, 5000); // start a new hiding process that will trigger after 5 seconds
}
});
For tracking user interaction, you could use:
@Override
public void onUserInteraction(){
h.removeCallbacks(runnable); // cancel the running action (the hiding process)
h.postDelayed(runnable, 5000); // start a new hiding process that will trigger after 5 seconds
}
Which is available in your activity.
回答2:
I like to do this with AsyncTask:
class ProgressDialogTask extends AsyncTask<Integer, Void, Void> {
public static final int WAIT_LENGTH = 2000;
private ProgressDialog dialog;
public ProgressDialogTask(Activity activity) {
dialog = new ProgressDialog(activity);
}
@Override
protected void onPreExecute() {
dialog.setMessage("Loading");
}
@Override
protected Void doInBackground(final Integer... i) {
long start = System.currentTimeMillis();
while(!isCancelled()&&System.currentTimeMillis()-start< WAIT_LENGTH){}
return null;
}
@Override
protected void onPostExecute(final Void v) {
if(dialog.isShowing()) {
dialog.dismiss();
}
}
}
Then trigger it from your Activity on click:
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ProgressDialogTask task = new ProgressDialogTask(this);
task.execute(0);
}
});
If you need better precision you can also use System.nanoTime()
回答3:
I am also new at android, but I recommend creating a timer, and when lets say the timer t is greater than or equal to 2, then you do something. It would look kind of like this
if (t >= 2.0){
//Do whatever you want it to do
}
This may not work for your purposes, but it's just something that may require less lines of code in the end. (as I always say, less code is more code) I know that timers are basically easy to make, but I have never used one in an app. I wouldn't specifically know how to make the timer, but I'm sure you can find a tutorial on youtube.
回答4:
This is the question that came up when I was looking up things regarding timing out. I have implemented an answer which uses AsyncTask
, Handler
, and Runnable
. I am providing my answer here as a potential template for future answer searchers.
private class DownloadTask extends AsyncTask<Void, CharSequence, Void> {
//timeout timer set here for 2 seconds
public static final int timerEnd = 2000;
private Handler timeHandler = new Handler();
@Override
protected void onPreExecute() {
ProgressDialog dProgress = new ProgressDialog(/*Context*/);
dProgress.setMessage("Connecting...");
dProgress.setCancelable(false);
dProgress.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Dismissing dProgress
dialog.dismiss();
//Removing any Runnables
timeHandler.removeCallbacks(handleTimeout);
//cancelling the AsyncTask
cancel(true);
//Displaying a confirmation dialog
AlertDialog.Builder builder = new AlertDialog.Builder(/*Context*/);
builder.setMessage("Download cancelled.");
builder.setCancelable(false);
builder.setPositiveButton("OK", null);
builder.show();
} //End onClick()
}); //End new OnClickListener()
dProgress.show();
} //End onPreExecute()
@Override
protected Void doInBackground(Void... params) {
//Do code stuff here
//Somewhere, where you need, call this line to start the timer.
timeHandler.postDelayed(handleTimeout, timerEnd);
//when you need, call onProgressUpdate() to reset the timer and
//output an updated message on dProgress.
//...
//When you're done, remove the timer runnable.
timeHandler.removeCallbacks(handleTimeout);
return null;
} //End doInBackground()
@Override
protected void onProgressUpdate(CharSequence... values) {
//Update dProgress's text
dProgress.setMessage(values[0]);
//Reset the timer (remove and re-add)
timeHandler.removeCallbacks(handleTimeout);
timeHandler.postDelayed(handleTimeout, timerEnd);
} //End onProgressUpdate()
private Runnable handleTimeout = new Runnable() {
public void run() {
//Dismiss dProgress and bring up the timeout dialog
dProgress.dismiss();
AlertDialog.Builder builder = new AlertDialog.Builder(/*Context*/);
builder.setMessage("Download timed out.");
builder.setCancelable(false);
builder.setPositiveButton("OK", null);
builder.show();
}
}; //End Runnable()
} //End DownloadTask class
To those somewhat new to using AsyncTask
, you must make a DownloadTask object
and call .execute()
.
For example:
DownloadTask dTaskObject = new DownloadTask();
dTaskObject.execute();
I actually also took this code further than what you see by having all my doInBackground()
code be done via a function, so I actually had to call onProgressUpdate()
and other functions using the DownloadTask
object.
来源:https://stackoverflow.com/questions/18137371/how-to-close-a-dialog-after-certain-seconds-of-inactivity