Bagaimana cara menyetel warna teks support library snackbar ke sesuatu selain android: textColor?

95

Jadi saya sudah mulai menggunakan Snackbar baru di Design Support Library, tetapi saya menemukan bahwa saat Anda mendefinisikan "android: textColor" di tema Anda, ini berlaku untuk warna teks snackbar. Ini jelas menjadi masalah jika warna teks utama Anda gelap.

masukkan deskripsi gambar di sini

Adakah yang tahu cara mengatasi ini atau memiliki saran tentang bagaimana saya harus mewarnai teks saya?

EDIT Januari 2017: (Pasca-Jawaban)

Meskipun ada beberapa solusi khusus untuk memperbaiki masalah di bawah ini, sebaiknya berikan cara yang benar untuk tema Snackbars.

Pertama, Anda mungkin tidak harus mendefinisikan android:textColortema Anda sama sekali (kecuali Anda benar-benar tahu ruang lingkup apa yang menggunakan tema). Ini mengatur warna teks pada dasarnya setiap tampilan yang terhubung ke tema Anda. Jika Anda ingin menentukan warna teks dalam tampilan Anda yang bukan default, gunakan android:primaryTextColordan rujuk atribut itu dalam tampilan kustom Anda.

Namun, untuk menerapkan tema ke Snackbar, lihat panduan kualitas ini dari dokumen materi pihak ketiga: http://www.materialdoc.com/snackbar/ (Ikuti implementasi tema terprogram agar tidak bergantung pada gaya xml)

Sebagai referensi:

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

(Anda juga dapat membuat Snackbarlayout kustom Anda sendiri juga, lihat link di atas. Lakukan jika metode ini terasa terlalu hacky dan Anda ingin cara yang pasti dapat diandalkan agar Snackbar kustom Anda bertahan melalui kemungkinan update support library).

Dan sebagai alternatif, lihat jawaban di bawah untuk jawaban yang serupa dan mungkin lebih cepat untuk menyelesaikan masalah Anda.

Mahonster
sumber
terima kasih atas solusinya! properti sebenarnya disebutandroid:textColorPrimary
muetzenflo
Terima kasih atas penjelasan komprehensif ini.
Bug Terjadi
"Anda mungkin tidak harus mendefinisikan android: textColor di tema Anda sama sekali ..." itu adalah kuncinya bagi saya, terima kasih!
Tyler

Jawaban:

41

Saya tahu ini sudah dijawab tetapi cara termudah yang saya temukan adalah langsung di make menggunakan Html.fromHtmlmetode dan fonttag

Snackbar.make(view, 
       Html.fromHtml("<font color=\"#ffffff\">Tap to open</font>").show()
JPM
sumber
3
Saya lebih suka solusi ini karena ini adalah satu baris.
Lahiru Chandima
1
Ini bukanlah solusi sebenarnya dari pertanyaan itu. Gunakan: snackbar.setActionTextColor (Color.WHITE) .show ();
Ahamadullah Saikat
Ada / tadinya bug dalam pengaturan Snackbar warna tidak melakukan apa pun. Cara ini berhasil apa pun yang terjadi, tetapi mungkin bukan solusi optimal untuk orang lain.
JPM
Ini membutuhkan API level> 24.
frank17
171

Saya menemukan ini di Apa saja fitur baru Pustaka Dukungan Desain Android dan cara menggunakan Snackbar-nya?

Ini berhasil bagi saya untuk mengubah warna teks di 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();



PEMBARUAN: ANDROIDX: Seperti yang dblackker tunjukkan di komentar, dengan pustaka dukungan AndroidX yang baru, kode untuk menemukan ID Snackbar TextView berubah menjadi:

TextView tv = view.findViewById(com.google.android.material.R.id.snackbar_text);
tv.setTextColor(ContextCompat.getColor(requireContext(), R.color.someColor))
Jarod Young
sumber
2
Untuk berjaga-jaga jika ada orang lain yang dengan sia-sia mencari cara untuk mengubah ukuran teks dari sebuah Snackbar, ini dia!
Janis Peisenieks
2
FYI, Anda dapat melakukan hal yang sama dengan teks Tindakan dengan menggunakan snackbar_actionalih-alih snackbar_text. Lihat jawaban ini untuk contoh: stackoverflow.com/a/36800101/293280
Joshua Pinter
7
Ini adalah peretasan terbaik - apa yang terjadi jika ID untuk android.support.design.R.id.snackbar_text berubah di rilis pustaka dukungan di masa mendatang? Apakah tidak ada jenis gaya SnackBar default yang dapat diganti di styles.xml?
DiscDev
7
ID itu memang diubah di rilis mendatang dari pustaka dukungan, saya mendapatkan penunjuk null sekarang.
CaptainForge
3
Perbarui - dengan androidx, id sekarang sebagai berikut:snack.view.findViewById(com.google.android.material.R.id.snackbar_text) as TextView
dblackker
15

Peretasan android.support.design.R.id.snackbar_textitu rapuh, cara yang lebih baik atau lebih baik untuk melakukannya adalah:

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();
Jet Zhao
sumber
15

Membuat fungsi ekstensi kotlin yang saya gunakan dalam proyek saya:

fun Snackbar.setTextColor(color: Int): Snackbar {
    val tv = view.findViewById(com.google.android.material.R.id.snackbar_text) as TextView
    tv.setTextColor(color)

    return this
}

Penggunaan seperti yang Anda harapkan:

Snackbar.make (view, R.string.your_string, Snackbar.LENGTH_LONG) .setTextColor (Color.WHITE) .show ()

Richard
sumber
Suka penggunaan metode ekstensi Kotlin yang sederhana! ;-)
Patrick Kuijpers
13
Gunakan com.google.android.material.R.id.snackbar_textjika Anda bermigrasi ke AndroidX.
Rishabh876
Berubah @ Rishabh876 :)
Richard
14

