サポートライブラリのスナックバーのテキストの色をandroid:textColor以外に設定するにはどうすればよいですか?


94

そこで、デザインサポートライブラリで新しいスナックバーを使い始めましたが、テーマで「android:textColor」を定義すると、スナックバーのテキストの色に適用されることがわかりました。プライマリテキストの色が暗い場合、これは明らかに問題です。

ここに画像の説明を入力してください

これを回避する方法を知っている人や、テキストに色を付ける方法についてのアドバイスはありますか?

2017年1月の編集:(回答後)

以下に問題を修正するためのカスタムソリューションがいくつかありますが、スナックバーのテーマを設定する正しい方法を提供することはおそらく良いことです。

まず、おそらく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
単一行なので、この解決策を選びます。
Lahiru Chandima 2016年

1
これはその質問の実際の解決策ではありません。使用:スナックバー.setActionTextColor(Color.WHITE).show();
Ahamadullah Saikat 2017

スナックバーの設定にバグがありました/色は何もしませんでした。この方法は何に関係なく機能しますが、他の人にとって最適なソリューションではない場合があります。
JPM 2017

これには、APIレベル> 24が必要です。
frank17

171

これは、Android Design Support Libraryの新機能とその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のIDを検索するコードが次のように変更されます。

TextView tv = view.findViewById(com.google.android.material.R.id.snackbar_text);
tv.setTextColor(ContextCompat.getColor(requireContext(), R.color.someColor))

2
他の誰かがスナックバーのテキストサイズを変更する方法を無駄に探している場合に備えて、これはそれです!
Janis Peisenieks

2
参考までに、のsnackbar_action代わりにを使用して、アクションテキストでも同じことができますsnackbar_text。例については、この回答を参照してください。stackoverflow.com
Joshua Pinter

7
これはせいぜいハックです-サポートライブラリの将来のリリースでandroid.support.design.R.id.snackbar_textのIDが変更されるとどうなりますか?styles.xmlでオーバーライドできるある種のデフォルトのSnackBarスタイルはありませんか?
DiscDev 2016

7
そのIDはサポートライブラリの将来のリリースで実際に変更されましたが、現在はnullポインターを取得しています。
CaptainForge

3
アップデートは、 -以下のようにandroidxと、IDは次のようになる: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(view、R.string.your_string、Snackbar.LENGTH_LONG).setTextColor(Color.WHITE).show()


Kotlin拡張メソッドの単純な使用が大好きです!;-)
Patrick Kuijpers、2018

12
com.google.android.material.R.id.snackbar_textAndroidXに移行する場合に使用します。
Rishabh876 2018

14

よし、テキストの色のやり方を基本的に再編成して修正した。

私のライトテーマでは、私はに設定android:textColorPrimaryし、normal dark textに設定android:textColorしましたwhite

すべてのテキストビューとボタンを更新して android:textColor="?android:attr/textColorPrimary".

つまり、スナックバーはから描画するためtextColor、他のすべてのテキストをに設定するだけtextColorPrimaryです。

2017年1月の編集:---------------------------------------------- ------

コメントが言うように、そして上記の編集された元の質問で述べたようにandroid:textColor、テーマ内のすべてのビューのテキストの色を変更するので、おそらくテーマで定義すべきではありません。


私はこのタスクを完了したところです。ただし、時代遅れのPreferencesアクティビティ(preferences.xmlを使用)には、以下の "m vai's"メソッドを使用する必要がありました。私のアプリのスタイリングはテーマに基づいてはるかに正確に残されていると思います。+1
OceanLife

1
良い解決策ではありませんIMO、私はtextviewの実際のテーマを保持し、スナックバーのテキストの色を変更するだけです...
issamux

1
android:textColorテーマで定義する必要はまったくありません。これはのスタイル属性ですTextView。あなたはそれを定義する場合、テーマ、あなたは、すべてのテキストの色上書きTextViewまたはButtonXMLでのテキストの色を指定していません。それはたまたまスナックバーメッセージでもあり、通常はダークテーマのオーバーレイから色を付けます。
Eugen Pechanec

12

1つのアプローチは、スパンを使用することです。

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

スパンを使用すると、1つのスナックバー内に複数の色とスタイルを追加することもできます。ここに良いガイドがあります:

https://androidbycode.wordpress.com/2015/06/06/material-design-snackbar-using-the-design-support-library/


9

androidXに移行した場合com.google.android.material.R.id.snackbar_textandroid.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

SnackbarでTextViewを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)


1

IDによる検索が機能しなかったため、別の解決策を見つけました。

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

SnackbarMaterial Components Libraryに含まれているを使用して、

  • 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

あなたがしている場合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()

鉱山と同じ答え😉
リチャード・

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年1月)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はこれらのスタイルなしのレガシーレイアウトを使用します。

私はソースコードで両方snackbarButtonStylesnackbarTextViewStyle定義し、そうでなければそれは使用されないことを発見しました。


-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
これはハックであり、さまざまなサポートライブラリビューのIDが静的であることに依存しています。私はこのソリューションを絶対に避けます。
DiscDev 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.