Як встановити колір тексту для бібліотеки закусочної підтримки на щось інше, ніж android: textColor?


94

Отже, я почав використовувати нову закусочну в бібліотеці підтримки дизайну, але виявив, що коли ви визначаєте "android: textColor" у своїй темі, це стосується кольору тексту закусочної. Це очевидно проблема, якщо ваш основний колір тексту темний.

введіть тут опис зображення

Хтось знає, як це обійти, чи має пораду, як мені розфарбувати текст?

EDIT січень 2017: (після відповіді)

Незважаючи на те, що є кілька власних рішень, щоб вирішити проблему нижче, можливо, добре надати правильний спосіб тематизації Снек-барів.

По-перше, вам, мабуть, взагалі не слід визначати 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 витримала останні можливі оновлення бібліотеки підтримки).

Крім того, дивіться відповіді нижче, щоб отримати подібні та, можливо, швидші відповіді для вирішення вашої проблеми.


дякую за рішення! власність насправді називаєтьсяandroid:textColorPrimary
muetzenflo

Дякуємо за це вичерпне пояснення.
Помилки трапляються

"ви, мабуть, взагалі не повинні визначати android: textColor у своїх темах ..." це було для мене ключовим, дякую!
Тайлер

Відповіді:


41

Я знаю, що на це вже відповіли, але найпростіший спосіб, який я знайшов, був безпосередньо у марці, використовуючи Html.fromHtmlметод та fontтег

Snackbar.make(view, 
       Html.fromHtml("<font color=\"#ffffff\">Tap to open</font>").show()

3
Я віддаю перевагу цьому рішенню, оскільки воно однорядкове.
Лахіру Чандіма,

1
Це не фактичне рішення цього питання. Використання: snackbar.setActionTextColor (Color.WHITE) .show ();
Ahamadullah Saikat

У налаштуваннях Snackbar є / була помилка, колір нічого не зробив. Цей спосіб працює незалежно від того, що може бути, але не є оптимальним рішенням для інших.
JPM

Для цього потрібен рівень API> 24.
frank17

171

Я знайшов це в Які нові функції бібліотеки підтримки дизайну Android та як користуватися її Snackbar?

Це спрацювало для мене, змінивши колір тексту на 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 = view.findViewById(com.google.android.material.R.id.snackbar_text);
tv.setTextColor(ContextCompat.getColor(requireContext(), R.color.someColor))

2
Про всяк випадок, якщо хтось інший марно шукає спосіб змінити розмір тексту Snackbar, це все!
Яніс Пейсенієкс,

2
FYI, ви можете зробити те саме з текстом Action, використовуючи snackbar_actionзамість snackbar_text. Див. Цю відповідь для прикладу: stackoverflow.com/a/36800101/293280
Джошуа Пінтер

7
У кращому випадку це злом - що трапляється, коли ідентифікатор android.support.design.R.id.snackbar_text змінюється в майбутньому випуску бібліотеки підтримки? Чи не існує якогось типового стилю SnackBar, який можна замінити у styles.xml?
DiscDev

7
Цей ідентифікатор справді було змінено в майбутньому випуску бібліотеки підтримки, зараз я отримую нульовий покажчик.
CaptainForge

3
Оновлення - для androidx ідентифікатор тепер такий:snack.view.findViewById(com.google.android.material.R.id.snackbar_text) as TextView
dblackker

15

Злом 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();

15

Створив цю функцію розширення 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 (вигляд, R.string.your_string, Snackbar.LENGTH_LONG) .setTextColor (Color.WHITE) .show ()


Любіть просте використання методів розширення Kotlin! ;-)
Патрік Куйперс

12
Використовуйте, com.google.android.material.R.id.snackbar_textякщо ви переходите на AndroidX.
Rishabh876

14

Добре, тому я виправив це, в основному реорганізувавши спосіб, як я роблю кольори тексту.

У моїй світлій темі, я поставив android:textColorPrimaryна що normal dark textя хотів, і я поставив android:textColorв white.

Я оновив усі свої текстові подання та кнопки android:textColor="?android:attr/textColorPrimary".

Отож, оскільки закусочна черпає textColor, я просто встановив для всього іншого тексту textColorPrimary.

РЕДАКТУВАТИ СІЧНЯ 2017: ---------------------------------------------- ------

Отож, як зазначається в коментарях, і як зазначено у відредагованому оригінальному запитанні вище, ви, мабуть, не повинні визначати android:textColorу своїх темах, оскільки це змінює колір тексту кожного перегляду всередині теми.


