사용자 지정 알림 레이아웃 및 텍스트 색상


81

내 응용 프로그램은 일부 알림을 표시하며 사용자 기본 설정에 따라 알림에서 사용자 정의 레이아웃을 사용할 수 있습니다. 잘 작동하지만 텍스트 색상 이라는 작은 문제가 있습니다. 재고 Android 및 거의 모든 제조업체 스킨은 알림 텍스트에 밝은 배경에 검은 색 텍스트를 사용하지만 삼성은 그렇지 않습니다. 알림 풀다운에 어두운 배경이 있고 기본 알림 레이아웃의 텍스트는 흰색입니다.

따라서 이로 인해 문제가 발생합니다. 멋진 레이아웃을 사용하지 않는 알림은 잘 표시되지만 사용자 지정 레이아웃을 사용하는 알림은 텍스트가 기본 흰색 대신 검은 색이기 때문에 읽기가 어렵습니다. 공식 문서 조차도에 대한 #000색상을 설정하기 TextView때문에 거기에서 포인터를 찾을 수 없습니다.

사용자는 문제의 스크린 샷을 찍을만큼 친절했습니다.

스크린 샷

그렇다면 레이아웃 에서 장치의 기본 알림 텍스트 색상을 어떻게 사용 합니까? 전화 모델을 기반으로 텍스트 색상을 동적으로 변경하는 대신 많은 업데이트가 필요하고 사용자 지정 ROM을 사용하는 사람들이 사용중인 피부에 따라 문제가 발생할 수 있기 때문에 차라리 시작하지 않습니다.


9
더 이상 사용할 수없는 이미지
Amir Uval 2013 년

가능하면 이미지를 다시 업로드하십시오.
Maciej Gol

답변:


63

Malcolm의 솔루션은 API> = 9에서 잘 작동합니다. 다음은 이전 API에 대한 솔루션입니다.

트릭은 표준 알림 개체를 contentView만든 다음에서 만든 기본값을 탐색하는 것 Notification.setLatestEventInfo(...)입니다. 올바른 TextView를 찾으면 tv.getTextColors().getDefaultColor().

다음은 기본 텍스트 색상과 텍스트 크기를 추출하는 코드입니다 (크기 조정 된 밀도 픽셀-sp).

private Integer notification_text_color = null;
private float notification_text_size = 11;
private final String COLOR_SEARCH_RECURSE_TIP = "SOME_SAMPLE_TEXT";

private boolean recurseGroup(ViewGroup gp)
{
    final int count = gp.getChildCount();
    for (int i = 0; i < count; ++i)
    {
        if (gp.getChildAt(i) instanceof TextView)
        {
            final TextView text = (TextView) gp.getChildAt(i);
            final String szText = text.getText().toString();
            if (COLOR_SEARCH_RECURSE_TIP.equals(szText))
            {
                notification_text_color = text.getTextColors().getDefaultColor();
                notification_text_size = text.getTextSize();
                DisplayMetrics metrics = new DisplayMetrics();
                WindowManager systemWM = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
                systemWM.getDefaultDisplay().getMetrics(metrics);
                notification_text_size /= metrics.scaledDensity;
                return true;
            }
        }
        else if (gp.getChildAt(i) instanceof ViewGroup)
            return recurseGroup((ViewGroup) gp.getChildAt(i));
    }
    return false;
}

private void extractColors()
{
    if (notification_text_color != null)
        return;

    try
    {
        Notification ntf = new Notification();
        ntf.setLatestEventInfo(this, COLOR_SEARCH_RECURSE_TIP, "Utest", null);
        LinearLayout group = new LinearLayout(this);
        ViewGroup event = (ViewGroup) ntf.contentView.apply(this, group);
        recurseGroup(event);
        group.removeAllViews();
    }
    catch (Exception e)
    {
        notification_text_color = android.R.color.black;
    }
}

extractColors즉 전화 . 서비스의 onCreate ()에서. 그런 다음 사용자 지정 알림을 만들 때 원하는 색상과 텍스트 크기는 다음 notification_text_colornotification_text_size같습니다.

Notification notification = new Notification();
RemoteViews notification_view = new RemoteViews(getPackageName(), R.layout.notification);       
notification_view.setTextColor(R.id.label, notification_text_color);
notification_view.setFloat(R.id.label, "setTextSize", notification_text_size);

