Program Tip

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

programtip 2020. 10. 9. 12:15
반응형

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


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

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

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

스크린 샷

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


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

해결책은 기본 제공 스타일을 사용하는 것입니다. 필요한 스타일 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답변을 참조하십시오 .


다음은 리소스 만 사용하는 모든 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-에는 하드 코딩 된 값이 사용됩니다. 따라서 일부 드문 오래된 사용자 지정 펌웨어에서 문제가 발생할 수 있습니다.


2.3 이상 ( Android 문서에서 ) :

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

android:TextAppearance.StatusBar.EventContent보조 텍스트에 스타일 사용합니다 .

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

If you want to compile against 2.2 and support 2.3+, and support all the variety of devices out there, Gaks' solution is the only one I know.

BTW, what Google suggested about using the value ?android:attr/textColorPrimary for 2.2-, isn't working. Just try it using the emulator. Gaks' way is the only way.

More resources: This and this do not work.


You should use the colors specified in android.R.color

For example: android.R.color.primary_text_light

Custom ROM developers and Android skin designers are supposed to update these so your app's colors can be in line with the rest of the system. This includes making sure your text shows up properly throughout the system.


Lookin at this instructions: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView If you set up your background color for the LinearLayout container then you can have your colors in notification for text and the background.

If the default colour for the notification text is defined by the launcher application then you cannot retrieve it from the android defaults settings unless the launcher is sharring this information.

However, have you try to remove this line android:textColor="#000" from your layout so that it can get automatically the default color?


I've found a very simple solution directly changing the name of the attribute provided by Android.

As you can see in this tutorial: http://www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/

You only need to use a different attribute:

<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>

Hope this can help you!


I use this on the TextView in question:

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

It gives me white text if the background is black and black text if the background is white. And it works at least as far back as API 19.


Solution from @Malckom didn't help me at Lolipop with dark notification background because of TextAppearance.Material.Notification.Title is a system hardcoded color. Solution from @grzaks did, but with some changes within notification creating process:

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

I know it is an old question but it could help someone else ; ) I do this in my app and that works perfect in some few lines :

    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;

    }

이 오류를 해결하는 데 도움이 된 것은 다음과 같습니다. 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>

참고 URL : https://stackoverflow.com/questions/4867338/custom-notification-layouts-and-text-colors

반응형