独自のアクションボタンを使用してスナックバーを閉じる方法は?


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マテリアルデザインガイドラインに違反します。
Loyalar 16

回答:


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();

Kotlinの場合、

        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、2015

60
アクションをクリックすると、スナックバーはデフォルトで非表示になります。dismissメソッドを明示的に呼び出す必要はありません。
Mark Buikema、2015年

9
@MarkBuikemaこの機能は後で追加されました。質問の時、それはスナックバーのデフォルトの行動ではありませんでした。
EE66 2015年

場合JFYI、アクションは表示されませんOnClickListenerですnull
crgarridos

今日の時点で、このコードは異なるイベント値でdismissを2回呼び出します。1つはアクションをクリックするためのもので、もう1つはプログラムで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場合、dismissのアクションボタンは必要ありません。このコードを使用する必要があります:

 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の同様の機能に関する私の経験を共有したいと思います。したがって、アプリのデザインを取得しました。スナックバーは無期限に表示され、ユーザーはそれを非表示にできるはずです。しかし、その中にDISMISSボタンがあってはなりません(とにかく、Googleはスナックバー内のDismissまたはCancelアクションを推奨していません)。スナックバーはタップするだけで解散する必要がありました。

私たちにとって有効な唯一の解決策は、最後にありました(ここでは、retrolambdaを使用していますが、標準のView.OnClickListenerも使用できます)。

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

途中でgetView()を呼び出すことに注意してください。


「Googleはスナックバー内での操作の終了またはキャンセルを推奨していません」とどこで読みますか?私は....理由を読みたい
ヨーゼフ

@JoseF質問自体の最初のコメントを確認してください;)マテリアルデザインガイドラインにあります:material.io/guidelines/components/…( "0-1アクション、却下またはキャンセルしないでください")
Dariusz Wiechecki

3

スナックバー(「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();

スナックバーの却下タイプ:

/** 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サンプルコードでラムダ式を使用(RetroLambdaによる)


問題は、ハンドラーを閉じることではありません。問題は、ボタンのクリックでどのように却下するかです。

2

私も同じ問題を抱えていました。.dismiss()を使用すると、アニメーションが異なって見え、2つの問題がありました。

  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()を呼び出さなければならないのですか?それはナンセンスだと思われます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.