在片段中的 OnTouchEvent 之后重新启动 Dialog window 中的 CountDownTimer

Restarting a CountDownTimer in a Dialog window after an OnTouchEvent in a fragment

我有一个关闭对话框弹出窗口的 CountDownTimer window。如果用户触摸屏幕,我希望这个计时器重新启动。这是我目前所拥有的,

public class dataCapture extends Fragment implements OnClickListener {
...
MotionEvent event;
View.OnTouchListener touchListener;

@Override
public void onCreate(Bundle savedDataEntryInstanceState) {
    super.onCreate(savedDataEntryInstanceState);
    setRetainInstance(true);
}
...
@Override
public View onCreateView
@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btnHelpFilexml:
            openHelpDialog();
            break;
        ...
    }

private void openHelpDialog() {
    Button btnCloseWindow;
    final Dialog helpDialog;
    TextView tvHelpDialogTitle, tvHelpDialogBody;
    helpDialog = new Dialog(getActivity(), android.R.style.Theme_Translucent);
    helpDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);


    helpDialog.setCancelable(true);
    helpDialog.setContentView(R.layout.help_dialog);

    tvHelpDialogTitle = (TextView) helpDialog.findViewById(R.id.tvHelpDialogTitle);
    tvHelpDialogTitle.setText("DataCapture Help");

    tvHelpDialogBody = (TextView) helpDialog.findViewById(R.id.tvHelpDialogBody);
    tvHelpDialogBody.setText("Start of help text\n" +
            "This is help text\n" +
            "\n" +
            "Here we go...\n" +
            ...
            "This is the end.");

    btnCloseWindow = (Button) helpDialog.findViewById(R.id.btnCloseWindow);
    btnCloseWindow.setText("Close");

    btnCloseWindow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            helpDialog.dismiss();
        }
    });
    CountDownTimer countDownTimer = new CountDownTimer(30000, 1000) {
        // new countDownTimer(30000, 1000) {//makes popup go away after 30 secs
        @Override
        public void onTick(long millisUntilFinished) {//Do something every second...
        }
        @Override
        public void onFinish() {//action at end of specified time
            helpDialog.dismiss();
        }
    }.start();
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction()==MotionEvent.ACTION_DOWN) {
            countDownTimer.cancel();
            countDownTimer.start();
        }
        return super.onTouchEvent(event);
    }
    helpDialog.show();
  }
}

如有任何关于如何最好地实现此功能的建议,我们将不胜感激。大量 TIA。

更新 知道了。下面的解决方案。谢谢

public class dataCapture extends Fragment implements OnClickListener {
...
private static final int COUNTDOWN_TIME_MS = 30000;
Handler handlerHelpDialogTimer;
Runnable runnableHelpDialogDismissCountdown;
Dialog helpDialog;

 private Dialog getHelpDialog() {
    Button btnCloseWindow;
    final Dialog helpDialog;
    TextView tvHelpDialogTitle, tvHelpDialogBody;
    helpDialog = new Dialog(getActivity(), android.R.style.Theme_Translucent);
    helpDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    helpDialog.setCancelable(true);
    helpDialog.setContentView(R.layout.help_dialog);
    tvHelpDialogTitle = (TextView) helpDialog.findViewById(R.id.tvHelpDialogTitle);
    tvHelpDialogTitle.setText("DataCapture Help");
    tvHelpDialogBody.setText("Start of help text\n" +
        "This is help text\n" +
        "\n" +
        "Wheee, here we go\n" +
        ...
        "this is the end.");
    btnCloseWindow = (Button) helpDialog.findViewById(R.id.btnCloseWindow);
    btnCloseWindow.setText("Close");
    btnCloseWindow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            helpDialog.dismiss();
        }
    });
    tvHelpDialogBody.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View tvHelpDialogBody, MotionEvent event) {
            cancelCountdown();
            startCountdown();
            return false;
        }
    });
    helpDialog.show();
    return (helpDialog);
}
private void showHelpDialog() {
    helpDialog = getHelpDialog();
    helpDialog.show();
    startCountdown();
}
synchronized private void startCountdown() {
    handlerHelpDialogTimer.postDelayed(getCountdownTask(), COUNTDOWN_TIME_MS);
}
synchronized private void cancelCountdown() {
    handlerHelpDialogTimer.removeCallbacks(runnableHelpDialogDismissCountdown);
    runnableHelpDialogDismissCountdown = null;
}
private Runnable getCountdownTask() {
    Runnable task = new Runnable() {
        @Override
        public void run() {
            if (helpDialog != null) helpDialog.dismiss();
        }
    };
    runnableHelpDialogDismissCountdown = task;
    return task;
}

放弃倒数计时器。而是使用处理程序,例如:

public class AwesomeActivity extends Activity {

  private static final int COUNTDOWN_TIME_MS = 300000;
  Handler handler;
  Runnable countDown;
  Dialog helpDialog;

  @Override public void onCreate(Bundle b) {
    super.onCreate(b);
    handler = new Handler();
  }

  /* call cancelCountdown() in onPause*  */

  private Dialog getHelpDialog() { return /* fill in the details */ }

  private void showHelpDialog() { 
    helpDialog = getHelpDialog();
    helpDialog.show();
    startCountDown();
  } 

  synchronized private void startCountDown() {
    handler.postDelayed(getCountdownTask(), COUNTDOWN_TIME_MS);
  } 

  synchronized private void cancelCountdown() {
    handler.removeCallbacks(countdown);
    countdown = null;
  }

 private Runnable getCountdownTask() {
    Runnable task = new Runnable() {
      @Override public void run() {
        if (helpDialog != null) helpDialog.dismiss();
      }
    };
    countDown = task;
    return task;
  } 
}

现在 onTouch(MotionEvent e) 您可以取消并开始倒计时。

我会留给你解决如何处理 onPauseonResume :)

此外,如果你真的想要,你可以覆盖 Dialog 并将 Handler 计时器倒计时逻辑放在 class 中,覆盖 show() 以启动倒计时,然后添加一个方法,例如 restartTimer() 你可以在 TOUCH_DOWN 之后调用。如果你这样做,你也可以在Dialog子class中覆盖onSaveInstanceStateonRestoreInstanceState来取消回调,存储剩余时间,然后拉出剩余时间并用剩余时间重新延迟倒计时。