Can we perform 2 different actions in Snack bar at a time in android?-ThrowExceptions

Exception or error:

I am creating an android application in which i want to use Snack Bar,
In a that snack bar i want 2 different words on which we have to perform 2 different actions.

enter image description here

How to solve:

From the Google design specifications:

Each snackbar may contain a single action, neither of which may be “Dismiss” or “Cancel.”

For multiple actions, use a dialog.

###

As @Elias N answer’s each Snackbar may contain a single action. If you want to set more then action in Snackbar then you need to create your own layout. Please try this i hope this will help you.

Create one xml file my_snackbar.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="50dp"
              android:background="#000000">
    <TextView
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight=".7"
        android:gravity="center_vertical"
        android:text="Please select any one"
        android:textColor="@color/white"/>

    <TextView
        android:id="@+id/txtOne"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight=".1"
        android:gravity="center"
        android:text="ONE"
        android:textColor="@color/red"/>
    <TextView
        android:id="@+id/txtTwo"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_weight=".1"
        android:gravity="center"
        android:text="TWO"
        android:textColor="@color/red"/>
</LinearLayout>

Now in your activity file do the following code.

public void myCustomSnackbar()
{
    // Create the Snackbar
    LinearLayout.LayoutParams objLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    Snackbar snackbar = Snackbar.make(llShow, "", Snackbar.LENGTH_LONG);
    // Get the Snackbar's layout view
    Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
    layout.setPadding(0,0,0,0);
    // Hide the text
    TextView textView = (TextView) layout.findViewById(android.support.design.R.id.snackbar_text);
    textView.setVisibility(View.INVISIBLE);

    LayoutInflater mInflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
    // Inflate our custom view
    View snackView = getLayoutInflater().inflate(R.layout.my_snackbar, null);
    // Configure the view
    TextView textViewOne = (TextView) snackView.findViewById(R.id.txtOne);

    textViewOne.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.i("One", "First one is clicked");
        }
    });

    TextView textViewTwo = (TextView) snackView.findViewById(R.id.txtTwo);
    textViewTwo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
        Log.i("Two", "Second one is clicked");
        }
    });

    // Add the view to the Snackbar's layout
    layout.addView(snackView, objLayoutParams);
    // Show the Snackbar
    snackbar.show();
}

For more detail please read this documentation and here.

###

Thanks Shailesh, I had to modify the code in order to make it work for me.

my_snackbar.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:id="@+id/my_snackbar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/dark_grey"
    android:padding="15dp">

    <TextView
        android:id="@+id/message_text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".6"
        android:gravity="center_vertical"
        android:text="Two button snackbar"
        android:textColor="@color/white"/>

    <TextView
        android:id="@+id/first_text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".2"
        android:gravity="center"
        android:text="ONE"
        android:textColor="#FFDEAD"/>

    <TextView
        android:id="@+id/second_text_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight=".2"
        android:gravity="center"
        android:text="TWO"
        android:textColor="#FFDEAD"/>

</LinearLayout> 

In your activity call this method whenever you want to show the snackbar:

 private void showTwoButtonSnackbar() {

    // Create the Snackbar
    LinearLayout.LayoutParams objLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    snackbar = Snackbar.make(this.findViewById(android.R.id.content), message, Snackbar.LENGTH_INDEFINITE);

    // Get the Snackbar layout view
    Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();

    // Set snackbar layout params
    int navbarHeight = getNavBarHeight(this);
    FrameLayout.LayoutParams parentParams = (FrameLayout.LayoutParams) layout.getLayoutParams();
    parentParams.setMargins(0, 0, 0, 0 - navbarHeight + 50);
    layout.setLayoutParams(parentParams);
    layout.setPadding(0, 0, 0, 0);
    layout.setLayoutParams(parentParams);

    // Inflate our custom view
    View snackView = getLayoutInflater().inflate(R.layout.my_snackbar, null);

    // Configure our custom view
    TextView messageTextView = (TextView) snackView.findViewById(R.id.message_text_view);
    messageTextView.setText(message);

    TextView textViewOne = (TextView) snackView.findViewById(R.id.first_text_view);
    textViewOne.setText("ALLOW");
    textViewOne.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("Allow", "showTwoButtonSnackbar() : allow clicked");
            snackbar.dismiss();
        }
    });

    TextView textViewTwo = (TextView) snackView.findViewById(R.id.second_text_view);
    textViewTwo.setText("DENY");
    textViewTwo.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("Deny", "showTwoButtonSnackbar() : deny clicked");
            snackbar.dismiss();
        }
    });

    // Add our custom view to the Snackbar's layout
    layout.addView(snackView, objLayoutParams);

    // Show the Snackbar
    snackbar.show();
}

To get nav bar height:

public static int getNavBarHeight(Context context) {
    int result = 0;
    int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
} 

###

