Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Snackbar with CoordinatorLayout disable dismiss

I am using the support

  • FloatingActionButton
  • Snackbar
  • CoordinatorLayout

I need the CoordinatorLayout so that if SnackBar is shown the FloatingActionButton moves up to make room for the Snackbar. For better understanding check this video.

I am using SnackBar for double-back to exit the application, but the SnackBar can be dismissed.

Is there a way to disable the dismiss on the SnackBar?

Snackbar snackbar = Snackbar.make(view, R.string.press_back_again_to_exit, Snackbar.LENGTH_SHORT);
snackbar.setAction(R.string.ok, new View.OnClickListener() {
    @Override
    public void onClick(View v)
    {

    }
});
snackbar.setActionTextColor(getResources().getColor(R.color.white));

View view = snackbar.getView();
view.setBackgroundColor(getResources().getColor(R.color.orange_warning));

snackbar.show();

Layout

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        xmlns:sothree="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:fitsSystemWindows="true">

        <com.sothree.slidinguppanel.SlidingUpPanelLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="bottom"
            sothree:umanoFadeColor="@android:color/transparent"
            sothree:umanoPanelHeight="100dp"
            sothree:umanoShadowHeight="4dp">

            <!-- Toolbar and main content -->
            <LinearLayout
                android:id="@+id/toolbar_and_content"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <include layout="@layout/toolbar"/>

                <!-- Your content layout -->
                <FrameLayout
                    android:id="@+id/content_frame"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"/>

            </LinearLayout>

            <!-- Sliding up panel layout -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/darker_grey"
                android:orientation="vertical">

                ...

            </LinearLayout>

        </com.sothree.slidinguppanel.SlidingUpPanelLayout>


        <!-- Navigation drawer -->
        <ExpandableListView
            android:id="@+id/lv_left_drawer"
            android:layout_width="280dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@color/white"
            android:childDivider="@android:color/transparent"
            android:clickable="true"
            android:divider="@color/divider_color"
            android:dividerHeight="0.6dp"
            android:fadeScrollbars="true"
            android:groupIndicator="@null"
            android:listSelector="@drawable/button_drawer_child_selector"
            android:scrollbarSize="0dp"/>

    </android.support.v4.widget.DrawerLayout>

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|bottom"
        android:layout_marginBottom="@dimen/floating_action_button_margin"
        android:layout_marginRight="@dimen/floating_action_button_margin"
        android:src="@drawable/ic_add"
        android:visibility="invisible"
        app:backgroundTint="@color/orange"
        app:borderWidth="0dp"
        app:elevation="6dp"
        app:fabSize="normal"/>

</android.support.design.widget.CoordinatorLayout>

P.S.

I am aware of this GitHub library, that has this functionality, but is there a 'native' way to do it?

like image 478
Marko Avatar asked Aug 24 '15 13:08

Marko


People also ask

How do I get rid of snackbar?

setAction("Dismiss", new View. OnClickListener() { @Override public void onClick(View v) { } }). show(); The snackbar can be dismissed by a swipe.

What is Snackbar explain it with Example?

Snackbar in android is a new widget introduced with the Material Design library as a replacement of a Toast. Android Snackbar is light-weight widget and they are used to show messages in the bottom of the application with swiping enabled. Snackbar android widget may contain an optional action button.

What is Snackbar in Android?

Snackbars provide lightweight feedback about an operation. They show a brief message at the bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other elements on screen and only one can be displayed at a time.

Why use Coordinator layout Android?

CoordinatorLayout is a super-powered FrameLayout . CoordinatorLayout is intended for two primary use cases: As a top-level application decor or chrome layout. As a container for a specific interaction with one or more child views.


3 Answers

Snackbar now has actual support disabling swipe to dismiss using the setBehavior method. The great thing here is that before you would always lose some behaviors which are now preserved. You'll also want to use Snackbar.LENGTH_INDEFINITE

Note that the package moved so you have to import the "new" Snackbar in the snackbar package.

Snackbar.make(view, stringId, Snackbar.LENGTH_INDEFINITE)
    .setBehavior(new NoSwipeBehavior())
    .show();

class NoSwipeBehavior extends BaseTransientBottomBar.Behavior {

    @Override
    public boolean canSwipeDismissView(View child) {
      return false;
    }
}
like image 122
MinceMan Avatar answered Oct 17 '22 18:10

MinceMan


You can alter the duration of Snackbar to be shown. It will be similar to disable dismiss.

int     LENGTH_INDEFINITE   Show the Snackbar indefinitely. 

Check docs.

if it does not work For this then there is only one way, Implement Your custom Snackbar and override dismiss() method and in that do nothing. :) As dismiss() is a public API.

like image 8
theJango Avatar answered Oct 17 '22 18:10

theJango


The answer about just using LENGTH_INDEFINITE is not sufficient.

It is only non-dismissable when the Snackbar is no child of CoordinatorLayout. When it is a child, you can still swipe away the SnackBar.

What you can do in that case is listen for the dismiss swipe and simply re-show the Snackbar.

public void showAnnoyingSnackBar(View root, String text) {
    Snackbar.make(root, text, Snackbar.LENGTH_INDEFINITE)
        .setCallback(new Snackbar.Callback() {
            @Override public void onDismissed(Snackbar snackbar, int event) {
                // recursively call this method again when the snackbar was dismissed through a swipe
                if (event == DISMISS_EVENT_SWIPE) showAnnoyingSnackBar(root, text);
            }
        })
        .show();
}
like image 8
Paul Woitaschek Avatar answered Oct 17 '22 20:10

Paul Woitaschek