32

This is my Snackbar code :

        Snackbar.make(viewHolder.productView, "Some Text Here ..", Snackbar.LENGTH_SHORT)
                .setAction("I want be a icon here instead TEXT", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // Perform anything for the action selected
                    }
                })
                .show();

Is there anyway to add icon instead of text in .setAction ?

I know google suggested not use icon in Snackbar, but I want to use it.

GGWP
  • 1,111
  • 2
  • 12
  • 24
Farhad Navayazdan
  • 1,091
  • 3
  • 12
  • 22

7 Answers7

69

ImageSpan may not look right with longer text (multiple lines). Instead, use a left compound drawable (same as android:drawableLeft).

Snackbar snackbar = Snackbar.make(layout, R.string.test, Snackbar.LENGTH_LONG);
View snackbarLayout = snackbar.getView();
TextView textView = (TextView)snackbarLayout.findViewById(android.support.design.R.id.snackbar_text);
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.white_checkbox, 0, 0, 0);
textView.setCompoundDrawablePadding(getResources().getDimensionPixelOffset(R.dimen.snackbar_icon_padding));
snackbar.show();

If you are using the AndroidX Material library, replace android.support.design.R.id.snackbar_text with com.google.android.material.R.id.snackbar_text.

Daniel Zolnai
  • 16,487
  • 7
  • 59
  • 71
  • 2
    I do like this method better than accepted, BUT will google decide to make `id/snackbar_text` be a custom view which doesn't support compound drawables, this method may just fail silently – Max Ch Mar 07 '17 at 23:48
  • 1
    setCompoundDrawablesWithIntrinsicBounds() method API 17+ – Sinan Dizdarević Mar 18 '17 at 03:26
  • 1
    You are looking at `setCompoundDrawablesRelativeWithIntrinsicBounds` instead of `setCompoundDrawablesWithIntrinsicBounds` – Daniel Zolnai Mar 18 '17 at 14:33
  • 1
    how to set gravity to right of close button of textview. – Vishal Patoliya ツ Aug 16 '17 at 11:06
  • @Max Ch, good point. That's why you better place code `textView.setCompoundDrawables...` into the following `if`clause: `if(textView != null && textView instanceof TextView) {//add here drawable and padding} snackbar.show()`; – Kirill Karmazin Aug 24 '18 at 19:25
  • 3
    If using Material library, use `com.google.android.material.R.id.snackbar_text` to find the TextView – Chisko Jan 17 '20 at 04:03
20

Have you heard of ImageSpan? It may help you you to achieve your goal! See below code:

SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append("My message ").append(" ");
builder.setSpan(new ImageSpan(MainActivity.this, R.drawable.ic_launcher), builder.length() - 1, builder.length(), 0);
builder.append(" next message");
Snackbar.make(parent view, builder, Snackbar.LENGTH_LONG).show();]

Dont use big icons as they will not maintain gravity.

Ref:How to display image in Android's TextView?

Hope it helped.

Community
  • 1
  • 1
Harin
  • 2,413
  • 3
  • 15
  • 30
6

If you are using Kotlin then you can also use this extension function (for com.google.android.material):

import com.google.android.material.snackbar.Snackbar
import android.widget.TextView
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import androidx.annotation.ColorInt

fun Snackbar.setIcon(drawable: Drawable, @ColorInt colorTint: Int): Snackbar {
    return this.apply {
        setAction(" ") {}
        val textView = view.findViewById<TextView>(com.google.android.material.R.id.snackbar_action)
        textView.text = ""

        drawable.setTint(colorTint)
        drawable.setTintMode(PorterDuff.Mode.SRC_ATOP)
        textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
    }
}

Use it with your snackbar like this:

Snackbar.make(view, "Hey there!", Snackbar.LENGTH_SHORT)
        .setIcon(
            getDrawable(R.drawable.ic_launcher)!!,
            resources.getColor(android.R.color.white, theme)
        )
        .show()
ThePBone
  • 508
  • 6
  • 13
4

You also can add views to SnackbarContentLayout

Kotlin code:

val snackbar = Snackbar.make(....
val textView = snackbar.view.findViewById(R.id.snackbar_action) as TextView
textView.isAllCaps = false
val imgClose = ImageView(context)
imgClose.scaleType = ImageView.ScaleType.CENTER_INSIDE
val layImageParams = ViewGroup.LayoutParams(WRAP_CONTENT, MATCH_PARENT)
imgClose.setImageResource(R.drawable.ic_close)
(textView.parent as SnackbarContentLayout).addView(imgClose, layImageParams)
imgClose.setOnClickListener { snackbar.dismiss() }
snackbar.show()
anthorlop
  • 1,771
  • 1
  • 11
  • 11
4

Easy 2020 solution, if you want JUST the icon without action text:

Snackbar.make(anchor, message, Snackbar.LENGTH_INDEFINITE).apply {

  setAction(" ") { // onClick event }
  // the " " is just so android can create the view, otherwise it won't, it will be cleared later

  val textView = view.findViewById<TextView>(com.google.android.material.R.id.snackbar_action)
  textView.text = "" // clear the text to keep only the icon
  textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_whatever, 0, 0, 0)

  show()
}
TootsieRockNRoll
  • 3,218
  • 2
  • 25
  • 50
3

This is all you can change of a Snackbar:

Snackbar snackbar = Snackbar
  .make(parentLayout, R.string.snackbar_text, Snackbar.LENGTH_LONG)
  .setAction(R.string.snackbar_action, myOnClickListener);
snackbar.setActionTextColor(Color.CYAN);
View snackbarView = snackbar.getView();
snackbarView.setBackgroundColor(Color.YELLOW);//change Snackbar's background color;
TextView textView = (TextView)snackbarView .findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.BLUE);//change Snackbar's text color;
snackbar.show(); // Don’t forget to show!

Unfortunately, we still can't customize contents of a Snackbar by far like we do to Toast. In the future? I don't know.

SilentKnight
  • 13,761
  • 19
  • 49
  • 78
  • Thank you , but when i used textView.setBackground(R.drawable.icon); it filled all of the text view .. I used @Harry 's answer and it workes :D , Tnx again <3 – Farhad Navayazdan Jul 08 '15 at 11:18
2

Suppose you want to add an icon to the left of a snackbar. The following code helps you achieve this:

SpannableStringBuilder builderTextLeft = new SpannableStringBuilder();
builderTextLeft.append(" ");
builderTextLeft.setSpan(new ImageSpan(context, R.drawable.ic_vector), 0, 1, 0);
Snackbar snackbar = Snackbar.make(parentLayout, builderTextLeft, Snackbar.LENGTH_LONG);
snackbar.show();

In the above code I have added an info icon to the left of the snackbar.

If you want to add an icon to the right of a snackbar, you need to do the following:

SpannableStringBuilder buildetTextRight = new SpannableStringBuilder();
buildetTextRight.append(" ");
buildetTextRight.setSpan(new ImageSpan(context, R.drawable.ic_close),
                buildetTextRight.length()-1, buildetTextRight.length(), 0);

In the above code, I have added a close icon to the right of the snackbar.

Avik Chowdhury
  • 171
  • 1
  • 1
  • 7