Android Multiline Snackbar

AndroidAndroid Support-LibraryAndroid Design-LibraryAndroid Snackbar

Android Problem Overview


I'm trying to leverage new Snackbar from Android Design Support Library to display multiline snackbar, as shown in http://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs:

import android.support.design.widget.Snackbar;

final String snack = "First line\nSecond line\nThird line";
Snackbar.make(mView, snack, Snackbar.LENGTH_LONG).show();

It displays only First line... on my Nexus 7. How to make it display all lines?

PS: I tried Toast and it displayed all lines.

Android Solutions


Solution 1 - Android

Just set the maxLines attribute of Snackbars Textview

View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5);  // show multiple line

If you're using the more recent "com.google.android.material:material:1.0.0"dependency, then you will use this: com.google.android.material.R.id.snackbar_text to access the Snackbar's TextView.

You can use even R.id.snackbar_text as well. it's work for me.

Solution 2 - Android

One can override the predefined value used for that in values.xml of the app

<integer name="design_snackbar_text_max_lines">5</integer>

This value is used by Snackbar by default.

Solution 3 - Android

Snackbar snackbar =  Snackbar.make(view, "Text",Snackbar.LENGTH_LONG).setDuration(Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView tv= (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setMaxLines(3); 
snackbar.show();

Solution 4 - Android

Here is my finding on this :

Android does support multiline snackbars but it has a max limit of 2 lines which matches the design guideline where it says that the height of multiline snack bar should be 80dp (almost 2 lines)

To verify this, i used the cheesesquare android sample project. If i use following string:

Snackbar.make(view, "Random Text \n When a second snackbar is triggered while the first is displayed", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();

In this case, i can see the multiline snack bar with the text of 2nd line, i.e. "When a second snackbar is triggered" but if i change this code to following implementation:

Snackbar.make(view, "Random Text \n When \n a second snackbar is triggered while the first is displayed", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();

I can only see the "Random Text\nWhen ...". This means that design library is intentionally forcing the textview to be of max 2 lines.

Solution 5 - Android

With the Material Components Library you can define it using with the snackbarTextViewStyle attribute in the app theme:

<style name="AppTheme" parent="Theme.MaterialComponents.*">
  ...
  <item name="snackbarTextViewStyle">@style/snackbar_text</item>
</style>

<style name="snackbar_text" parent="@style/Widget.MaterialComponents.Snackbar.TextView">
    ...
    <item name="android:maxLines">5</item>
</style>

enter image description here

Note: it requires the version 1.2.0 of the library.

Solution 6 - Android

In kotlin you can use extensions.

// SnackbarExtensions.kt

fun Snackbar.allowInfiniteLines(): Snackbar {
    return apply { (view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.isSingleLine = false }
}

Usage:

Snackbar.make(view, message, Snackbar.LENGTH_LONG)
                        .allowInfiniteLines()
                        .show()

Solution 7 - Android

For Material Design, the reference is com.google.android.material.R.id.snackbar_text

val snack = Snackbar.make(myView, R.string.myLongText, Snackbar.LENGTH_INDEFINITE).apply {
                view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text).maxLines = 10
            }
            snack.show()

Solution 8 - Android

In Kotlin, you can just do

Snackbar.make(root_view, "Yo\nYo\nYo!", Snackbar.LENGTH_SHORT).apply {
    view.snackbar_text.setSingleLine(false)
    show()
}

You could also replace setSingleLine(false) with maxLines = 3.

Android Studio should prompt you to add

import kotlinx.android.synthetic.main.design_layout_snackbar_include.view.*

EDIT

I haven't been able to get this to work again, so I'll just share what I think is the cleanest way to write in Kotlin what a few others have already shared:

import com.google.android.material.R as MaterialR

Snackbar.make(root_view, "Yo\nYo\nYo!", Snackbar.LENGTH_SHORT).apply {
    val textView = view.findViewById<TextView>(MaterialR.id.snackbar_text)
    textView.setSingleLine(false)
    show()
}

Solution 9 - Android

An alternative to the suggestions that involve hardcoding the resource ID for the textview contained by the snackbar is to iterate to find the TextView. It's safer long-term and lets you update the support library with minimal fear of the ID changing.

Example:

 public static Snackbar getSnackbar(View rootView, String message, int duration) {
    Snackbar snackbar = Snackbar.make(rootView, message, duration);
    ViewGroup snackbarLayout = (ViewGroup) snackbar.getView();

    TextView text = null;

    for (int i = 0; i < snackbarLayout.getChildCount(); i++) {
        View child = snackbarLayout.getChildAt(i);

        // Since action is a button, and Button extends TextView,
        // Need to make sure this is the message TextView, not the 
        // action Button view.
        if(child instanceof TextView && !(child instanceof Button)) {
            text = (TextView) child;
        }
    }

    if (text != null) {
        text.setMaxLines(3);
    }
    return snackbar;
}

Solution 10 - Android

Instead of using setMaxLines, i use setSingleLine to make the textview wrap to its content.

String yourText = "First line\nSecond line\nThird line";
Snackbar snackbar = Snackbar.make(mView, yourText, Snackbar.LENGTH_SHORT);
    TextView textView =
        (TextView) snackbar.getView().findViewById(android.support.design.R.id.snackbar_text);
    textView.setSingleLine(false);
snackbar.show();

Solution 11 - Android

this works for me

Snackbar snackbar =  Snackbar.make(mView, "Your text string", Snackbar.LENGTH_INDEFINITE);
((TextView) snackbar.getView().findViewById(android.support.design.R.id.snackbar_text)).setSingleLine(false);
snackbar.show();

Solution 12 - Android

Late, but might be helpful to someone:

public void showSnackBar(String txt, View view){
    final Snackbar snackbar = Snackbar.make(view,txt,Snackbar.LENGTH_INDEFINITE)
        .setAction("OK", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //do something
            }
        });
    View view = snackbar.getView();
    TextView textView = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
    textView.setMaxLines(5);
    snackbar.show();
}

Solution 13 - Android

A way to do it which won't crash in case things change on newer versions of the library :

Snackbar.make(...).setAction(...) {
    ...
}.apply {
    (view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.setSingleLine(false)
}.show()

And a way to do it without having ids being used, setting all TextViews in the Snackbar to have unlimited multi-lines :

@UiThread
fun setAllTextViewsToHaveInfiniteLinesCount(view: View) {
    when (view) {
        is TextView -> view.setSingleLine(false)
        is ViewGroup -> for (child in view.children)
            setAllTextViewsToHaveInfiniteLinesCount(child)
    }
}

Snackbar.make(...).setAction(...) {
    ...
}.apply {
    setAllTextViewsToHaveInfiniteLinesCount(view)
}.show()

The same function in Java:

@UiThread
public static void setAllTextViewsToHaveInfiniteLines(@Nullable final View view) {
    if (view == null)
        return;
    if (view instanceof TextView)
        ((TextView) view).setSingleLine(false);
    else if (view instanceof ViewGroup)
        for (Iterator<View> iterator = ViewGroupKt.getChildren((ViewGroup) view).iterator(); iterator.hasNext(); )
            setAllTextViewsToHaveInfiniteLines(iterator.next());
}

Solution 14 - Android

May i suggest you to use com.google.android.material.snackbar.Snackbar. This is the recommanded way by google. First you have to add your snackbar.

final Snackbar snackbar = Snackbar.make(
            findViewById(R.id.activity_layout),
            "snackbar explanation text \n multilines \n\n here",
            Snackbar.LENGTH_INDEFINITE)
            .setAction(R.string.action_settings, new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // your action here
                }
            });

Then to add multilines support

TextView messageView = snackbar.getView().findViewById(R.id.snackbar_text);
                        messageView.setMaxLines(4);
                        

Finally show the snackbar.

snackbar.show();

Solution 15 - Android

Just a quick comment, if you are using com.google.android.material:material the prefix or package for R.id should be com.google.android.material

val snackbarView = snackbar.view
val textView = snackbarView.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)
textView.maxLines = 3

