studio - snackbar android
¿Cómo establecer el color de texto de la barra de snack de la biblioteca de soporte en algo diferente a Android: textColor? (19)
Buscar por ID no funcionó para mí, así que encontré otra solución:
Snackbar snackbar = Snackbar.make(view, text, duration);//just ordinary creation
ViewGroup snackbarView = (ViewGroup) snackbar.getView();
SnackbarContentLayout contentLayout = (SnackbarContentLayout) snackbarView.getChildAt(0);
TextView tvText = contentLayout.getMessageView();
tvText.setTextColor(/*your color here*/);
//set another colors, show, etc
Así que comencé a usar el nuevo Snackbar en la Biblioteca de soporte de diseño, pero descubrí que cuando define "android: textColor" en su tema, se aplica al color del texto del snackbar. Obviamente, esto es un problema si el color del texto principal es oscuro.
¿Alguien sabe una forma de evitar esto o tiene consejos sobre cómo debo colorear mi texto?
EDITAR enero de 2017: (posterior a la respuesta)
Si bien hay algunas soluciones personalizadas para solucionar el problema a continuación, probablemente sea bueno proporcionar la forma correcta de tema Snackbars.
En primer lugar, probablemente no deberías definir
android:textColor
en tus temas (a menos que realmente sepas el alcance de lo que está usando el tema).
Esto establece el color del texto de básicamente cada vista que se conecta a su tema.
Si desea definir colores de texto en sus vistas que no son predeterminados, use
android:primaryTextColor
y
android:primaryTextColor
referencia a ese atributo en sus vistas personalizadas.
Sin embargo, para aplicar temas a
Snackbar
, consulte esta guía de calidad de un documento de material de terceros:
http://www.materialdoc.com/snackbar/
(Siga la implementación del tema programático para que no se base en un estilo xml)
Para referencia:
// create instance
Snackbar snackbar = Snackbar.make(view, text, duration);
// set action button color
snackbar.setActionTextColor(getResources().getColor(R.color.indigo));
// get snackbar view
View snackbarView = snackbar.getView();
// change snackbar text color
int snackbarTextId = android.support.design.R.id.snackbar_text;
TextView textView = (TextView)snackbarView.findViewById(snackbarTextId);
textView.setTextColor(getResources().getColor(R.color.indigo));
// change snackbar background
snackbarView.setBackgroundColor(Color.MAGENTA);
(También puede crear sus propios diseños de
Snackbar
personalizados, consulte el enlace de arriba. Hágalo si este método se siente demasiado hacky y desea una forma seguramente confiable de que su Snackbar personalizado dure a través de posibles actualizaciones de la biblioteca de soporte).
Y, alternativamente, vea las respuestas a continuación para obtener respuestas similares y quizás más rápidas para resolver su problema.
Cambié mi tema
Theme.AppCompat.Light.NoActionBar
a
Theme.AppCompat.NoActionBar
Funcionó. Intente utilizar un tema simple en lugar de luz u otro tema.
Creé esta función de extensión de Kotlin que uso en mis proyectos:
fun Snackbar.setTextColor(color: Int): Snackbar {
val tv = view.findViewById(android.support.design.R.id.snackbar_text) as TextView
tv.setTextColor(color)
return this
}
Uso como cabría esperar:
Snackbar.make (ver, R.string.your_string, Snackbar.LENGTH_LONG) .setTextColor (Color.WHITE) .show ()
Encontré esto en ¿Cuáles son las nuevas características de Android Design Support Library y cómo usar su Snackbar?
Esto funcionó para mí para cambiar el color del texto en un Snackbar.
Snackbar snack = Snackbar.make(view, R.string.message, Snackbar.LENGTH_LONG);
View view = snack.getView();
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(Color.WHITE);
snack.show();
ACTUALIZACIÓN: ANDROIDX:
como señala dblackker en los comentarios, con la nueva biblioteca de soporte de AndroidX, el código para encontrar la ID de Snackbar TextView cambia a:
TextView tv = snack.findViewById(com.google.android.material.R.id.snackbar_text);
Esto es lo que uso cuando necesito colores personalizados
@NonNull
public static Snackbar makeSnackbar(@NonNull View layout, @NonNull CharSequence text, int duration, int backgroundColor, int textColor/*, int actionTextColor*/){
Snackbar snackBarView = Snackbar.make(layout, text, duration);
snackBarView.getView().setBackgroundColor(backgroundColor);
//snackBarView.setActionTextColor(actionTextColor);
TextView tv = (TextView) snackBarView.getView().findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(textColor);
return snackBarView;
}
Y consumido como:
CustomView.makeSnackbar(view, "Hello", Snackbar.LENGTH_LONG, Color.YELLOW,Color.CYAN).setAction("DO IT", myAction).show();
Hackear en
android.support.design.R.id.snackbar_text
es frágil, una forma mejor o menos hacky de hacerlo será:
String snackText = getResources().getString(YOUR_RESOURCE_ID);
SpannableStringBuilder ssb = new SpannableStringBuilder()
.append(snackText);
ssb.setSpan(
new ForegroundColorSpan(Color.WHITE),
0,
snackText.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Snackbar.make(
getView(),
ssb,
Snackbar.LENGTH_SHORT)
.show();
La única forma en que veo es usando
getView()
y
getView()
través de su hijo.
No sé si va a funcionar, y es tan malo como parece.
Espero que pronto agreguen algo de API sobre este problema.
Snackbar snack = Snackbar.make(...);
ViewGroup group = (ViewGroup) snack.getView();
for (int i = 0; i < group.getChildCount(); i++) {
View v = group.getChildAt(i);
if (v instanceof TextView) {
TextView t = (TextView) v;
t.setTextColor(...)
}
}
snack.show();
Muy bien, así que lo arreglé básicamente reorganizando la forma en que hago los colores del texto.
En mi tema claro, configuré
android:textColorPrimary
en el
normal dark text
que quería, y configuré
android:textColor
en
white
.
android:textColor="?android:attr/textColorPrimary".
todas mis vistas de texto y botones para tener
android:textColor="?android:attr/textColorPrimary".
Entonces, debido a que snackbar se basa en
textColor
, simplemente configuré todo mi otro texto en
textColorPrimary
.
EDITAR ENERO 2017: ---------------------------------------------- ------
Entonces, como dicen los comentarios, y como se indica en la pregunta original editada anteriormente, probablemente no debería definir
android:textColor
en sus temas, ya que esto cambia el color del texto de cada vista dentro del tema.
Puede usar esta biblioteca: https://github.com/SandroMachado/restaurant
new Restaurant(MainActivity.this, "Snackbar with custom text color", Snackbar.LENGTH_LONG)
.setTextColor(Color.GREEN)
.show();
Descargo de responsabilidad: hice la biblioteca.
Sé que esto ya ha sido respondido, pero la forma más fácil que encontré fue directamente en la marca usando el método
Html.fromHtml
y una etiqueta de
font
Snackbar.make(view,
Html.fromHtml("<font color=/"#ffffff/">Tap to open</font>").show()
Según los nuevos componentes de AndroidX Jitpack
implementation ''com.google.android.material:material:1.0.0''
Usa esta extensión que había creado
inline fun View.snack(message: String, length: Int = Snackbar.LENGTH_LONG,
f: Snackbar.() -> Unit) {
val snack = Snackbar.make(this, message, length)
snack.f()
snack.show()
}
fun Snackbar.action(action: String, actionColor: Int? = null, textColor: Int? = null, listener: (View) -> Unit) {
setAction(action, listener)
actionColor?.let {
setActionTextColor(it)
}
textColor?.let {
this.view.findViewById<TextView>(R.id.snackbar_text).setTextColor(it)
}
}
Úselo así
btn_login.snack(
getString(R.string.fields_empty_login),
ContextCompat.getColor(this@LoginActivity, R.color.whiteColor)
) {
action(getString(R.string.text_ok), ContextCompat.getColor(this@LoginActivity, R.color.gray_300),ContextCompat.getColor(this@LoginActivity, R.color.yellow_400)) {
[email protected]()
}
}
Si decide utilizar la solución sucia y hacky para encontrar TextView en Snackbar por id y ya migró a androidx, entonces aquí está el código:
val textViewId = com.google.android.material.R.id.snackbar_text
val snackbar = Snackbar.make(view, "Text", Snackbar.LENGTH_SHORT)
val textView = snackbar.view.findViewById(textViewId) as TextView
textView.setTextColor(Color.WHITE)
Si estás en Kotlin , puedes crear una extensión:
fun Snackbar.withTextColor(color: Int): Snackbar {
val tv = this.view.findViewById(android.support.design.R.id.snackbar_text) as TextView
tv.setTextColor(color)
return this
}
Uso :
yourSnackBar.withTextColor(Color.WHITE).show()
Si migró a androidX, use
com.google.android.material.R.id.snackbar_text
lugar de
android.support.design.R.id.snackbar_text
para cambiar el color del texto en la barra de bocadillos.
Si va a migrar su código a AndroidX, la propiedad TextView ahora es:
com.google.android.material.R.id.snackbar_text
Solo para ahorrar su valioso tiempo de desarrollo, aquí está el método estático que estoy usando:
public static void snack(View view, String message) {
if (!TextUtils.isEmpty(message)) {
Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT);
snackbar.getView().setBackgroundColor(Color.YELLOW);
TextView tv = snackbar.getView().findViewById(android.support.design.R.id.snackbar_text); //snackbar_text
tv.setTextColor(Color.BLACK);
snackbar.show();
}
}
Así es como se ve:
También noté el mismo problema. Gracias a las respuestas aquí, he creado una pequeña clase, que puede ayudar a resolver este problema más fácilmente, simplemente reemplazando esto:
Snackbar.make(view, "Error", Snackbar.LENGTH_LONG).show();
con este:
Snackbar2.make(view, "Error", Snackbar.LENGTH_LONG).show();
Aquí está mi clase:
public class Snackbar2 {
static public Snackbar make(View view, int resid, int duration){
Snackbar result = Snackbar.make(view, resid, duration);
process(result);
return result;
}
static public Snackbar make(View view, String text, int duration){
Snackbar result = Snackbar.make(view, text, duration);
process(result);
return result;
}
static private void process(Snackbar snackbar){
try {
View view1= snackbar.getView();
TextView tv = (TextView) view1.findViewById(android.support.design.R.id.snackbar_text);
tv.setTextColor(Color.WHITE);
}catch (Exception ex)
{
//inform about error
ex.printStackTrace();
}
}
}
Tengo un código simple que ayudará a obtener una instancia de la vista de texto de Snackbar, después de eso puede llamar a todos los métodos que sean aplicables en una vista de texto.
Snackbar snackbar = Snackbar.make( ... ) // Create Snack bar
snackbar.setActionTextColor(getResources().getColor(R.color.white)); //if you directly want to apply the color to Action Text
TextView snackbarActionTextView = (TextView) snackbar.getView().findViewById( android.support.design.R.id.snackbar_action );
snackbarActionTextView.setTextColor(Color.RED); //This is another way of doing it
snackbarActionTextView.setTypeface(snackbarActionTextView.getTypeface(), Typeface.BOLD);
//Below Code is to modify the Text in Snack bar
TextView snackbarTextView = (TextView) snackbar.getView().findViewById(android.support.design.R.id.snackbar_text);
snackbarTextView.setTextSize( 16 );
snackbarTextView.setTextColor(getResources().getColor(R.color.white));
Un enfoque es usar tramos:
final ForegroundColorSpan whiteSpan = new ForegroundColorSpan(ContextCompat.getColor(this, android.R.color.white));
SpannableStringBuilder snackbarText = new SpannableStringBuilder("Hello, I''m white!");
snackbarText.setSpan(whiteSpan, 0, snackbarText.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
Snackbar.make(view, snackbarText, Snackbar.LENGTH_LONG)
.show();
Con los tramos también puede agregar varios colores y estilos dentro de una Snackbar. Aquí hay una buena guía: