43

I am displaying a snackbar with a fairly long text message and on the phone in portrait mode it looks fine.

Phone Portrait mode

But on the tablet it seems to only allow 1 line of text so it gets ellipsis-ed

Tablet Landscape mode

Is there anyway I can get it to be 2 line in tablet landscape?

ChatGPT
  • 5,334
  • 12
  • 50
  • 69
arinte
  • 3,660
  • 10
  • 45
  • 65
  • 5
    as per the design guidelines snackbars should not contain lots of text, a snackbar should display a single small line of text. https://www.google.com/design/spec/components/snackbars-toasts.html# a dialog is better suited here – tyczj Aug 26 '15 at 13:43
  • As per the guidelines, the developers are not very smart. There is no way to measure text, and internationalization further makes that a complex issue. Resolution: build your own in-app-notification-system, since the default provider jumped off a bridge. – Hypersoft Systems Oct 24 '19 at 00:42
  • Tap on truncated text to open expanded view would have been sufficient..., but magically disappearing notifications, are actually useless unless the user is babysitting the screen. Would have probably made a nice game of WHACK-A-MOLE, trying to catch the notes before they disappear...LOL – Hypersoft Systems Oct 24 '19 at 00:53

6 Answers6

48

What's important and not stated in other answers is that you need to use Snackbar's view.

So:

Snackbar snackbar = Snackbar.make(rootView, R.string.message, Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView snackTextView = (TextView) snackbarView.findViewById(com.google.android.material.R.id.snackbar_text);

snackTextView.setMaxLines(2);
snackbar.show();

Note: This may also help with devices with lower screen density.

P.S If you're not using AndroidX (which is recommended), and are still using the legacy support libraries, please use android.support.design.R.id.snackbar_text instead of com.google.android.material.R.id.snackbar_text for getting the Snackbar's internal TextView.

varun
  • 2,027
  • 1
  • 15
  • 17
Szymon Chaber
  • 2,076
  • 16
  • 19
29

You can reference the SnackBar's TextView like this:

TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);

And then operate on the TextView itself by changing its max lines:

tv.setMaxLines(3)
Ali Bdeir
  • 4,151
  • 10
  • 57
  • 117
Mateusz Jablonski
  • 1,039
  • 9
  • 11
24

Based on Snackbar source code you can see that on devices with width more or equal than 600 dp they change max lines to 1. So You can also just add:

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

into your res\values\*.xml values

wrozwad
  • 2,610
  • 1
  • 30
  • 38
4

A more elaborate and thorough example with context would be this:

// Create on click listener
final  OnClickListener positiveButtonClickListener = new OnClickListener()
{
  @Override
  public void onClick(View v)
  {
    // Do your action - e.g. call GooglePlay  to update app
    openGooglePlayAppUpdate();
  }
};

// Create snack bar instance
Snackbar sBar = Snackbar.make(findViewById(R.id.some_view_to_bind),  // You bind here e.g. layout, or form view
                              R.string.snack_bar_message,
                              Snackbar.LENGTH_INDEFINITE)
                        // Set text and action to the snack bar
                        .setAction(android.R.string.ok, positiveButtonClickListener);

// Now get text view of your snack bar ...
TextView snckBarTv = (TextView) offerUpdate.getView().findViewById(android.support.design.R.id.snackbar_text);
snckBarTv.setMaxLines(5); // ... and set max lines
sBar.show(); // and finally display snack bar !
Sold Out
  • 1,321
  • 14
  • 34
1

For those using Kotlin you can make use of extensions


fun Snackbar.setMaxLines(lines: Int): Snackbar = apply { 
    view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text).maxLines = lines
}

Biscuit
  • 4,840
  • 4
  • 26
  • 54
0

For me, the best solution was auto-size within 2 lines:

<style name="ThemeOverlay.MyApp.SnackBar.Text" parent="@style/Widget.MaterialComponents.Snackbar.TextView" >
    <item name="autoSizeStepGranularity">0.5dp</item>
    <item name="autoSizeMaxTextSize">16dp</item>
    <item name="autoSizeMinTextSize">10dp</item>
    <item name="autoSizeTextType">uniform</item>
</style>

You can also increase the max number of lines or change any other TextView attribute:

<style name="ThemeOverlay.MyApp.SnackBar.Text" parent="@style/Widget.MaterialComponents.Snackbar.TextView" >
    <item name="android:maxLines">3</item>
</style>

And customize the button and paddings:

<style name="ThemeOverlay.MyApp.SnackBar.Button" parent="@style/Widget.MaterialComponents.Button.TextButton.Snackbar" >
    <item name="android:paddingStart">16dp</item>
    <item name="android:paddingEnd">16dp</item>
    <item name="android:textSize">14dp</item>  
    <item name="android:textAllCaps">false</item>     
    <item name="android:letterSpacing">0.0</item> 
</style>

<style name="ThemeOverlay.MyApp.SnackBar" parent="@style/Widget.MaterialComponents.Snackbar" >
    <item name="android:paddingStart">8dp</item>
    <item name="android:paddingEnd">8dp</item>
</style>

Your theme:

<style name="Theme.MyApp" parent="@style/Theme.MaterialComponents.DayNight.NoActionBar">
    <item name="snackbarStyle">@style/ThemeOverlay.MyApp.SnackBar</item>       
    <item name="snackbarButtonStyle">@style/ThemeOverlay.MyApp.SnackBar.Button</item>
    <item name="snackbarTextViewStyle">@style/ThemeOverlay.MyApp.SnackBar.Text</item>
</style>
Evgeny
  • 431
  • 3
  • 10