web-dev-qa-db-ja.com

カスタム通知レイアウトとテキストの色

私のアプリケーションはいくつかの通知を表示し、ユーザー設定に応じて、通知でカスタムレイアウトを使用する場合があります。それはうまくいきますが、小さな問題があります-テキストの色。在庫Androidおよびほぼすべてのメーカースキンは、通知テキストに明るい背景に対して黒いテキストを使用しますが、Samsungは使用しません。通知プルダウンの背景が暗いため、デフォルトの通知レイアウトのテキストは白です。 。

そのため、これにより問題が発生します。派手なレイアウトを使用しない通知は問題なく表示されますが、カスタムレイアウトを使用する通知は、テキストがデフォルトの白ではなく黒であるため読みにくくなります。 公式ドキュメント でもTextView#000色を設定しているだけなので、そこにポインタが見つかりませんでした。

ユーザーは、問題のスクリーンショットを撮ってくれました。

Screenshot

だからレイアウトでデバイスからのデフォルトの通知テキストの色をどのように使用しますか?電話モデルに基づいてテキストの色を動的に変更し始めるのはやめたいです。なぜなら、それは多くの更新を必要とし、使用しているスキンによってはカスタムROMを持つ人々がまだ問題を抱えている可能性があるからです。

79
Veeti

Malcolmによるソリューションは、API> = 9で正常に機能します。古いAPIのソリューションは次のとおりです。

トリックは、標準の通知オブジェクトを作成し、Notification.setLatestEventInfo(...)によって作成されたデフォルトのcontentViewをトラバースすることです。適切な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_colorおよびnotification_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);
59
grzaks

解決策は、組み込みスタイルを使用することです。必要なスタイルはTextAppearance.StatusBar.EventContent in Android 2.3 and Android 4.x. In Android 5.xマテリアル通知は、他のいくつかのスタイルを使用します。 TextAppearance.Material.NotificationTextAppearance.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>
    

    ここで、このスタイルは実際には組み込み色を参照しないため、最も安全な方法は、組み込み色の代わりにこのスタイルを適用することです。

もう1つ:Android 2.3(APIレベル9)以前は、スタイルも色もありませんでした。ハードコーディングされた値しかありませんでした。理由については、 Gaksによる回答 を参照してください。

81
Malcolm

リソースのみを使用する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-に使用されます。そのため、いくつかのまれな古いカスタムファームウェアで問題が発生する可能性があります。

17
A-IV

2.3以降の場合(From Android documentation ):

プライマリテキストにはAndroid:TextAppearance.StatusBar.EventContent.Titleスタイルを使用します。

セカンダリテキストにはAndroid:TextAppearance.StatusBar.EventContentスタイルを使用します。

2.2-の場合、このスレッドに対する別の回答で Gaksが提案した を実行します。

2.2に対してコンパイルし、2.3 +をサポートし、世の中にあるさまざまなデバイスをすべてサポートしたい場合、私が知っているのはGaksのソリューションだけです。

ところで、Googleが2.2-に?android:attr/textColorPrimaryの値を使用することを提案したのは機能していません。エミュレータを使用して試してください。 Gaksの方法が唯一の方法です。

その他のリソース: This および this は機能しません。

13

Android.R.colorで指定された色を使用する必要があります

例:Android.R.color.primary_text_light

カスタムROM開発者およびAndroidスキンデザイナーはこれらを更新して、アプリの色がシステムの他の部分と一致するようにします。これには、テキストはシステム全体に正しく表示されます。

2
Austyn Mahoney

問題のTextViewでこれを使用します。

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

背景が黒の場合は白のテキスト、背景が白の場合は黒のテキストが表示されます。そして、少なくともAPI 19にまで遡って動作します。

1
Gavin Wright

Androidが提供する属性の名前を直接変更する非常に簡単なソリューションを見つけました。

このチュートリアルでわかるように、 http://www.framentos.com/Android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-Android/ =

別の属性を使用するだけです。

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

これがあなたを助けることを願っています!

1
Mauri

この手順をご覧ください: http://developer.Android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView LinearLayoutコンテナの背景色を設定すると、テキストと背景の通知の色。

通知テキストのデフォルトの色がランチャーアプリケーションによって定義されている場合、ランチャーがこの情報を共有していない限り、Androidデフォルト設定から取得できません。

ただし、レイアウトからこの行Android:textColor = "#000"を削除して、デフォルトの色を自動的に取得できるようにしましたか?

1
Lumis

私はそれが古い質問であることを知っていますが、他の誰かを助けることができます。 )私は自分のアプリでこれを行いますが、それはいくつかの行で完璧に動作します:

    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
Samet

TextAppearance.Material.Notification.Titleはシステムのハードコーディングされた色であるため、@ Malckomからのソリューションは、通知の背景が暗い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
Yurii Solopov

このエラーを解決するために私が働いたのは次のとおりです。以下を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
inder