Я щойно виконав це завдання, Фу, зайняв трохи часу! Однак мені потрібно було скористатися методом "m vai" нижче для моєї застарілої Налаштування (використовуючи preferences.xml). Я думаю, що це залишило стиль мого додатка набагато коректнішим на основі теми, що приємно. +1
OceanLife

1
Невдале рішення IMO, я хочу зберегти свою актуальну тему для текстового перегляду і просто змінити колір тексту Snakbar ...
issamux

1
Ви взагалі не повинні визначати android:textColorу своїй темі. Це атрибут стилюTextView . Якщо визначити його в темі перевизначити колір тексту кожен TextViewабо Buttonякий не визначає колір тексту в XML. Це також трапляється повідомлення закусочної, яке, як правило, забарвлюється із темної накладеної теми .
Євген Печанець

12

Один із підходів - використовувати прольоти:

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/


9

Якщо ви перейшли на androidX, використовуйте com.google.android.material.R.id.snackbar_textзамість того, android.support.design.R.id.snackbar_textщоб змінювати колір тексту на панелі перекусів .


Ви заслуговуєте медалі.
frank17

@ frank17, це було згадано в декількох коментарях тут.
CoolMind

6

Єдиний спосіб, який я бачу, - це використання 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();

6

Якщо ви перенесете свій код на AndroidX, властивість TextView тепер:

com.google.android.material.R.id.snackbar_text

2

Це те, що я використовую, коли мені потрібні власні кольори

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

2

Я змінив тему

Theme.AppCompat.Light.NoActionBar

до

Theme.AppCompat.NoActionBar 

Це спрацювало. Спробуйте використовувати просту тему замість світла чи іншої теми.


2

Якщо ви вирішили використовувати брудне і хакерське рішення для пошуку TextView в Snackbar за ідентифікатором, і ви вже перейшли на 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)


1

Пошук за ідентифікатором у мене не спрацював, тому я знайшов інше рішення:

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

1

Скористайтесь Snackbarвключеною до бібліотеки компонентів матеріалів і застосуйте

  • setTextColor щоб визначити колір тексту
  • setActionTextColorщоб визначити колір тексту, що використовується в дії. Ви можете використовувати колір або селектор кольорів
  • setBackgroundTint щоб визначити колір тла закусочної

Щось на зразок:

Snackbar snackbar = Snackbar.make(view, "My custom Snackbar", Snackbar.LENGTH_LONG);        
snackbar.setTextColor(ContextCompat.getColor(this,R.color.xxxxx));
snackbar.setActionTextColor(ContextCompat.getColor(this,R.color.my_selector));
snackbar.setBackgroundTint(ContextCompat.getColor(this,R.color.xxxx));
snackbar.show();

введіть тут опис зображення


0

У мене є простий код, який допоможе отримати екземпляр як текстового перегляду 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));

0

Щоб заощадити ваш дорогоцінний час на розробку, ось статичний метод, який я використовую:

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

Ось як це виглядає:

жовта закусочна з чорним текстом


0

Якщо ви перебуваєте в Котліні , ви можете створити розширення:

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

така ж відповідь, як і моя 😉
Річард

0

Відповідно до нових компонентів 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(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)) {
            this@snack.dismiss()
        }
    }

0

Це мій спосіб вирішити такий тип проблем у 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
    }

0

В даний час (січень 2020 р.) С com.google.android.material:material:1.2.0 і , ймовірно , також1.1.0

Безумовно, це найкращий спосіб, як це зробити, замінюючи такі стилі:

<item name="snackbarStyle">@style/Widget.MaterialComponents.Snackbar</item>
<item name="snackbarButtonStyle">@style/Widget.MaterialComponents.Button.TextButton.Snackbar</item>
<item name="snackbarTextViewStyle">@style/Widget.MaterialComponents.Snackbar.TextView</item>

Якщо ви використовуєте матеріальну тему з .Bridge в кінці, з якихось причин жоден із цих стилів не визначений. Тож Snackar буде використовувати деякий застарілий макет без цих стилів.

Я знайшов у вихідному коді, що обидва snackbarButtonStyleі snackbarTextViewStyleповинні бути визначені, інакше він не використовуватиметься.


-1

Я також помітив ту саму проблему. Завдяки відповідям тут я створив невеликий клас, який може допомогти вирішити цю проблему легше, просто замінивши це:

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

}


1
Це хак, і він покладається на те, що ідентифікатори різних подань бібліотеки підтримки є статичними. Я б уникнув цього рішення будь-якою ціною.
DiscDev
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.