Another hacky workaround you could try (works in my case).

    final Snackbar snackbar = Snackbar.make(view, "UNDO MARKED AS READ", Snackbar.LENGTH_LONG);
    snackbar.setAction("DISMISS", new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (snackbar != null)
                snackbar.dismiss();
        }
    });
    View snackbarView = snackbar.getView();
    int snackbarTextId = android.support.design.R.id.snackbar_text;
    TextView textView = (TextView) snackbarView.findViewById(snackbarTextId);
    textView.setTextColor(Color.WHITE);
    textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (snackbar != null)
                snackbar.dismiss();
            // undo mark as unread code
        }
    });
    snackbar.show();

###

You can use BottomSheetDialog and disguise it as a SnackBar. Only difference would be that it will be dismissed by swiping down instead of right and it can stay there until user dismissed it while SnackBar eventually fades away.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_history_menu_bottom"
    style="@style/Widget.Design.BottomNavigationView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:orientation="horizontal"
    android:background="@color/cardview_dark_background"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior">


    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/appCompatTextView"
        android:layout_width="wrap_content"
        android:layout_height="19dp"
        android:layout_gravity="center_vertical"

        android:layout_marginStart="8dp"
        android:layout_weight="0.6"
        android:text="Load More ?"
        android:textAppearance="@style/TextAppearance.Design.Snackbar.Message"
        android:textColor="@color/cardview_light_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <LinearLayout
        android:id="@+id/fragment_history_bottom_sheet_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right|end"
        android:layout_weight="0.4"
        android:clickable="true"
        android:focusable="true"
        android:foreground="?android:attr/selectableItemBackground"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent">

        <android.support.v7.widget.AppCompatButton
            style="@style/Widget.AppCompat.Button.Borderless.Colored"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Yes" />

        <android.support.v7.widget.AppCompatButton
            style="@style/Widget.AppCompat.Button.Borderless"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="No"
            android:textColor="@color/cardview_light_background" />
    </LinearLayout>
</android.support.constraint.ConstraintLayout>

and use it as following (Kotlin)

val dialog = BottomSheetDialog(this)
    dialog.setContentView(this.layoutInflater.inflate(R.layout.bottom_sheet_load_prompt,null))
    dialog.show()

result will be similar to SnackBar

Similar to SnackBar

###

Following Shaileshs solution:

snackbar class

public class SnackbarOfflineErrorNotification {
/**
 * A view from the content layout.
 */
@NonNull
private final View view;

@NonNull
private Context context;

/**
 * The snack bar being shown.
 */
@Nullable
private Snackbar snackbar = null;

/**
 * Construct a new instance of the notification.
 *
 * @param view A view from the content layout, used to seek an appropriate anchor for the
 *             Snackbar.
 */
public SnackbarOfflineErrorNotification(@NonNull final View view, @NonNull Context context) {
    this.view = view;
    this.context = context;
}

public void showOfflineError (){
    if (snackbar == null){
        //create snackbar
        snackbar = Snackbar.make(this.view, R.string.offline_text, LENGTH_INDEFINITE);

        // Create the Snackbar
        LinearLayout.LayoutParams objLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        // Get the Snackbar's layout view
        Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) snackbar.getView();
        layout.setPadding(0,0,0,0);
        // Hide the text
        TextView textView = (TextView) layout.findViewById(android.support.design.R.id.snackbar_text);
        textView.setVisibility(View.INVISIBLE);

        // Inflate our custom view
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View snackView = inflater.inflate(R.layout.snackbar_offline, null);
        // Configure the view
        Button btnOne = (Button) snackView.findViewById(R.id.btnOne);

        btnOne.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // action 1
            }
        });

        Button btnTwo = (Button) snackView.findViewById(R.id.btnTwo);
        btnTwo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // action 2
            }
        });

        // Add the view to the Snackbar's layout
        layout.addView(snackView, objLayoutParams);

        // Show the Snackbar
        snackbar.show();
    }

}

/**
 * Hides the currently displayed error.
 */
public void hideError() {
    if (snackbar != null) {
        snackbar.dismiss();
        snackbar = null;
    }
}
}

snackbar xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#000000">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:layout_weight=".7"
    android:gravity="center_vertical"
    android:text="offline"
    android:textColor="@color/white"
    android:paddingLeft="16dp"/>

<Button
    android:id="@+id/btnOne"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:layout_weight=".1"
    android:gravity="center"
    android:text="one" />

<Button
    android:id="@+id/btnTwo"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:layout_weight=".1"
    android:gravity="center"
    android:text="two"/>
</LinearLayout>

target activity

constructor(){
    snackbarOfflineErrorNotification = new SnackbarOfflineErrorNotification(findViewById(R.id.coordinator_layout), getApplicationContext());
}

public void hideSnackbar(){
    snackbarOfflineErrorNotification.hideError();
}

public showSnackbar(){
    snackbarOfflineErrorNotification.showOfflineError();
}

Leave a Reply

Your email address will not be published. Required fields are marked *