触摸屏幕任一位置重置倒计时

需求:界面上有一个倒计时,倒计时结束返回主界面,用户触摸屏幕即刻重置倒计时

解决方案:
1.在activity中,重写dispatchTouchEvent方法,重置倒计时
2.在fragment中,写一个监听,让fragment去监听dispatchTouchEvent
3.在dialog中,继承dialog,重写dispatchTouchEvent方法

倒计时:CountDownTimer:

private long mTotalTime = 90 * 1000;
private long mTickTime = 1 * 1000;

private CountDownTimer mCountDownTimer;
/**
* 启动倒计时
*/
public void startCountDown() {
    if (mCountDownTimer != null) {
        mCountDownTimer.start();
    } else {
        mCountDownTimer = new CountDownTimer(mTotalTime, mTickTime) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTextView.setText(millisUntilFinished / 1000 + "s");
            }

            @Override
            public void onFinish() {
                mTextView.setText("onFinish");
            }
        };
        mCountDownTimer.start();
    }
}

/*
* 重启倒计时
*/
public void restartCountDown() {
    if (mCountDownTimer != null) {
        mCountDownTimer.cancel();
        mCountDownTimer.start();
    } else {
        startCountDown();
    }
}

在activity中,dispatchTouchEvent方法重启倒计时

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    restartCountDown();
    return super.dispatchTouchEvent(ev);
}

在dialog中,先查看源码:

/**
 * Called to process touch screen events.  You can override this to
 * intercept all touch screen events before they are dispatched to the
 * window.  Be sure to call this implementation for touch screen events
 * that should be handled normally.
 * 
 * @param ev The touch screen event.
 * 
 * @return boolean Return true if this event was consumed.
 */
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (mWindow.superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}
/**
 * Called when a touch screen event was not handled by any of the views
 * under it. This is most useful to process touch events that happen outside
 * of your window bounds, where there is no view to receive it.
 * 
 * @param event The touch screen event being processed.
 * @return Return true if you have consumed the event, false if you haven't.
 *         The default implementation will cancel the dialog when a touch
 *         happens outside of the window bounds.
 */
public boolean onTouchEvent(MotionEvent event) {
    if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {
        cancel();
        return true;
    }
    
    return false;
}

Dialog已经消费touch事件,现新建一个DispatchDialog继承Dialog,重写dispatchTouchEvent方法:

import android.app.Dialog;
import android.content.Context;
import android.view.MotionEvent;

/**
 * Created by ZP on 2016/11/26.
 */

public class DispatchDialog extends Dialog {


    public DispatchDialog(Context context) {
        super(context);
    }

    public DispatchDialog(Context context, int themeResId) {
        super(context, themeResId);
    }

    protected DispatchDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (mOnTouchListener != null) {
            mOnTouchListener.onTouch(ev);
        }
        return super.dispatchTouchEvent(ev);
    }


    public interface onTouchListener{
        void onTouch(MotionEvent ev);
    }

    private onTouchListener mOnTouchListener;

    public void setOnTouchListener(onTouchListener onTouchListener) {
        mOnTouchListener = onTouchListener;
    }
}

如何调用:

private DispatchDialog mDialog;
mDialog = new DispatchDialog(MainActivity.this);
mDialog.setOnTouchListener(new DispatchDialog.onTouchListener() {
    @Override
    public void onTouch(MotionEvent ev) {
        restartCountDown();
    }
});
mDialog.setCanceledOnTouchOutside(false);
mDialog.show();

总结:
读者自行尝试验证PopupWinodow

你可能感兴趣的:(触摸屏幕任一位置重置倒计时)