1
+1 좋은 답변. 잘 작동합니다. 제목과 주요 콘텐츠에 대해 두 가지 기본 색상이있는 것으로 나타났습니다. 둘 다 가져오고 싶지만이 방법을 사용하여 제목 색상 만 가져올 수있었습니다. 반복은 1 개의 텍스트 상자 만 찾는 것 같습니다. 어떤 아이디어?
Hermit

1
@Raw와 동일하게 TextView가 하나만 표시됩니다. "Utest"를 다른 검색 팁 (및 다른 문자열)으로 대체했습니다. 하나의 TextView 만 찾고 COLOR_SEARCH_RECURSE_TIP과 일치합니다. 포인터가 있습니까? 고마워.
ciscogambo

6
하나만 찾는 이유는 "return recurseGroup ((ViewGroup) gp.getChildAt (i));"의 버그 때문입니다. -메소드는 내부 "recurseGroup"이 true를 리턴 한 경우에만 리턴해야합니다. "if (recurseGroup ((ViewGroup) gp.getChildAt (i))) return true;"여야합니다. 솔루션에 감사드립니다.
AlikElzin-kilaka 2011

9
이 답변에 감사드립니다. 매우 도움이되었습니다. 관심있는 사람을 위해 Gaks 답변을 기반으로 제목과 텍스트 색상 / 크기를 모두 가져 오기 위해 드롭 할 수있는 빠른 수업을 함께했습니다. 여기에서 찾을 수 있습니다. pastebin.com/sk08QGxs
NuSkooler

3
이 때문에이 문장을 조심 사실이 아니다 (API 레벨 10으로 갤럭시 에이스에서 테스트) Solution by Malcolm works fine with API>=9. 아시다시피 Android와 제조업체는 까다로운 것입니다. 모든 플랫폼에이 솔루션을 사용하십시오.
cprcrack

83

해결책은 기본 제공 스타일을 사용하는 것입니다. 필요한 스타일 TextAppearance.StatusBar.EventContent은 Android 2.3 및 Android 4.x에서 호출 됩니다. 안드로이드에서 5.x의 재료 통지는 여러 가지 다른 스타일을 사용 : TextAppearance.Material.Notification, TextAppearance.Material.Notification.Title,와 TextAppearance.Material.Notification.Line2. 텍스트보기에 적절한 텍스트 모양을 설정하기 만하면 필요한 색상을 얻을 수 있습니다.

이 솔루션에 어떻게 도달했는지 관심이 있으시면 여기 내 탐색 경로가 있습니다. 코드 발췌는 Android 2.3에서 가져온 것입니다.

  1. Notification기본 제공 수단을 사용하여 텍스트 를 사용 하고 설정하면 다음 줄이 레이아웃을 만듭니다.

    RemoteViews contentView = new RemoteViews(context.getPackageName(),
            com.android.internal.R.layout.status_bar_latest_event_content);
    
  2. 언급 된 레이아웃에는 View알림 텍스트보기를 담당 하는 다음 이 포함 됩니다.

    <TextView android:id="@+id/text"
        android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:fadingEdge="horizontal"
        android:paddingLeft="4dp"
        />
    
  3. 따라서 결론은 필요한 스타일이 TextAppearance.StatusBar.EventContent입니다. 정의는 다음과 같습니다.

    <style name="TextAppearance.StatusBar.EventContent">
        <item name="android:textColor">#ff6b6b6b</item>
    </style>
    

    이 스타일은 실제로 기본 제공 색상을 참조하지 않으므로 가장 안전한 방법은 기본 제공 색상 대신이 스타일을 적용하는 것입니다.

한 가지 더 : Android 2.3 (API 레벨 9) 이전에는 스타일도 색상도 없었고 하드 코딩 된 값만있었습니다. 어떤 이유로 이러한 이전 버전을 지원해야하는 경우 Gaks답변을 참조하십시오 .


이 대답을 이해하지 못하는 것 같습니다. 마지막 문장은이를 위해 사용할 수있는 색상 참조가 없다고 말합니다. 이 경우 어떤 색상을 사용해야합니까?
Steve Pomeroy

