Как установить цвет текста библиотеки закупок библиотеки для чего-то другого, кроме android: textColor?
Итак, я начал использовать новую Snackbar в библиотеке поддержки дизайна, но обнаружил, что когда вы определяете "андроид: textColor" в своей теме, это относится к цвету текста закутки. Это, очевидно, проблема, если ваш основной цвет текста темный.
![enter image description here]()
Кто-нибудь знает способ обойти это или посоветуйте, как мне покрасить текст?
EDIT Январь 2017: (пост-ответ)
Несмотря на то, что существуют некоторые специальные решения для устранения проблемы, приведенной ниже, вероятно, полезно обеспечить правильный путь к темам Snackbars.
Во-первых, вы, вероятно, не должны определять android:textColor
в своих темах вообще (если только вы не знаете, в чем смысл темы). Это устанавливает цвет текста в основном для каждого вида, который соединяется с вашей темой. Если вы хотите определить цвета текста в своих представлениях, которые не являются стандартными, используйте android:primaryTextColor
и укажите этот атрибут в своих пользовательских представлениях.
Однако для применения тем к Snackbar
обратитесь к этому руководству по качеству из документа стороннего материала: http://www.materialdoc.com/snackbar/ (Следуйте реализация программной темы, чтобы она не зависела от стиля xml)
Для справки:
// 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);
(Вы также можете создать свои собственные макеты Snackbar
, см. ссылку выше. Сделайте так, если этот метод слишком взломан, и вы хотите получить надежный способ обновить свой пользовательский Snackbar с помощью возможных обновлений библиотеки поддержки).
И, альтернативно, см. ответы ниже для получения похожих и, возможно, более быстрых ответов для решения вашей проблемы.
Ответы
Ответ 1
Я знаю, что на этот вопрос уже был дан ответ, но самый простой способ, который я нашел, был непосредственно в make с использованием метода Html.fromHtml
и тега font
Snackbar.make(view,
Html.fromHtml("<font color=\"#ffffff\">Tap to open</font>").show()
Ответ 2
Я узнал об этом в разделе "Что нового в библиотеке поддержки дизайна Android и как использовать ее 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();
ОБНОВЛЕНИЕ: ANDROIDX: Как указывает dblackker в комментариях, с новой библиотекой поддержки AndroidX код для поиска идентификатора Snackbar TextView изменяется на:
TextView tv = snack.findViewById(com.google.android.material.R.id.snackbar_text);
Ответ 3
Создал эту функцию расширения kotlin, которую я использую в своих проектах:
fun Snackbar.setTextColor(color: Int): Snackbar {
val tv = view.findViewById(android.support.design.R.id.snackbar_text) as TextView
tv.setTextColor(color)
return this
}
Использование, как вы ожидаете:
Snackbar.make(view, R.string.your_string, Snackbar.LENGTH_LONG).setTextColor(Color.WHITE).show()
Ответ 4
Хорошо, поэтому я исправил его, в основном, реорганизуя способ, которым я рисую цвета текста.
В моей легкой теме я установил android:textColorPrimary
в normal dark text
, я хотел, и я установил android:textColor
в white
.
Я обновил все свои текстовые представления и кнопки, чтобы иметь android:textColor="?android:attr/textColorPrimary".
Так как snackbar рисует от textColor
, я просто устанавливаю весь свой другой текст на textColorPrimary
.
ИЗМЕНИТЬ ЯНВАРЬ 2017: ---------------------------------------- ------------
Итак, как говорят комментарии, и как указано в отредактированном исходном вопросе выше, вы, вероятно, не должны определять android:textColor
в своих темах, так как это изменяет цвет текста каждого вида внутри темы.
Ответ 5
Взлом на android.support.design.R.id.snackbar_text
является хрупким, лучше или менее хакерским способом сделать это будет:
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();
Ответ 6
Один подход заключается в использовании интервалов:
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();
С пролетами вы также можете добавить несколько цветов и стилей внутри одной закуски. Вот хороший гид:
https://androidbycode.wordpress.com/2015/06/06/material-design-snackbar-using-the-design-support-library/
Ответ 7
Если вы перешли на androidX, используйте com.google.android.material.R.id.snackbar_text
вместо android.support.design.R.id.snackbar_text
для изменения цвета текста на панели.
Ответ 8
Единственный способ, которым я вижу, - использовать getView()
и ездить по велосипеду через его дочерний элемент. Я не знаю, будет ли это работать, и это плохо, как кажется. Надеюсь, они скоро добавят API по этой проблеме.
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();
Ответ 9
Если вы перенесете свой код в AndroidX, свойство TextView теперь:
com.google.android.material.R.id.snackbar_text
Ответ 10
Я изменил тему
Theme.AppCompat.Light.NoActionBar
to
Theme.AppCompat.NoActionBar
Это сработало. Попытайтесь использовать простую тему вместо легкой или другой темы.
Ответ 11
Это то, что я использую, когда мне нужны пользовательские цвета
@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;
}
И потребляется как:
CustomView.makeSnackbar(view, "Hello", Snackbar.LENGTH_LONG, Color.YELLOW,Color.CYAN).setAction("DO IT", myAction).show();
Ответ 12
Если вы решили использовать грязное и хакерское решение для поиска TextView в Snackbar по id, и вы уже мигрировали на androidx, то вот код:
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)
Ответ 13
Вы можете использовать эту библиотеку: https://github.com/SandroMachado/restaurant
new Restaurant(MainActivity.this, "Snackbar with custom text color", Snackbar.LENGTH_LONG)
.setTextColor(Color.GREEN)
.show();
Отказ от ответственности: я создал библиотеку.
Ответ 14
У меня есть простой код, который поможет получить экземпляр как текстового представления Snackbar, после чего вы можете вызвать все методы, которые применимы к текстовому виду.
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));
Ответ 15
Snackbar.make(getView(), "Hello", Snackbar.LENGTH_SHORT)
.setActionTextColor(Color.WHITE)
.show();
Ответ 16
Просто чтобы сэкономить ваше драгоценное время на разработку, вот статический метод, который я использую:
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();
}
}
Вот как это выглядит:
![yellow snackbar with black text]()
Ответ 17
Если вы находитесь в Kotlin, вы можете создать расширение:
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
}
Использование:
yourSnackBar.withTextColor(Color.WHITE).show()
Ответ 18
Поиск по идентификатору не работает для меня, поэтому я нашел другое решение:
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
Ответ 19
Согласно новым компонентам AndroidX Jitpack
implementation 'com.google.android.material:material:1.0.0'
Используйте это расширение, которое я создал
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)
}
}
Используйте это так
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]()
}
}
Ответ 20
Это мой обходной путь для решения проблемы такого типа в androidx
с помощью kotlin
fun showSnackBar(message: String) {
mContent?.let {
val snackbar = Snackbar.make(it, message, Snackbar.LENGTH_LONG)
val snackbarView = snackbar.view
val tv = snackbarView.findViewById<TextView>(R.id.snackbar_text)
tv.setTextColor(Color.WHITE) //change the color of text
tv.maxLines = 3 //specify the limit of text line
snackbar.duration = BaseTransientBottomBar.LENGTH_SHORT //specify the duraction of text message
snackbar.show()
}
}
Вам нужно инициализировать mContent
внутри метода onViewCreated
, как показано ниже
var mContent: View? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mContent = view
}
Ответ 21
Я также заметил ту же проблему. Благодаря ответам здесь я создал небольшой класс, который может помочь решить эту проблему более легко, просто заменив это:
Snackbar.make(view, "Error", Snackbar.LENGTH_LONG).show();
с этим:
Snackbar2.make(view, "Error", Snackbar.LENGTH_LONG).show();
Вот мой класс:
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();
}
}
}