Estoy tratando de aprovechar lo nuevo Snackbar
de la biblioteca de compatibilidad de diseño de Android para mostrar una barra de bocadillos de varias líneas, como se muestra en 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();
Solo se muestra First line...
en mi Nexus 7. ¿Cómo hacer que muestre todas las líneas?
PD: lo intenté Toast
y mostró todas las líneas.
Respuestas:
Simplemente configure el
maxLines
atributo de Snackbars TextviewView snackbarView = snackbar.getView(); TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text); textView.setMaxLines(5); // show multiple line
Si está utilizando la
"com.google.android.material:material:1.0.0"
dependencia más reciente , utilizará esto:com.google.android.material.R.id.snackbar_text
para acceder al TextView de Snackbar.Puedes usar incluso
R.id.snackbar_text
también. es trabajo para mi.fuente
Se puede anular el valor predefinido utilizado para eso en values.xml de la aplicación
<integer name="design_snackbar_text_max_lines">5</integer>
Snackbar utiliza este valor de forma predeterminada.
fuente
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();
fuente
Aquí está mi hallazgo sobre esto:
Android admite barras de bocadillos de varias líneas, pero tiene un límite máximo de 2 líneas que coincide con la guía de diseño donde dice que la altura de la barra de bocadillos de líneas múltiples debe ser 80dp (casi 2 líneas)
Para verificar esto, utilicé el proyecto de muestra de Android cheesesquare. Si uso la siguiente cadena:
Snackbar.make(view, "Random Text \n When a second snackbar is triggered while the first is displayed", Snackbar.LENGTH_LONG) .setAction("Action", null).show();
En este caso, puedo ver la barra de bocadillos de varias líneas con el texto de la segunda línea, es decir, "Cuando se activa una segunda barra de bocadillos", pero si cambio este código a la siguiente implementación:
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();
Solo puedo ver el "Texto aleatorio \ nCuando ... ". Esto significa que la biblioteca de diseño está forzando intencionalmente la vista de texto a tener un máximo de 2 líneas.
fuente
Para Material Design, la referencia es
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()
fuente
Una alternativa a las sugerencias que implican codificar el ID de recurso para la vista de texto contenida en la barra de bocadillos es iterar para encontrar la Vista de texto. Es más seguro a largo plazo y le permite actualizar la biblioteca de soporte con el mínimo temor de que cambie la identificación.
Ejemplo:
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; }
fuente
findViewsWithText
, ya que ya conoce el texto. Esta solución puede fallar en un par de situaciones (por ejemplo, si nuestra vista de texto se convierte en un elemento secundario del diseño del snackbar).snackbarLayout.getChildAt()
que nunca volverá aTextView
.En lugar de usar setMaxLines, uso setSingleLine para hacer que la vista de texto se ajuste a su contenido.
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();
fuente
esto funciona para mi
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();
fuente
Tarde, pero podría ser útil para alguien:
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(); }
fuente
Con la biblioteca de componentes de materiales puede definirlo usando el
snackbarTextViewStyle
atributo en el tema de la aplicación:<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>
Nota : requiere la versión 1.2.0 de la biblioteca.
fuente
En Kotlin, puedes simplemente hacer
Snackbar.make(root_view, "Yo\nYo\nYo!", Snackbar.LENGTH_SHORT).apply { view.snackbar_text.setSingleLine(false) show() }
También puede reemplazarlo
setSingleLine(false)
conmaxLines = 3
.Android Studio debería pedirle que agregue
import kotlinx.android.synthetic.main.design_layout_snackbar_include.view.*
EDITAR
No he podido hacer que esto funcione nuevamente, así que solo compartiré lo que creo que es la forma más limpia de escribir en Kotlin lo que algunos otros ya han compartido:
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() }
fuente
snackbar_text
.java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setSingleLine(boolean)' on a null object reference
implementation 'com.google.android.material:material:1.1.0'
y es su Snackbar la indicadacom.google.android.material.snackbar.Snackbar
? Si no es así, intenteandroid.support.design.R.id.snackbar_text
como ID de recurso.Una forma de hacerlo que no se bloqueará en caso de que las cosas cambien en las versiones más nuevas de la biblioteca:
Snackbar.make(...).setAction(...) { ... }.apply { (view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.setSingleLine(false) }.show()
Y una forma de hacerlo sin tener que usar identificadores, configurando todos los TextViews en Snackbar para que tengan múltiples líneas ilimitadas:
@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()
La misma función en 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()); }
fuente
En kotlin puedes usar extensiones.
// SnackbarExtensions.kt fun Snackbar.allowInfiniteLines(): Snackbar { return apply { (view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.isSingleLine = false } }
Uso:
Snackbar.make(view, message, Snackbar.LENGTH_LONG) .allowInfiniteLines() .show()
fuente
Solo un comentario rápido, si está utilizando
com.google.android.material:material
el prefijo o el paquete paraR.id
debería sercom.google.android.material
val snackbarView = snackbar.view val textView = snackbarView.findViewById<TextView>(com.google.android.material.R.id.snackbar_text) textView.maxLines = 3
fuente
así que como estoy usando la última biblioteca de diseño de materiales de Google,
com.google.android.material:material:1.1.0
y usé el siguiente fragmento de código simple a continuación, para resolver permitir más líneas en el snackbar. Espero que también ayude a los nuevos desarrolladores.TextView messageView = snackbar.getView().findViewById(R.id.snackbar_text); messageView.setMaxLines(5);
fuente
Para evitar la escasez de otras respuestas que se pueden usar
updateMaxLine
, es menos probable que esta solución se rompa si Google decide cambiar la identificación de una vista de texto)val snackBar = Snackbar.make(view, message, duration) snackBar.view.allViews.updateMaxLine(5) snackBar.show()
solo tenga en cuenta que esta opción actualizará la línea máxima para todas las vistas de texto en la vista Snakbar (que tbh no creo que importe)
agregar esto como extensión
private fun <T> Sequence<T>.updateMaxLine(maxLine : Int) { for (view in this) { if (view is TextView) { view.maxLines = maxLine } } }
fuente