즉, Android의 변경 로그에서 API 레벨 9에서만 android : textAppearance = "@ androidstyle / TextAppearance.StatusBar.EventContent"가 공개되었습니다. 그 전에는 숨겨져있었습니다.
Steve Pomeroy 2011 년

1
Android 2.3 이전에는 숨겨지지 않았으며 단순히 존재하지 않았습니다. 당시에는 레이아웃에 하드 코딩 된 값이 있었는데, 장치 공급 업체가이를 변경하기로 결정하면 이에 대해 아무것도 할 수 없습니다. 이 값에 액세스 할 수있는 색상이나 스타일이 없습니다. 지금은 여전히 ​​색상이 없지만 특정 텍스트 색상을 얻기 위해 적용 할 수있는 스타일이 있습니다. 말이 되나? :)
Malcolm 2011 년

3
어떤 지역 스타일? 내 대답의 스타일은 Android 소스에서 직접 가져온 것입니다. 다른 내장 스타일 ( style="@android:style/TextAppearance.StatusBar.EventContent") 로 적용 하고 텍스트에 필요한 색상을 얻습니다. 그것은 될거야 #ff6b6b6b바닐라 안드로이드의 경우, 또는 어떤 색상 장치 공급 업체에서 대신이 설정되었다.
Malcolm 2011 년

4
그냥 다른 사람들이,이 6+ 안드로이드에서 작동하지 않습니다 알려합니다
iGoDa

17

다음은 리소스 만 사용하는 모든 SDK 버전에 대한 솔루션입니다.

res / values ​​/ styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationTitle">
      <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
      <item name="android:textStyle">bold</item>
    </style>
    <style name="NotificationText">
      <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
    </style>
</resources>

res / values-v9 / styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationText" parent="android:TextAppearance.StatusBar.EventContent" />
    <style name="NotificationTitle" parent="android:TextAppearance.StatusBar.EventContent.Title" />
</resources>

res / layout / my_notification.xml

...
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="title"
    style="@style/NotificationTitle"
    />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="text"
    style="@style/NotificationText"
    />
...

PS : 2.2-에는 하드 코딩 된 값이 사용됩니다. 따라서 일부 드문 오래된 사용자 지정 펌웨어에서 문제가 발생할 수 있습니다.


텍스트 색상이 필요합니까? 부모가 이미 설정 했죠?
안드로이드 개발자

13

2.3 이상 ( Android 문서에서 ) :

android:TextAppearance.StatusBar.EventContent.Title기본 텍스트에 스타일 을 사용하십시오 .

android:TextAppearance.StatusBar.EventContent보조 텍스트에 스타일 을 사용하십시오 .

2.2-의 경우이 스레드에 대한 다른 답변에서 Gaks가 제안한 것을 수행하십시오 .

2.2에 대해 컴파일하고 2.3 이상을 지원하고 모든 다양한 장치를 지원하려면 Gaks의 솔루션이 내가 아는 유일한 솔루션입니다.

?android:attr/textColorPrimary2.2- 의 값 을 사용하는 것에 대해 Google이 제안한 BTW 가 작동하지 않습니다. 에뮬레이터를 사용하여 시도하십시오. Gaks의 방법이 유일한 방법입니다.

더 많은 리소스 : 이것이것은 작동하지 않습니다.


5
2.3+ 지침이 Android 5에서 작동하지 않았습니다. 흰색 배경에 흰색 텍스트가 생성되었습니다.
Sam

5

문제의 TextView에서 이것을 사용합니다.

style="@style/TextAppearance.Compat.Notification.Title"

배경이 검은 색이면 흰색 텍스트를, 배경이 흰색이면 검은 색 텍스트를 제공합니다. 그리고 그것은 적어도 API 19까지 거슬러 올라갑니다.


2

에 지정된 색상을 사용해야합니다. android.R.color

예를 들면 : android.R.color.primary_text_light

커스텀 ROM 개발자와 Android 스킨 디자이너는 앱의 색상이 나머지 시스템과 일치 할 수 있도록이를 업데이트해야합니다. 여기에는 텍스트가 시스템 전체에 제대로 표시되는지 확인하는 것이 포함됩니다.