Solution 16 - Android

so as i am using latest material design library from google, com.google.android.material:material:1.1.0 and i used simple following code snipet below, to resolve allow to more lines in snackbar. hope it will help to new developers as well.

TextView messageView = snackbar.getView().findViewById(R.id.snackbar_text);
messageView.setMaxLines(5);

Solution 17 - Android

To avoid flakiness of other answers can use updateMaxLine, this solution is less likely to break if Google decide to change the id of a text view)

val snackBar = Snackbar.make(view, message, duration)
 snackBar.view.allViews.updateMaxLine(5)
 snackBar.show()

just note, this option will update the max line for all the text views in the Snakbar view (which tbh I do not think it matters)

add this as extension

private fun <T> Sequence<T>.updateMaxLine(maxLine : Int) {
    for (view in this) {
        if (view is TextView) {
            view.maxLines = maxLine
        }
    }
}

enter image description here

Solution 18 - Android

2021 Answer in Kotlin for com.google.android.material:material:1.4.0

isSingleLine = false is required as well as maxLines = 5

Snackbar.make(view, "line 1\nline 2", BaseTransientBottomBar.LENGTH_INDEFINITE)
    .apply {
        this.view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)?.apply {
            maxLines = 5
            isSingleLine = false
        }
    }
    .show()

Solution 19 - Android

Snackbar height adjustment:

val sMsg = "Msg\n\n"
val sOk = getString(R.string.ok)
val sMoreLines = StringBuilder()
for (iCtr in 1..6) {
    sMoreLines.append("\n")                 
}
Snackbar
.make(
    this.requireActivity().findViewById(android.R.id.content),
    sMsg,
    Snackbar.LENGTH_INDEFINITE)        
.setAction("$sMoreLines$sOk\n$sMoreLines") {
    // ...
}
.show()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDima KornilovView Question on Stackoverflow
Solution 1 - AndroidNilesh SentaView Answer on Stackoverflow
Solution 2 - Androidakd005View Answer on Stackoverflow
Solution 3 - AndroidRamesh RView Answer on Stackoverflow
Solution 4 - AndroidmuditView Answer on Stackoverflow
Solution 5 - AndroidGabriele MariottiView Answer on Stackoverflow
Solution 6 - AndroidVincent SitView Answer on Stackoverflow
Solution 7 - AndroidrmirabelleView Answer on Stackoverflow
Solution 8 - AndroidGumby The GreenView Answer on Stackoverflow
Solution 9 - AndroidChantell OsejoView Answer on Stackoverflow
Solution 10 - AndroidmedhdjView Answer on Stackoverflow
Solution 11 - AndroidtechSquatsView Answer on Stackoverflow
Solution 12 - AndroidAdeeb karimView Answer on Stackoverflow
Solution 13 - Androidandroid developerView Answer on Stackoverflow
Solution 14 - AndroidZharView Answer on Stackoverflow
Solution 15 - AndroidNicolas JafelleView Answer on Stackoverflow
Solution 16 - AndroidAbhishek GargView Answer on Stackoverflow
Solution 17 - Androidbastami82View Answer on Stackoverflow
Solution 18 - AndroidAwsom3DView Answer on Stackoverflow
Solution 19 - AndroidGotDotsView Answer on Stackoverflow