Is there any way to add an icon to a Snackbar?

24,014

Solution 1

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.

Solution 2

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.

Solution 3

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

Solution 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()
}

Solution 5

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()
Share:
24,014
Farhad Navayazdan
Author by

Farhad Navayazdan

My name is Farhad. I am an Android Developer, Linux lover, and interested in Startups. I enjoy each aspect of building apps from start to end. My main focus is on building Android Apps and Web APIs using Kotlin and Java.

Updated on July 17, 2022

Comments

  • Farhad Navayazdan
    Farhad Navayazdan almost 2 years

    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.