지원 라이브러리 스낵바 텍스트 색상을 android : textColor가 아닌 다른 색상으로 설정하는 방법은 무엇입니까?


95

그래서 디자인 지원 라이브러리에서 새로운 Snackbar를 사용하기 시작했지만 테마에서 "android : textColor"를 정의하면 스낵바의 텍스트 색상에 적용된다는 것을 알았습니다. 기본 텍스트 색상이 어두우면 분명히 문제가됩니다.

여기에 이미지 설명 입력

누구든지 이것에 대한 방법을 알고 있거나 텍스트에 색상을 지정하는 방법에 대한 조언이 있습니까?

2017 년 1 월 수정 : (답변 후)

아래에 문제를 해결하기위한 몇 가지 사용자 지정 솔루션이 있지만 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를 지속 할 수있는 확실한 방법을 원한다면 그렇게하십시오).

또는 문제를 해결하기 위해 유사하거나 더 빠른 답변을 보려면 아래 답변을 참조하십시오.


솔루션에 감사드립니다! 속성이 실제로라고android:textColorPrimary
muetzenflo

이 포괄적 인 설명에 감사드립니다.
Bugs Happen 2019

"당신은 아마 당신의 테마에 android : textColor를 전혀 정의하지 말아야 할 것입니다 ..."그것이 저에게 핵심이었습니다. 감사합니다!
Tyler

답변:


41

나는 이것이 이미 답변되었음을 알고 있지만 내가 찾은 가장 쉬운 방법은 Html.fromHtml방법과 font태그를 사용하여 직접 만드는 것이 었습니다.

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

3
한 줄이기 때문에이 솔루션을 선호합니다.
Lahiru Chandima 2016

1
이것은 그 질문의 실제 해결책이 아닙니다. 사용 : snackbar.setActionTextColor (Color.WHITE) .show ();
Ahamadullah Saikat

Snackbar 설정에 버그가 있거나 색상이 아무것도하지 않았습니다. 이 방법은 무엇이든 상관없이 작동하지만 다른 사람들에게는 최적의 솔루션이 아닐 수 있습니다.
JPM

이를 위해서는 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 2015

2
참고 snackbar_actionsnackbar_text. 대신을 사용하여 작업 텍스트에 대해 동일한 작업을 수행 할 수 있습니다 . 예
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(com.google.android.material.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

13
com.google.android.material.R.id.snackbar_textAndroidX로 마이그레이션하는 경우 사용 합니다.
Rishabh876

변경 @ Rishabh876 :)
Richard

14

그래서 기본적으로 텍스트 색상을 변경하는 방식으로 수정했습니다.

내 밝은 테마 android:textColorPrimary에서 normal dark text나는 원 함으로 설정 android:textColor하고로 설정 했습니다 white.

모든 텍스트보기와 버튼을 업데이트하여 android:textColor="?android:attr/textColorPrimary".

스낵바가에서 가져 오기 때문에 textColor다른 모든 텍스트를로 설정했습니다 textColorPrimary.

2017 년 1 월 수정 : ---------------------------------------------- ------

따라서 댓글이 말하고 위의 편집 된 원래 질문에서 언급했듯이 android:textColor테마 내에서 모든보기의 텍스트 색상이 변경되므로 테마에서 정의해서는 안됩니다 .


이 작업을 방금 완료했습니다. 휴, 시간이 좀 걸렸습니다! 그러나 구식 환경 설정 활동 (preferences.xml 사용)을 위해 아래의 "m vai"방법을 사용해야했습니다. 내 앱의 스타일링이 훨씬 더 정확한 테마 기반으로 남아 있다고 생각합니다. +1
OceanLife 2015 년

1
좋은 솔루션이 아닙니다 IMO, textview에 대한 실제 테마를 유지하고 snakbar 텍스트 색상 만 변경하고 싶습니다.
issamux

1
당신은 android:textColor당신의 주제에서 전혀 정의해서는 안됩니다 . 그것은 스타일 속성입니다 TextView. 테마 에서 정의하면 모든 텍스트 색상을 재정의 TextView하거나 ButtonXML에서 텍스트 색상을 지정하지 않습니다. 또한 일반적으로 어두운 테마 오버레이 에서 색상을 가져 오는 스낵바 메시지가 발생합니다 .
Eugen Pechanec

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.


U는 메달을받을 자격이 있습니다.
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

ID로 Snackbar에서 TextView를 찾는 더럽고 해키 한 솔루션을 사용하기로 결정하고 이미 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

Snackbar재료 구성 요소 라이브러리에 포함 된을 사용 하고

  • setTextColor 텍스트 색상을 정의하려면
  • setActionTextColor액션에 사용되는 텍스트 색상을 정의합니다. 색상 또는 색상 선택기를 사용할 수 있습니다.
  • setBackgroundTint Snackbar의 배경색 정의

다음과 같은 것 :

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

여기에 이미지 설명 입력


1

현재 (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는 이러한 스타일없이 일부 레거시 레이아웃을 사용합니다.

나는 모두가 소스 코드에서 발견 snackbarButtonStyle하고 snackbarTextViewStyle사용하지 않을 것이다, 그렇지 않으면 정의해야합니다.


0

Snackbar의 textview 인스턴스를 가져 오는 데 도움이되는 간단한 코드가 있습니다. 그 후에 textview에 적용 할 수있는 모든 메서드를 호출 할 수 있습니다.

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
    }

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