Is there any way to add an icon to a Snackbar?
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()
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, 2022Comments
-
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.