如何在几秒钟不活动后关闭对话框?

时间:2013-08-08 22:35:31

标签: android dialog scheduling

我有一个包含对话框的应用

我希望在x秒之后关闭此对话框,此时用户没有与应用程序进行任何交互,例如音量搜索栏弹出窗口(单击音量按钮时打开,并且在2秒钟不活动后关闭)。 实现这个的最简单方法是什么?

谢谢

4 个答案:

答案 0 :(得分:6)

例如,每当用户与对话框交互时,您可以使用Handler并调用其.removeCallbacks()和.postDelayed()方法。

在进行交互时,.removeCallbacks()方法将取消.postDelayed()的执行,之后,你用.postDelayed()

启动一个新的Runnable

在此Runnable中,您可以关闭对话框。

    // 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
        }
    });

要跟踪用户互动,您可以使用:

@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
}

您的活动中有哪些内容。

答案 1 :(得分:1)

我喜欢用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();
        }

    }
}

然后点击您的活动触发它:

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);
    }
});

如果您需要更高的精度,您也可以使用System.nanoTime()

答案 2 :(得分:0)

我也是android的新手,但我建议创建一个计时器,当我们说计时器t大于或等于2时,你会做一些事情。看起来有点像这样

if (t >= 2.0){
//Do whatever you want it to do
}

这可能不适用于您的目的,但它最终可能需要较少的代码行。 (正如我经常说的,更少的代码是更多的代码)我知道定时器基本上很容易制作,但我从来没有在应用程序中使用过。我不会特别知道如何制作计时器,但我相信你可以在youtube上找到一个教程。

答案 3 :(得分:0)

这是我在查看有关超时的事情时提出的问题。我已经实现了一个使用AsyncTaskHandlerRunnable的答案。我在这里提供我的答案作为未来答案搜索者的潜在模板。

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

对于使用AsyncTask的新手,您必须制作DownloadTask object并致电.execute()

例如:

DownloadTask dTaskObject = new DownloadTask();
dTaskObject.execute();

我实际上也比你通过函数完成所有doInBackground()代码所看到的代码更进一步,所以我实际上必须使用{{1}调用onProgressUpdate()和其他函数对象。