Baiklah jadi saya memperbaikinya dengan pada dasarnya mengatur ulang cara saya melakukan warna teks.

Dalam tema terang saya, saya setel android:textColorPrimaryke yang normal dark textsaya inginkan, dan saya setel android:textColorke white.

Saya memperbarui semua tampilan teks dan tombol saya agar memiliki android:textColor="?android:attr/textColorPrimary".

Jadi karena snackbar diambil dari textColor, saya hanya menyetel semua teks saya yang lain ke textColorPrimary.

EDIT JANUARI 2017: ---------------------------------------------- ------

Jadi seperti yang dikatakan oleh komentar, dan seperti yang dinyatakan dalam pertanyaan asli yang telah diedit di atas, Anda mungkin tidak perlu menentukan android:textColortema Anda, karena ini mengubah warna teks dari setiap tampilan di dalam tema.

Mahonster
sumber
Saya baru saja menyelesaikan tugas ini, Fiuh, butuh waktu lama! Namun, saya perlu menggunakan metode "m vai's" di bawah ini untuk aktivitas Preferensi kuno saya (menggunakan preferensi.xml). Saya pikir itu meninggalkan gaya aplikasi saya jauh lebih tepat berdasarkan tema yang bagus. +1
OceanLife
1
Bukan solusi yang baik IMO, saya ingin menyimpan tema saya yang sebenarnya untuk textview dan hanya mengubah warna teks snakbar ...
issamux
1
Anda tidak seharusnya mendefinisikan android:textColortema Anda sama sekali. Itu adalah atribut gaya dari TextView. Jika Anda menentukannya dalam tema Anda, Anda mengganti warna teks dari setiap TextViewatau Buttonyang tidak menentukan warna teksnya dalam XML. Itu juga merupakan pesan snackbar yang biasanya mengambil warna dari hamparan tema gelapnya .
Eugen Pechanec
12

Salah satu pendekatannya adalah dengan menggunakan span:

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

Dengan span, Anda juga dapat menambahkan beberapa warna dan gaya di dalam satu Snackbar. Ini panduan yang bagus:

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

ulcica
sumber
9

Jika Anda bermigrasi ke penggunaan androidX com.google.android.material.R.id.snackbar_textbukan android.support.design.R.id.snackbar_textuntuk mengubah warna teks pada snackbar.

Rohit Maurya
sumber
Kamu berhak mendapatkan medali.
frank17
@ frank17, itu disebutkan dalam beberapa komentar di sini.
CoolMind
6

Satu-satunya cara saya melihat adalah menggunakan getView()dan bersepeda melalui anaknya. Saya tidak tahu apakah itu akan berhasil, dan itu buruk seperti yang terlihat. Saya berharap mereka akan segera menambahkan beberapa API tentang masalah ini.

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();
natario
sumber
6

Jika Anda akan memigrasi kode ke AndroidX, properti TextView sekarang:

com.google.android.material.R.id.snackbar_text
Matjaz Kristl
sumber
2

Inilah yang saya gunakan saat saya membutuhkan warna khusus

    @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;
    }

Dan dikonsumsi sebagai:

CustomView.makeSnackbar(view, "Hello", Snackbar.LENGTH_LONG, Color.YELLOW,Color.CYAN).setAction("DO IT", myAction).show();
makata
sumber
2

Saya mengubah tema saya

Theme.AppCompat.Light.NoActionBar

untuk

Theme.AppCompat.NoActionBar 

Berhasil. Coba gunakan tema sederhana alih-alih tema terang atau lainnya.

Pavneet_Singh
sumber
2

Jika Anda memutuskan untuk menggunakan solusi dirty and hacky dengan menemukan TextView di Snackbar berdasarkan id dan Anda sudah bermigrasi ke androidx, berikut kodenya:

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)
Grzegorz Matyszczak
sumber
1

Anda dapat menggunakan perpustakaan ini: https://github.com/SandroMachado/restaurant

new Restaurant(MainActivity.this, "Snackbar with custom text color", Snackbar.LENGTH_LONG)
    .setTextColor(Color.GREEN)
    .show();

Penafian: Saya membuat perpustakaan.

Sandro Machado
sumber
1

Temukan menurut id tidak berfungsi untuk saya, jadi saya menemukan solusi lain:

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
Anrimian
sumber
1

Gunakan yang Snackbardisertakan dalam Material Components Library dan terapkan

Sesuatu seperti:

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

masukkan deskripsi gambar di sini

Gabriele Mariotti
sumber
1

Saat ini (Januari 2020) dengan com.google.android.material:material:1.2.0dan mungkin juga1.1.0

Jelas merupakan cara terbaik untuk melakukannya dengan mengganti gaya berikut:

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

Jika Anda menggunakan tema material dengan .Bridge di bagian akhir, karena alasan tertentu, tak satu pun dari gaya ini yang ditentukan. Jadi Snackar akan menggunakan beberapa tata letak lama tanpa gaya ini.

Saya menemukan di kode sumber bahwa keduanya snackbarButtonStyledan snackbarTextViewStyleharus didefinisikan jika tidak maka tidak akan digunakan.

Atom
sumber
0

Saya memiliki kode sederhana yang akan membantu mendapatkan contoh dari kedua tampilan teks Snackbar, setelah itu Anda dapat memanggil semua metode yang berlaku pada tampilan teks.

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));
Menyimpulkan Jain
sumber
0

Hanya untuk menghemat waktu pengembangan Anda yang berharga, berikut adalah metode statis yang saya gunakan:

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

Beginilah tampilannya:

snackbar kuning dengan teks hitam

Ifta
sumber
0

Jika Anda berada di Kotlin , Anda dapat membuat ekstensi:

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
}

Penggunaan :

yourSnackBar.withTextColor(Color.WHITE).show()
Phil
sumber
jawaban yang sama seperti saya 😉
Richard
0

Sesuai dengan komponen Jitpack AndroidX baru

implementation 'com.google.android.material:material:1.0.0'

Gunakan ekstensi ini yang telah saya buat

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

Gunakan seperti ini

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()
        }
    }
Manoj Perumarath
sumber
0

Ini adalah solusi saya untuk mengatasi masalah jenis ini dalam androidxpenggunaankotlin

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

Anda perlu menginisialisasi metode mContentdi dalam onViewCreatedseperti di bawah ini

var mContent: View? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mContent = view
    }
Suraj Bahadur
sumber
-1

Saya juga memperhatikan masalah yang sama. Berkat jawaban di sini, saya telah membuat kelas kecil, yang dapat membantu memecahkan masalah ini dengan lebih mudah, hanya dengan mengganti ini:

Snackbar.make(view, "Error", Snackbar.LENGTH_LONG).show();

dengan ini:

Snackbar2.make(view, "Error", Snackbar.LENGTH_LONG).show();

Ini kelas saya:

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

}

Dr. Failov
sumber
1
Ini adalah retasan, dan bergantung pada id dari berbagai tampilan pustaka dukungan agar statis. Saya akan menghindari solusi ini dengan segala cara.
DiscDev