How to dismiss Snackbar when user does any action?
Asked Answered
G

3

6

I can show snackbar like this.

Snackbar snackbar = Snackbar.make(this.findViewById(android.R.id.content), "snackbar", Snackbar.LENGTH_INDEFINITE)
        .setAction("action", new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // ...
            }
        });
snackbar.show();

My snackbar has indefinite length and I want it. But When user does any action, such as scrolling screen or touching screen/view, I want to dismiss snackbar. I can find some library and codes but they are so complicate. Is there not easy way to dismiss snackbar?

Grattan answered 24/1, 2016 at 9:41 Comment(1)
Try to use OnTouchListenerEnrage
L
6

I am assuming you are using fragments, so you could set an onTouchListener to your fragments main layout, and put inside snackbar.dismiss().

if you just want to dismiss on scroll set an onScrollListener and in the event dismiss the snackbar, Here's an implementation for recyclerview onScroll:

list.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (dy > 0) 
                    snackbar.dismiss();
                    }
                });
Linton answered 24/1, 2016 at 10:21 Comment(0)
N
1

use dismiss() to close a snackbar programatically.

In Kotlin, create a null-safe variable because dismiss() crashes when null

var snack : Snackbar? = null

create a snackbar inside a button click with (view: View) or if it's in the menu, replace view with findViewById(android.R.id.content)

   snack = Snackbar.make(view, "tell something", Snackbar.LENGTH_INDEFINITE).setAction(null, null)
   snack.show()

then close it from other button click

snack.dismiss()
Nahshon answered 12/8, 2022 at 18:57 Comment(0)
G
0

Maybe I found solution. I add framelayout in my view group. thank you dieter_h

Creating custom Framelayout class for override IntercepterTouchEvent

private class InterceptTouchEventLayout extends FrameLayout {

    Snackbar mSnackbar;

    public InterceptTouchEventLayout(Context context) {
        super(context);
        setLayoutParams(new CoordinatorLayout.LayoutParams(
                CoordinatorLayout.LayoutParams.MATCH_PARENT,
                CoordinatorLayout.LayoutParams.MATCH_PARENT));
    }

    public void setSnackbar(Snackbar snackbar) {
        mSnackbar = snackbar;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (mSnackbar != null && mSnackbar.isShown()) {
                    mSnackbar.dismiss();
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }
}

my xml:

<FrameLayout
    ...>
    <ScrollView .../>
    <FrameLayout .../>
</FrameLayout>

Getting FrameLayout which is top of it by

View contentView = this.findViewById(android.R.id.content);
View framLayout = ((ViewGroup) contentView).getChildAt(0);

Writing method for adding custom layout

private void addInterceptLayoutToViewGroup(Snackbar snackbar) {
    View contentView = this.findViewById(android.R.id.content);
    ViewGroup vg = (ViewGroup) ((ViewGroup) contentView).getChildAt(0);
    if (!(vg.getChildAt(0) instanceof InterceptTouchEventLayout)) {
        InterceptTouchEventLayout interceptLayout =
                new InterceptTouchEventLayout(this);
        interceptLayout.setSnackbar(snackbar);
        for (int i = 0; i < vg.getChildCount(); i++) {
            View view = vg.getChildAt(i);
            vg.removeView(view);
            interceptLayout.addView(view);
        }
        vg.addView(interceptLayout, 0);
    } else {
        InterceptTouchEventLayout interceptLayout = 
                (InterceptTouchEventLayout) vg.getChildAt(0);
        interceptLayout.setSnackbar(snackbar);
    }
}

So, I can use like this!!!

Snackbar snackbar = Snackbar.make(this.findViewById(android.R.id.content), "text", Snackbar.LENGTH_INDEFINITE)
        .setAction("action", new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                //...
            }
        });
snackbar.show();
addInterceptLayoutToViewGroup(snackbar);

Honestly, My solution changes the view tree(?). After that, My xml may be..

<FrameLayout
    ...>
    <InterceptTouchEventLayout
        ...>
        <ScrollView .../>
        <FrameLayout .../>
    </InterceptTouchEventLayout>
</FrameLayout>
Grattan answered 24/1, 2016 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.