如何使用自己的“动作”按钮关闭小吃店?


93

Android设计支持库现在包括对Snackbar的支持。

我使用以下代码创建一个:

Snackbar.make(findViewById(R.id.root_layout), result, Snackbar.LENGTH_LONG)
        .setAction("Dismiss", new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        }).show();

可以通过滑动来关闭快餐栏。但是,我也想使用它自己的动作按钮(使用setAction函数创建)将其关闭。

但是似乎没有可用的功能可以做到这一点。


4
作为来这里的人的注意,SnackbarGoogle进行“撤消”操作违反了Google材料设计指南
Loyalar '16

Answers:


145

对于Java,

.make方法返回一个Snackbar对象。保存该对象的实例final。然后,在中onClick(),致电.dismiss

final Snackbar snackBar = Snackbar.make(findViewById(android.R.id.content), "Snackbar Message", Snackbar.LENGTH_LONG);

        snackBar.setAction("Action Message", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Call your action method here
                snackBar.dismiss();
            }
        });
        snackBar.show();

对于科特林,

        Snackbar.make(
            findViewById(android.R.id.content),
            "Snackbar Message",
            Snackbar.LENGTH_INDEFINITE
        ).setAction("Action Message") {
            // Call action functions here
        }.show()

2
如果我使用FloatingActionButton在协调器布局中执行此操作,则FloatingActionButton不会下降。
Vinay W

60
单击操作时,默认情况下将关闭快餐栏。无需显式调用dismiss方法。
Mark Buikema

9
@MarkBuikema稍后添加了此功能。在提出问题时,这还不是小吃店的愚蠢行为。
EE66 2015年

肯尼迪国际机场(JFYI),如果动作OnClickListenernull
crgarridos '18

从今天开始,此代码将使用不同的事件值调用两次dismiss,一次用于单击操作,另一次用于以编程方式调用dissmiss()。
胡安

52

实施点击动作并将其清空。点击空的点击动作将关闭快餐栏。

Snackbar.make(coordinatorLayoutView, "Service Enabled", Snackbar.LENGTH_LONG)
    .setAction("DISMISS", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        }
    })
    .show();

您可以传递null给侦听器,而无需创建实际实例
ccpizza

11

使用Snackbar.LENGTH_LONG时,不需要操作按钮即可关闭,第二秒钟后自动关闭。您应该使用以下代码:

 Snackbar snackbar = Snackbar.make(relativeLayout, "Your Message", Snackbar.LENGTH_INDEFINITE);
            snackbar.setAction("dismiss", new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    snackbar.dismiss();
                }
            });

            snackbar.show();

注意这一行

Snackbar.LENGTH_INDEFINITE

5

这是一个古老的问题,但是我只想分享一下有关Snackbar上类似功能的我自己的经验。因此,我们为应用程序设计了一个功能,即应该无限期显示小吃栏,并且用户应该可以关闭它。我们的小吃店只能通过点击将其解雇。

唯一对我们有用的解决方案是最后(我在这里使用Retrolambda,但也可以使用标准View.OnClickListener):

final Snackbar snack = ... /* create proper snackbar as alway */
snack.getView().setOnClickListener(v -> snack.dismiss());

注意中间的getView()调用。


您在哪里读到“ Google不建议您在Snackbars内部建议关闭或取消操作”?我想读的原因....
约瑟夫

@JoseF请检查问题本身下的第一条评论;)它在材料设计指南中:material.io/guidelines/components / ...(“ 0-1行动,不撤消或取消”)
Dariusz Wiechecki

3

Snackbar(来自“ com.android.support:design:23.2.1”)支持多种类型的关闭操作。您可以使用event创建一个简单的过滤器,例如以下示例:

Snackbar.make(view, wornMessage, Snackbar.LENGTH_LONG).setActionTextColor(context.getResources().getColor(R.color.primary))
    .setCallback(new Snackbar.Callback() {
        @Override
        public void onShown(Snackbar snackbar) {
            super.onShown(snackbar);
        // when snackbar is showing
        }

        @Override
        public void onDismissed(Snackbar snackbar, int event) {
            super.onDismissed(snackbar, event);
            if (event != DISMISS_EVENT_ACTION) {
               //will be true if user not click on Action button (for example: manual dismiss, dismiss by swipe
            }
        }
    })
    .setAction("Undo, view1 -> {
        // if user click on Action button
}).show();

Snackbar的解雇类型:

/** Indicates that the Snackbar was dismissed via a swipe.*/
public static final int DISMISS_EVENT_SWIPE = 0;
/** Indicates that the Snackbar was dismissed via an action click.*/
public static final int DISMISS_EVENT_ACTION = 1;
/** Indicates that the Snackbar was dismissed via a timeout.*/
public static final int DISMISS_EVENT_TIMEOUT = 2;
/** Indicates that the Snackbar was dismissed via a call to {@link #dismiss()}.*/
public static final int DISMISS_EVENT_MANUAL = 3;
/** Indicates that the Snackbar was dismissed from a new Snackbar being shown.*/
public static final int DISMISS_EVENT_CONSECUTIVE = 4;

PS在示例代码中使用了lambda表达式(由RetroLambda提供)


问题不在于解雇处理程序。问题是如何在单击按钮时关闭。
令人难以置信的

2

我有同样的问题。当我使用.dismiss()时,动画看起来有所不同,并且存在两个问题:

  1. FAB不再下降
  2. SnackBar本身不会像单击一样滑落

通过查看Snackbar的原始Android源代码,我发现了以下解决方案:

View snackbarView = snackbar.getView();
Button snackbarActionButton = (Button) snackbarView.findViewById(android.support.design.R.id.snackbar_action);
//snackbarActionButton.setSoundEffectsEnabled(false); // might be considered in order not to have a confusing sound because nothing was clicked by the user

然后,我将在SnackBarActionButton上调用.performClick

snackBarActionButton.performClick();

链接到Snackbar的Android源代码:https ://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/design/src/android/support/design/widget/Snackbar.java


对我来说没有任何意义。如果实际上单击一个按钮,为什么要调用performClick()?那似乎是胡说八道。
令人难以置信的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.