52

Sto cercando di sfruttare le nuove Snackbar da Android Supporto Design Library per visualizzare snack più righe, come mostrato in http://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs:Android multilinea Snackbar

import android.support.design.widget.Snackbar; 

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

viene visualizzato solo First line... sul mio Nexus 7. Come per renderlo visualizzare tutte le linee?

PS: Ho provato Toast e ha visualizzato tutte le linee.

+0

per quanto ne so, snackbar sono pensati per un rapido utente alert/feedback e sono stati progettati per supportare cioè "Single Line". Se vuoi mostrare un avviso/feedback che ha linee multiple, ti suggerirei di mostrare una finestra di dialogo quando l'utente può intervenire dopo aver letto il tuo messaggio. – mudit

+1

@mudit pensa all'internazionalizzazione. Anche se la stringa inglese può adattarsi alla singola riga, il tedesco potrebbe non farlo.Anche Google ha fornito le specifiche di Material Design per lo snack bar multilinea (l'ho collegato nella domanda) - perché se dovrebbe essere evitato? –

risposta

145

Basta impostare l'attributo di maxLines snackbar TextView

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

Questa risposta dovrebbe essere accettata :) –

9

Ecco la mia conclusione su questo:

Android supporta snackbar multilinea ma ha un limite massimo di 2 linee che corrisponde la linea guida di progettazione in cui si dice che l'altezza di snack bar multilinea dovrebbe essere 80dp (quasi 2 linee)

Per verificare ciò, ho utilizzato il progetto di esempio android cheesesquare. Se io uso seguente stringa:

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 questo caso, posso vedere lo snack bar multilinea con il testo del 2 ° linea, vale a dire "Quando un secondo snack si attiva", ma se cambio il codice al seguente implementazione:

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

posso vedere solo il "Testo a caso \ nQuando ...". Ciò significa che la libreria di progettazione sta costringendo intenzionalmente il textview a essere di max 2 righe.

+1

Ho accettato questa risposta, ma le specifiche materiali menzionano anche lo snackbar con 112dp: http://i.imgur.com/1ACCoQb.png –

+0

puoi nominare l'altezza della barra multifunzione? – alp

+0

@alp vedere https://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs –

20

Uno può ignorare il valore predefinito utilizzato per quella in values.xml dell'app

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

Questo valore viene utilizzato da Snackbar di default .

+10

Questa pratica dovrebbe essere evitata, poiché è un numero intero privato definito dalla libreria di progettazione, che potrebbe essere rinominato o eliminato senza generare alcuna compilazione o errore di runtime nell'app. –

+3

Sì, ma penso che dovrebbe essere chiarito che questo è molto diverso dall'accesso alle risorse private del sistema operativo. Questo funzionerà finché ti atterrai alla stessa versione della libreria di progettazione. Se si aggiorna a una versione più recente, è necessario testare l'app in ogni caso, basta metterla nella lista di controllo. – devconsole

3

Un'alternativa ai suggerimenti che implicano l'hardcoding dell'ID risorsa per la visualizzazione testo contenuta dalla snackbar è quella di scorrere per trovare il TextView. È più sicuro a lungo termine e ti consente di aggiornare la libreria di supporto con il minimo timore che l'ID cambi.

Esempio:

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; 
} 
+0

testo in qualche modo sempre nullo – stannums

+0

Controlla il tuo codice. [Ecco il codice sorgente AOSP per il layout di Snackbar] (https://github.com/dandar3/android-support-design/blob/master/res/layout/design_layout_snackbar_include.xml) Noterai che esiste un oggetto TextView lì, quindi non è possibile che il testo sia nullo. –

+0

Potrebbe essere ancora meglio usare 'findViewsWithText', dal momento che conosci già il testo. Questa soluzione potrebbe rompersi in un paio di situazioni (ad esempio se la nostra vista testuale diventa figlia di un bambino del layout della barra degli snack). – natario

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

Invece di usare setMaxLines, io uso setSingleLine per rendere l'involucro TextView al suo contenuto.

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

questo funziona per 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(); 
0

tardi, ma potrebbe essere utile a qualcuno:

public void showSnackBar(String txt,View view){ 
     Snackbar snackbar = null; 

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