Bir Snackbar, kendi Eylem düğmesini kullanarak nasıl kapatılır?


94

Android tasarım desteği kitaplığı artık Snackbar için destek içeriyor.

Bir tane oluşturmak için aşağıdaki kodu kullandım:

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

            }
        }).show();

Snackbar bir kaydırma hareketi ile kapatılabilir. Bununla birlikte, kendi Eylem Düğmesini (setAction işlevi kullanılarak oluşturulmuş) kullanarak da kapatmak istiyorum.

Ancak bunu yapabilecek herhangi bir işlev yok gibi görünüyor.


4
Buraya gelen kişilere bir not olarak Snackbar, Google Materyal Tasarım Yönergelerine aykırıdır .
Loyalar

Yanıtlar:


147

Java için,

.makeYöntem, bir döner Snackbarnesne. Yaparak o nesnenin bir örneğini kaydedin final. Ardından, şu onClick()numarayı arayın .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 için,

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

2
Bunu FloatingActionButton ile bir koordinatör düzeninde yaparsam, FloatingActionButton aşağı inmiyor.
Vinay W

61
Eylem tıklandığında bir snackbar varsayılan olarak kapatılır. Açıkça işten çıkarma yöntemini çağırmak gereksizdir.
Mark Buikema

9
@MarkBuikema bu özellik daha sonra eklendi. Soru sorulduğu sırada bu, snackbarın sağır davranışı değildi.
EE66

Eğer JFYI, aksiyon gösterilmeyecektir OnClickListenerolduğununull
crgarridos

Bugün itibariyle, bu kod, biri eylemi tıklamak ve diğeri dissmiss () programını programatik olarak çağırmak için olmak üzere, farklı olay değeriyle iki kez dismiss'i çağıracaktır.
Juan

53

Bir tıklama eylemi uygulayın ve boş bırakın. Boş tıklama eylemine tıklamak, snackbar'ı kapatır.

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

nullbir dinleyici için geçebilirsiniz , gerçek bir örnek oluşturmanıza gerek yoktur
ccpizza

11

Kullandığınızda Snackbar.LENGTH_LONG, görevden almak için işlem düğmesine ihtiyacınız yoktur, saniye sonra otomatik olarak kapanır. Bu kodu kullanmalısınız:

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

Bu satıra dikkat edin :

Snackbar.LENGTH_INDEFINITE

6

Bu eski bir soru, ancak Snackbar'daki benzer özelliklerle ilgili kendi deneyimimi paylaşmak istiyorum. Bu yüzden uygulamamız için bir tasarımımız var, bu snackbar süresiz olarak gösterilmeli ve kullanıcı onu kapatabilmelidir .. ama içinde ÇIKAR düğmesi olmamalıdır (Google yine de atıştırmalık çubuklarının içindeki Kapat veya İptal işlemlerini önermemektedir). Snack barımız sadece üzerine dokunarak kapatılmalıydı.

Bizim için çalışan tek çözüm sonunda oldu (burada retrolambda kullanıyorum, ancak standart View.OnClickListener da kullanılabilir):

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

Not GetView () ortada çağrıyı.


"Google, Snackbarlar içindeki Kapat veya İptal işlemlerini önermiyor" ifadesini nerede okuyorsunuz?
Sebebini

@JoseF Lütfen sorunun kendisinin altındaki ilk yorumu kontrol edin;) Materyal Tasarım yönergelerindedir: material.io/guidelines/components/… ("0-1 eylem, reddetme veya iptal etme")
Dariusz Wiechecki

Bu yanıt benzersizdir, çünkü 'LENGTH_INDEFINITE' olarak ayarlanmış atıştırmalık çubuğunu (böylece kullanıcının okumak için zamanı olur), işlem düğmesinin başlattığı eylemi başlatmak zorunda kalmadan kapatır. Oyuncularıma bir güncellemenin indirildiğini bildirmek ve uygulanmasını istiyorlarsa yeniden başlatmak için bir Snackbar kullanıyorum. Yeniden başlatmaya hazır değillerse, eylem düğmesine basmadan onu kapatmanın bir yolunu istedim. Test cihazlarımdaki atıştırmalık çubukları bir kaydırma ile kapatılmıyor. Bu kod, bence varsayılan davranış olması gereken eylem düğmesinin dışında bir dokunuşla onu
kapatıyor

3

Snackbar ( "com.android.support:design:23.2.1" den ) birçok tür reddetme eylemini destekler. Bu örnekte olduğu gibi olayı kullanarak basit bir filtre oluşturabilirsiniz :

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'ın reddetme türleri:

/** 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 Örnek kodda lambda ifadeleri kullanıldı (RetroLambda tarafından)


Soru, görevden alınan bir görevli ile ilgili değil. Soru, düğme tıklandığında nasıl kapatılacağıdır.
inanılmaz

2

Ben de aynı sorunu yaşadım. .Dismiss () kullandığımda animasyonlar farklı görünüyordu ve iki sorun vardı:

  1. FAB tekrar düşmüyor
  2. SnackBar, bir Tıklamadaki gibi aşağı kaymaz

Snackbar için orijinal Android Kaynak Koduna baktığımda aşağıdaki çözümü buldum:

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

Ardından, .performClick on the snackBarActionButton

snackBarActionButton.performClick();

Snackbar için Android Kaynak Koduna bağlantı: https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/design/src/android/support/design/widget/Snackbar.java


Bana mantıklı gelmiyor. Gerçekten bir düğmeyi tıklıyorsanız neden performClick () çağırmalısınız? Bu çok saçma görünüyor.
inanılmaz Jan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.