使用 SnackBar 实例再次显示

Posted

技术标签:

【中文标题】使用 SnackBar 实例再次显示【英文标题】:Use SnackBar instance to show again & again 【发布时间】:2016-04-05 23:36:51 【问题描述】:

步骤

我可以像这样保存 SnackBar 实例:

mSnackBar = Snackbar.make(view, R.string.snack_text, Snackbar.LENGTH_INDEFINITE);

第一次很容易使用这个来显示:mSnackBar.show();

问题

但是在我清除这个 Snack 之后使用这个:mSnackBar.dismiss()

它不会在 LOLLIPOP 设备中再次显示,它会在 JELLYBEAN 模拟器中再次显示(当需要时使用 show()预期的行为。

问题

请帮我找出 LOLLIPOP 设备在此过程中的错误或缺失?

【问题讨论】:

所以在 jellybean 中你关闭,然后自动再次显示或者你做一些动作来显示? 是的,我执行了一个操作,其中再次调用 show() 并在 JB 设备中再次显示小吃......这在 LOLLIPOP 中不正确 【参考方案1】:

查看源代码,我可以看到“解雇小吃店”将使 currentSnackBar 无效。

源代码 - SnackBar

public void dismiss(Callback callback, int event) 
    synchronized (mLock) 
        if (isCurrentSnackbarLocked(callback)) 
            cancelSnackbarLocked(mCurrentSnackbar, event);
         else if (isNextSnackbarLocked(callback)) 
            cancelSnackbarLocked(mNextSnackbar, event);
        
    


/**
 * Should be called when a Snackbar is no longer displayed. This is after any exit
 * animation has finished.
 */
public void onDismissed(Callback callback) 
    synchronized (mLock) 
        if (isCurrentSnackbarLocked(callback)) 
            // If the callback is from a Snackbar currently show, remove it and show a new one
            mCurrentSnackbar = null;
            if (mNextSnackbar != null) 
                showNextSnackbarLocked();
            
        
    

因此,当您在同一实例上进行表演时,此代码将运行

public void show(int duration, Callback callback) 
    synchronized (mLock) 
        if (isCurrentSnackbarLocked(callback)) 
            // Means that the callback is already in the queue. We'll just update the duration
            mCurrentSnackbar.duration = duration;

            // If this is the Snackbar currently being shown, call re-schedule it's
            // timeout
            mHandler.removeCallbacksAndMessages(mCurrentSnackbar);
            scheduleTimeoutLocked(mCurrentSnackbar);
            return;
         else if (isNextSnackbarLocked(callback)) 
            // We'll just update the duration
            mNextSnackbar.duration = duration;
         else 
            // Else, we need to create a new record and queue it
            mNextSnackbar = new SnackbarRecord(duration, callback);
        

        if (mCurrentSnackbar != null && cancelSnackbarLocked(mCurrentSnackbar,
                Snackbar.Callback.DISMISS_EVENT_CONSECUTIVE)) 
            // If we currently have a Snackbar, try and cancel it and wait in line
            return;
         else 
            // Clear out the current snackbar
            mCurrentSnackbar = null;
            // Otherwise, just show it now
            showNextSnackbarLocked();
        
    

如果它为空,则不会显示小吃栏。

解决方案

您不应该在 SnackBar 上调用dismiss,当持续时间到期或单击操作按钮时,它会自动隐藏。只需再次调用 show 方法,而无需首先调用 dismiss 再次显示 SnackBar。

【讨论】:

我深入研究了代码并检查了如果附加了回调,则调用了这个 nullify 语句。而且我没有使用任何回调 如果你查看 show() 方法,你会看到如果你不提供回调是由框架提供的。 谢谢这是正确的解决方案,我做了一个解决方法来关闭并再次显示 SnackBars。需要注意的是,这也适用于新的小吃店取代旧的.. 和 API 21+

以上是关于使用 SnackBar 实例再次显示的主要内容,如果未能解决你的问题,请参考以下文章

重新打开应用程序后,Snackbar 不再出现

显示没有 CoordinatorLayout 的 Snackbar

如何在颤动中显示 SnackBar?

Snackbar使用详解及其相关框架TSnackbar

Android Snackbar 的使用

Material Design ,Snackbar的使用