Daher habe ich angefangen, die neue Snackbar in der Design-Support-Bibliothek zu verwenden. Wenn Sie in Ihrem Design "Android: textColor" definieren, gilt dies für die Textfarbe der Snackbar. Dies ist offensichtlich ein Problem, wenn Ihre primäre Textfarbe dunkel ist.
Kennt jemand einen Weg, um dies zu umgehen, oder hat er Ratschläge, wie ich meinen Text einfärben soll?
BEARBEITEN Januar 2017: (Post-Answer)
Es gibt zwar einige benutzerdefinierte Lösungen, um das Problem unten zu beheben, aber es ist wahrscheinlich gut, die richtige Methode für die Themen-Snackbars bereitzustellen.
Erstens sollten Sie in Ihren Themen wahrscheinlich überhaupt nicht Android:textColor
Definieren (es sei denn, Sie wissen wirklich, in welchem Umfang das Thema verwendet wird). Hiermit wird die Textfarbe für jede Ansicht festgelegt, die mit Ihrem Thema verbunden ist. Wenn Sie Textfarben in Ihren Ansichten definieren möchten, die nicht die Standardfarben sind, verwenden Sie Android:primaryTextColor
Und verweisen Sie in Ihren benutzerdefinierten Ansichten auf dieses Attribut.
Informationen zum Anwenden von Designs auf Snackbar
finden Sie in diesem Qualitätsleitfaden eines Drittanbieters. Doc: http: //www.materialdoc.com/snackbar/ (Befolgen Sie die Anweisungen des Programms Theme-Implementierung, damit es nicht auf einen xml-Stil angewiesen ist)
Als Referenz:
// 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);
(Sie können auch Ihre eigenen benutzerdefinierten Snackbar
Layouts erstellen, siehe den obigen Link. Tun Sie dies, wenn sich diese Methode zu kitschig anfühlt und Sie möchten, dass Ihre benutzerdefinierte Snackbar durch mögliche Aktualisierungen der Unterstützungsbibliothek zuverlässig funktioniert.).
Alternativ finden Sie im Folgenden ähnliche und möglicherweise schnellere Antworten zur Lösung Ihres Problems.
Ich weiß, dass dies bereits beantwortet wurde, aber der einfachste Weg, den ich gefunden habe, war direkt in der Marke mit dem Html.fromHtml
Methode und ein font
Tag
Snackbar.make(view,
Html.fromHtml("<font color=\"#ffffff\">Tap to open</font>").show()
Ich fand dies unter Was sind die neuen Funktionen von Android Design Support Library und wie verwende ich die Snackbar?
Dies funktionierte für mich zum Ändern der Textfarbe in einer 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();
UPDATE: ANDROIDX: Wie dblackker in den Kommentaren ausführt, ändert sich mit der neuen AndroidX-Unterstützungsbibliothek der Code zum Ermitteln der ID von Snackbar TextView in:
TextView tv = snack.findViewById(com.google.Android.material.R.id.snackbar_text);
Erstellt diese Kotlin-Erweiterungsfunktion, die ich in meinen Projekten verwende:
fun Snackbar.setTextColor(color: Int): Snackbar {
val tv = view.findViewById(Android.support.design.R.id.snackbar_text) as TextView
tv.setTextColor(color)
return this
}
Verwendung wie erwartet:
Snackbar.make (view, R.string.your_string, Snackbar.LENGTH_LONG) .setTextColor (Color.WHITE) .show ()
Hacking auf Android.support.design.R.id.snackbar_text
ist zerbrechlich, ein besserer oder weniger hackiger Weg, dies zu tun, wird sein:
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();
Also gut, ich habe es behoben, indem ich die Art und Weise, wie ich Textfarben mache, grundlegend umstrukturiert habe.
In meinem Light-Theme habe ich Android:textColorPrimary
Auf das von mir gewünschte normal dark text
Und Android:textColor
Auf white
gesetzt.
Ich habe alle meine Textansichten und Schaltflächen auf Android:textColor="?android:attr/textColorPrimary".
Aktualisiert.
Da die Snackbar aus textColor
stammt, habe ich einfach den gesamten anderen Text auf textColorPrimary
gesetzt.
BEARBEITEN JANUAR 2017: -------------------------------------- ----------
Wie aus den Kommentaren hervorgeht und wie oben in der bearbeiteten Originalfrage angegeben, sollten Sie in Ihren Themen wahrscheinlich nicht Android:textColor
Definieren, da dies die Textfarbe jeder Ansicht innerhalb des Themas ändert.
Ein Ansatz ist die Verwendung von Überspannungen:
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();
Mit Spannen können Sie auch mehrere Farben und Stile in einer Snackbar hinzufügen. Hier ist eine nette Anleitung:
Wenn Sie zu AndroidX migriert haben, verwenden Sie com.google.Android.material.R.id.snackbar_text
anstatt Android.support.design.R.id.snackbar_text
zum Ändern der Textfarbe in der Snackbar.
Die einzige Möglichkeit, die ich sehe, ist die Verwendung von getView()
und das Durchlaufen des untergeordneten Elements. Ich weiß nicht, ob es funktionieren wird, und es ist schlecht, wie es aussieht. Ich hoffe, dass sie bald eine API zu diesem Problem hinzufügen werden.
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();
Wenn Sie Ihren Code auf AndroidX migrieren, lautet die TextView-Eigenschaft jetzt:
com.google.Android.material.R.id.snackbar_text
Ich habe mein Thema geändert
Theme.AppCompat.Light.NoActionBar
zu
Theme.AppCompat.NoActionBar
Es hat funktioniert. Versuchen Sie, ein einfaches Thema anstelle von Licht oder einem anderen Thema zu verwenden.
Wenn Sie sich entschließen, die schmutzige und hackige Lösung zu verwenden, um TextView in Snackbar nach ID zu finden, und Sie bereits zu AndroidX migriert sind, dann ist hier der Code:
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)
Dies ist, was ich benutze, wenn ich benutzerdefinierte Farben benötige
@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;
}
Und verzehrt als:
CustomView.makeSnackbar(view, "Hello", Snackbar.LENGTH_LONG, Color.YELLOW,Color.CYAN).setAction("DO IT", myAction).show();
Sie können diese Bibliothek verwenden: https://github.com/SandroMachado/restaurant
new Restaurant(MainActivity.this, "Snackbar with custom text color", Snackbar.LENGTH_LONG)
.setTextColor(Color.GREEN)
.show();
Haftungsausschluss: Ich habe die Bibliothek gemacht.
Wie bei neuen AndroidX Jitpack-Komponenten
implementation 'com.google.Android.material:material:1.0.0'
Verwenden Sie diese Erweiterung, die ich erstellt hatte
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)
}
}
Benutze es so
btn_login.snack(
getString(R.string.fields_empty_login),
ContextCompat.getColor([email protected], R.color.whiteColor)
) {
action(getString(R.string.text_ok), ContextCompat.getColor([email protected], R.color.gray_300),ContextCompat.getColor([email protected], R.color.yellow_400)) {
[email protected]()
}
}
Ich habe einen einfachen Code, der hilft, eine Instanz von beiden der Textansicht von Snackbar zu erhalten, danach können Sie alle Methoden aufrufen, die für eine Textansicht anwendbar sind.
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));
Wenn Sie in Kotlin sind, können Sie eine Erweiterung erstellen:
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
}
Verwendung:
yourSnackBar.withTextColor(Color.WHITE).show()
Suche nach ID hat bei mir nicht funktioniert, daher habe ich eine andere Lösung gefunden:
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
Hier ist die statische Methode, die ich verwende, um Ihre wertvolle Entwicklungszeit zu sparen:
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();
}
}
So sieht es aus: