자체 작업 버튼을 사용하여 스낵바를 닫는 방법은 무엇입니까?


94

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
여기 오는 사람들에게 참고로에서에서 '닫기'작업을하는 Snackbar것은 Google 머티리얼 디자인 가이드 라인 에 위배 됩니다.
Loyalar

답변:


147

자바의 경우

.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

61
작업을 클릭하면 기본적으로 스낵바가 닫힙니다. dismiss 메서드를 명시 적으로 호출 할 필요가 없습니다.
Mark Buikema 2015

9
@MarkBuikema이 기능은 나중에 추가되었습니다. 질문 당시 스낵바의 청각 장애인 행동이 아니 었습니다.
EE66 2015

(가) 경우 JFYI는 작업이 표시되지 않습니다 OnClickListener이다null
crgarridos

오늘부터이 코드는 다른 이벤트 값으로 dismiss를 두 번 호출합니다. 하나는 액션을 클릭하기위한 것이고 다른 하나는 프로그램 적으로 dissmiss ()를 호출하기위한 것입니다.
Juan

53

클릭 동작을 구현하고 비워 둡니다. 빈 클릭 동작을 클릭하면 스낵바가 닫힙니다.

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

6

이것은 오래된 질문이지만 Snackbar의 유사한 기능에 대한 내 경험을 공유하고 싶습니다. 그래서 우리는 앱에 대한 디자인을 얻었습니다. 그 스낵바는 무기한 표시되어야하고 사용자는 그것을 닫을 수 있어야합니다.하지만 그 안에 DISMISS 버튼이 있어서는 안됩니다 (Google은 스낵바 내부에서 Dismiss 또는 Cancel 작업을 권장하지 않습니다). 우리의 스낵바는 그것을 두드려서 닫아야 만했습니다.

우리를 위해 일한 유일한 해결책은 결국 (여기서 retrolambda를 사용하고 있지만 표준 View.OnClickListener도 사용할 수 있습니다) :

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

의 getView () 중간에 전화를.


"Google은 Snackbars 내에서 작업을 해제하거나 취소하는 것을 권장하지 않습니다."라는 내용을 어디에서 읽습니까? 이유를 읽고 싶습니다 ....
JoseF

: 그것은 소재 디자인 가이드 라인에) @JoseF 질문 자체에서 첫 코멘트를 확인하시기 바랍니다 material.io/guidelines/components/... () "0-1 조치, 기각 또는 취소 할"
다리우스 Wiechecki

이 답변은 'LENGTH_INDEFINITE'(사용자가 읽을 시간이 있음)로 설정된 스낵바를 닫을 수있는 방법을 제공한다는 점에서 고유합니다. 따라서 작업 버튼이 시작하는 작업을 시작하지 않아도됩니다. Snackbar를 사용하여 플레이어에게 업데이트가 다운로드되었음을 알리고 구현을 원하면 다시 시작합니다. 다시 시작할 준비가되지 않은 경우 작업 버튼을 누르지 않고 해제 할 수있는 방법을 원했습니다. 내 테스트 장치의 스낵바는 스 와이프해도 닫히지 않습니다. 이 코드는 액션 버튼 외부를 터치하면이를

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

스낵바의 닫기 유형 :

/** 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 In 샘플 코드에서 람다 식 사용 (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 ()을 호출해야합니까? 말도 안되는 것 같습니다.
놀라운
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.