如何在Android中几秒钟后隐藏消息

时间:2017-09-29 18:33:48

标签: java android notifications postdelayed

我向用户显示一条消息通知并在几秒钟后隐藏该通知,并且我正在使用postDelayed()来实现此功能,但问题是当我在隐藏第一个消息之前用新消息更新通知时,我需要重置/重启计时器。我无法找到任何方法来实现这一点,因为removeCallbacks()只删除待处理的任务。

每当我点击按钮时都会显示新消息时,我会使用新消息从showNotification()拨打MyClass。现在,如果我在4秒内再次点击该按钮(假设x秒)(隐藏旧通知消息之前)。没有办法取消旧的postDelayed或重启计时器到4秒,它会在4-x秒后隐藏我的新通知。

MyClass.java

...
// On Button Click - everytime a different message

MyNotification obj = new MyNotification();
obj.showNotification(msg);
...

MyNotification.java

public class MyNotification
{
    ...
    ...
    private static TextView textview1;
    private static MyNotification notification;

    @Override
    protected void onFinishInflate()
    {
        super.onFinishInflate();

        notification = (MyNotification) this.findViewById(R.id.notification_bar);
        textview1 = (TextView) this.findViewById(R.id.textview_notification);
    }

    Runnable hideNotification = new Runnable() {
        @Override
        public void run() {
            textview1.setVisibility(GONE);
            notification.setVisibility(GONE);
        }
    };

    public void showNotification(String msg)
    {

        textview1.setText(msg);
        textview1.setVisibility(VISIBLE);
        notification.setVisibility(VISIBLE);

        // Hide Toast notification after few secs
        notification.postDelayed(hideNotification, 4000);
    }

    ...
}

3 个答案:

答案 0 :(得分:0)

只需使用处理程序并根据需要添加或删除回调。我为此写了一堂课。我将与您分享。

   /**
     * Created with IntelliJ IDEA.
     * User: App Studio 35
     * Date: 5/17/13
     * Time: 1:53 PM
     * To change this template use File | Settings | File Templates.
     */

    public class TimeOutWatcher {

    /*//////////////////////////////////////////////////////////
    // MEMBERS
    *///////////////////////////////////////////////////////////
    private ITimeOutWatcher mTimeOutHandler = null;
    private Handler mHandler = null;
    private long mTimeOutMilliseconds;


    /*//////////////////////////////////////////////////////////
    // Runnable
    *///////////////////////////////////////////////////////////
    private Runnable mTimeoutRunnable = new Runnable() {
        @Override
        public void run() {
            //If stopTimeOutWatch has not been called then trigger TimeOutOccurred
            if(mTimeOutHandler != null){
                mTimeOutHandler.TimeOutOccurred();
            }

            //Remove callback to avoid duplicate triggers
            mHandler.removeCallbacks(mTimeoutRunnable);
        }
    };


   /*//////////////////////////////////////////////////////////
   // METHODS
   *///////////////////////////////////////////////////////////
    /**
     * Set TimeOutListener to trigger when timeout occurs
     *
     * @param listener of type ITimeOutWatcher
     */
    public void setTimeOutListener(ITimeOutWatcher listener){
        mTimeOutHandler = listener;
    }
    /**
     * Called when needing a timeout to occur based on the passed number of
     * Milliseconds. Performs a postDelay to trigger calling of TimeOutOccurred.
     * Must call stopTimeOutWatch after your waiting process is complete and
     * before this delay trigger happens if you want to avoid
     * getting a TimeOutOccurred
     *
     * @param timeOutMilliseconds
     */
    public void startTimeOutWatch(long timeOutMilliseconds){
        mTimeOutMilliseconds = timeOutMilliseconds;
        mHandler = new Handler(Looper.getMainLooper());
        mHandler.postDelayed(mTimeoutRunnable, timeOutMilliseconds);
    }
    public void resetTimeOutWatch(long timeOutMilliseconds){
        stopTimeOutWatch();
        startTimeOutWatch(timeOutMilliseconds);
    }
    public void resetTimeOutWatch(){
        stopTimeOutWatch();
        startTimeOutWatch(mTimeOutMilliseconds);
    }
    /**
     * Used to cancel TimeOut from happening
     * Call when process that you are waiting on is complete
     * to avoid TimeOutOccurred
     */
    public void stopTimeOutWatch(){
        if(mTimeoutRunnable != null){
            if(mHandler != null){
                mHandler.removeCallbacks(mTimeoutRunnable);
            }
        }
    }


    public interface ITimeOutWatcher {

        /**
         * Called when TimeOutWatcher exceeds requested TimeOut Period
         */
        void TimeOutOccurred();

    }
}

用法很简单,只需创建TimeOutWatcher的实例并在所需时间内启动超时。如果您需要取消它,请在需要重置然后调用重置时调用停止。简单。希望有所帮助。

答案 1 :(得分:0)

一个简单的解决方案是,如果在通知已经显示时单击按钮,则可以防止重复通知。

通过在启动runnable之前检查视图的可见性,可以轻松完成此操作:

public void showNotification(String msg)
    {

        if (textview1.getVisibility() != View.VISIBLE) {
            textview1.setText(msg);
            textview1.setVisibility(VISIBLE);
            notification.setVisibility(VISIBLE);

            // Hide Toast notification after few secs
            notification.postDelayed(hideNotification, 4000);
        }
    }

答案 2 :(得分:0)

当然,你可以取消runnable并发布一个新的:使用View.removeCallbacks(Runnable)

所以我认为你的代码会改为:

public void showNotification(String msg)
{

    textview1.setText(msg);
    textview1.setVisibility(VISIBLE);
    notification.setVisibility(VISIBLE);

    // Remove the existing hide instruction
    notification.removeCallbacks(hideNotification);
    // Hide Toast notification after few secs
    notification.postDelayed(hideNotification, 4000);
}