104

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

7 回答 7

158

对于 Java,

.make方法返回一个Snackbar对象。通过 make 保存该对象的实例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();

对于 Kotlin,

        Snackbar.make(
            findViewById(android.R.id.content),
            "Snackbar Message",
            Snackbar.LENGTH_INDEFINITE
        ).setAction("Action Message") {
            // Call action functions here
        }.show()
于 2015-06-09T10:25:04.543 回答
55

实现一个点击动作并让它为空。点击空的点击动作将关闭snackbar。

Snackbar.make(coordinatorLayoutView, "Service Enabled", Snackbar.LENGTH_LONG)
                        .setAction("DISMISS", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                            }
                        })
                        .show();
于 2015-09-20T11:25:07.003 回答
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
于 2016-08-09T23:41:38.727 回答
9

这是一个老问题,但我只想分享我自己在 Snackbar 上的类似功能的经验。所以我们为我们的应用设计了一个设计,该小吃栏应该无限期地显示并且用户应该能够关闭它..但里面不应该有 DISMISS 按钮(谷歌不建议在小吃栏内进行 Dismiss 或 Cancel 操作)。我们的小吃店只需点击它就必须被解雇。

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

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

注意中间的getView()调用。

于 2017-02-17T11:25:24.840 回答
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)

于 2016-04-09T20:24:02.137 回答
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

于 2016-03-06T18:55:06.460 回答
-1

如果您想将snackbar 放在静态方法中,请使用它。

 public static  void showSnackbar(Activity activity,String msg){
        Snackbar snackBar = null;

        snackBar = Snackbar.make( ((activity.findViewById(android.R.id.content))), msg,20000);//Snackbar.LENGTH_INDEFINITE
        Snackbar finalSnackBar = snackBar;
        //
        View.OnClickListener action =  new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finalSnackBar.dismiss();
            }
        };

        snackBar.setAction("OKAY",action )
                .setActionTextColor(activity.getApplicationContext().getResources().getColor(android.R.color.holo_red_light ));
        snackBar.show();
    }
于 2021-10-22T21:00:56.040 回答