【问题标题】:Android Support Library Snackbar with indefinite length长度不定的 Android 支持库 Snackbar
【发布时间】:2015-09-14 10:40:53
【问题描述】:

我看到 Snackbar 在确定其在屏幕上显示的长度时只会占用 LENGTH_LONG 或 LENGTH_SHORT。

我希望它一直显示,直到有人将其从屏幕上滑出。这适用于您遇到持续错误的某些情况,例如当您没有互联网并且您希望在选择 LENGTH_LONG 时通知用户而不会在 2750 毫秒后从屏幕上消失。

当然,我可以将 setDuration 设置为非常长的毫秒值,但有没有办法将其设置为在用户关闭它之前不会消失?

【问题讨论】:

  • 值得注意的是,Material Design 的指导方针明确指出 Snackbars 是瞬态视图元素。这意味着它们在任何情况下都不应该卡在屏幕上,因为它们会挡住屏幕上的其他元素。
  • 同意和好的观点。您是否认为必须在我的 UI 上的视图中构建无互联网消息?如果小吃店不是正确的工具,如何通知用户“没有互联网”?
  • 如果活动/永久连接真的很重要,我有时会将工具栏更改为另一种颜色,更改图标或显示通知。如果它只是一个加载数据的 Recycler/ListView,你应该在那里显示消息(带有刷新按钮),直到它被另一个片段替换。
  • 使用带有用户输入的snackbar androidbycode.wordpress.com/2015/06/06/…

标签: android snackbar


【解决方案1】:

根据文档,您可以在设置持续时间时使用LENGTH_INDEFINITE 标志:

Snackbar.make(view, "my snackbar", Snackbar.LENGTH_INDEFINITE).show();

【讨论】:

  • 你打算如何关闭它?你不能。您需要对快餐栏的引用才能稍后将其关闭。
  • 当然。但是你可以用最简单的方法来做。
【解决方案2】:

我正在使用 com.android.support:appcompat-v7:26.1.0 并且 Snackbar.LENGTH_INDEFINITE 工作正常。示例可能如下所示:

private HashMap<Long, Snackbar> mTokenSnackbarMap = new LinkedHashMap<>();

private void dropPoint(@NonNull Location location) {
    final Long token = SystemClock.elapsedRealtime();
    // <submitPoint> is the callback to be executed
    // at a time in the future, if the "cancel" button
    // of the Snackbar isn't clicked until that time.
    Runnable submitPoint = () -> {
        Snackbar bar = mTokenSnackbarMap.get(token);
        if (bar != null) {
            // "cancel" button of the Snackbar wasn't clicked,
            // but our time is up. Dismiss the Snackbar.
            bar.dismiss();
            mTokenSnackbarMap.remove(token);
            Log.i(TAG, "dropPoint: dismiss snackbar");
        }
        mDatabase.add(Point.Factory.create(uid, location));
        Log.i(TAG, "dropPoint: addPoint");
    };

    // The indefinite Snackbar allowing arbitrary cancellation.
    Snackbar snackbar = Snackbar.make(mMainView, R.string.point_pending, Snackbar.LENGTH_INDEFINITE)
        .setAction(R.string.cancel, (v) -> {
                    mTokenSnackbarMap.remove(token);
                    mUiHandler.removeCallbacks(submitPoint, token);
                    Log.i(TAG, "dropPoint: cancel snackbar");
                });
    mTokenSnackbarMap.put(token, snackbar);
    mUiHandler.postAtTime(submitPoint, token,
                SystemClock.uptimeMillis() + Constants.POINT_DELAY_MILLIS);
    Log.i(TAG, "dropPoint: postAtTime");
    snackbar.show();
}

【讨论】:

    【解决方案3】:

    Snackbars 会自动在屏幕上超时。它们不应持久或堆叠,因为它们位于屏幕上的其他元素之上。

    因此,Snackbars 似乎不适合通知用户的用例,直到用户采取措施将其关闭。

    相反,您应该考虑使用 Dialog

    对话框始终保持焦点,直到关闭或采取了必要的操作

    更多信息请参考:

    Material Design Guidelines - Snackbars

    Material Design Guidelines - Dialogs

    【讨论】:

      【解决方案4】:

      最新版本的 Android 支持库 (22.2.1),现在包括 LENGTH_INDEFINITE

      以下将显示 Snackbar,直到它被关闭或显示另一个 Snackbar。

      Snackbar.make(view, "Your Snackbar", Snackbar.LENGTH_INDEFINITE)
              .setAction("Your Action", null).show();
      

      【讨论】:

      • 在模拟器中运行良好......但至少在我的设备(带有 Android 7.0 的 Moto G4 Plus)上,没有显示快餐栏。所以归结为@Edward 作为对问题本身的评论添加的内容:material design 不想要这个
      【解决方案5】:

      更新:如前所述,随着 Android 支持库 22.2.1 的发布,现在可以使用 LENGTH_INDEFINITE 标志

      使用 Android 设计支持库中的官方实现时,无法设置 Snackbar 的无限期显示。

      虽然这样做可能会违反 Snackbar 的 Material Design 理念,但有 3rd 方的 Snackbar 实现确实允许这样做。这是一个例子:

      https://github.com/nispok/snackbar

      此项目允许显示持续时间的以下值:

      LENGTH_SHORT: 2s
      LENGTH_LONG: 3.5s (default)
      LENGTH_INDEFINTE: Indefinite; ideal for persistent errors
      

      请注意,由于官方 Snackbar 实施的发布,该项目不再被开发。

      【讨论】:

      • 最近发布的 support-design 22.2.1 现在可以实现了。
      猜你喜欢
      • 2016-05-09
      • 2015-08-18
      • 2015-10-19
      • 2015-11-18
      • 2016-02-07
      • 1970-01-01
      • 2015-08-13
      • 2023-04-06
      • 1970-01-01
      相关资源
      最近更新 更多