어떤 색을 사용해야 android.R.color하나요? 모든 텍스트 색상에는 "어두움"과 "밝음"변형이 모두 있습니다.
Veeti

1
사용자 지정 테마가있는 장치가 없어서 어떤 장치를 사용할지 실제로 테스트 할 수 없습니다. 둘 다 시도해보고 어떤 것이 당신에게 적합한 지 확인하십시오.
Austyn Mahoney

1

다음 지침을 참조하십시오 . http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView LinearLayout 컨테이너에 대한 배경색을 설정 한 경우 텍스트 및 배경.

알림 텍스트의 기본 색상이 런처 애플리케이션에 의해 정의 된 경우 런처가이 정보를 공유하지 않는 한 Android 기본 설정에서 검색 할 수 없습니다.

그러나 레이아웃에서 android : textColor = "# 000"줄을 제거하여 자동으로 기본 색상을 얻었습니까?


1
텍스트 색상을 제거해도 도움이되지 않습니다. 기본값은 알림 색상과 일치하지 않습니다.
Veeti

배경을 바꿔 보셨나요? 나는 이것이 심각한 문제라고 생각하고 당신이 그것을 제기 한 것이 좋습니다. Google 개발자 포럼 / 그룹을 사용해 보셨습니까?
Lumis


1

나는 그것이 오래된 질문이라는 것을 알고 있지만 다른 사람을 도울 수 있습니다. ) 내 앱에서이 작업을 수행하고 몇 줄에서 완벽하게 작동합니다.

    RemoteViews notificationView = new RemoteViews(context.getPackageName(), R.layout.notification_layout);

    if (SDK >= LOLLIPOP) {

            TextView textView = new TextView(context);
            textView.setTextAppearance(context, android.R.style.TextAppearance_Material_Notification_Title);

            notificationView.setTextColor(R.id.title, textView.getCurrentTextColor());
            notificationView.setFloat(R.id.title, "setTextSize", textView.getTextSize());

            textView.setTextAppearance(context,android.R.style.TextAppearance_Material_Notification_Line2);

            notificationView.setTextColor(R.id.contentText,textView.getCurrentTextColor());
            notificationView.setFloat(R.id.contentText,"setTextSize",textView.getTextSize());

            textView = null;

    }

0

@Malckom의 솔루션은 TextAppearance.Material.Notification.Title이 시스템 하드 코드 색상이기 때문에 어두운 알림 배경으로 Lolipop에서 나를 도와주지 않았습니다. @grzaks의 솔루션이 수행되었지만 알림 생성 프로세스 내에서 몇 가지 변경 사항이 있습니다.

NotificationCompat.Builder mBuilder =
    new NotificationCompat.Builder(this)
                          .setContentTitle(NOTIFICATION_TITLE_TIP)
                          .setContentText(NOTIFICATION_TEXT_TIP);
Notification ntf = mBuilder.build();
// ...
if (NOTIFICATION_TEXT_TIP.equals(szText)) {
    notification_text_color = text.getTextColors().getDefaultColor();
} else {
    if (NOTIFICATION_TITLE_TIP.equals(szText)) {
        notification_title_color = text.getTextColors().getDefaultColor();
    }
}
// ...

0

이 오류를 해결하는 데 도움이 된 것은 다음과 같습니다. styles.xml에 다음을 추가하십시오.

    <style name="TextAppearance">
    </style>
    <style name="TextAppearance.StatusBar">
    </style>
    <style name="TextAppearance.StatusBar.EventContent">
        <item name="android:textColor">#ff6b6b6b</item>
    </style>
    <style name="TextAppearance.StatusBar.EventContent.Info">
        <item name="android:textColor">#ff6b6b6b</item>
    </style>

0

당신의 expanable 또는 collaspse 레이아웃 설정에서 android:backgroundA와 "@android:color/transparent"이 때문에 자동으로 배경으로 장치 통지 테마 색상 및 설정을한다

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_margin="0dp"
android:background="@android:color/transparent"
android:orientation="vertical">
          <TextView

            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="@color/colorSecondary"
            android:textStyle="bold" />

그리고 textview 색상 Resource/color은 간단한 색상 파일 및 야간 모드 색상 파일의 파일에서와 같이 흑백을 정의 합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.