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


81

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

したがって、これにより問題が発生します。派手なレイアウトを使用しない通知は正常に表示されますが、カスタムレイアウトを使用する通知は、テキストがデフォルトの白ではなく黒であるため、読みにくくなります。公式ドキュメントでさえ、の#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;
    }
}

extractColorsieを呼び出します。サービスの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素晴らしい答え。うまく機能します。タイトルとメインコンテンツの2つの異なるデフォルトの色があるように見えることに気づきました。両方をフェッチしたいのですが、このメソッドを使用してタイトルの色を取得することしかできませんでした。反復では1つのテキストボックスしか検出されないようです。何か案は?
隠者

1
@Rawと同じように見えますが、TextViewは1つだけです。「Utest」を別の検索ヒント(および別の文字列)に置き換えました。1つのTextViewのみが検出され、COLOR_SEARCH_RECURSE_TIPと一致します。ポインタはありますか?どうも。
ciscogambo 2011年

6
1つしか見つからない理由は、「return recurseGroup((ViewGroup)gp.getChildAt(i));」のバグです。-メソッドは、内部の「recurseGroup」がtrueを返した場合にのみ返されます。「if(recurseGroup((ViewGroup)gp.getChildAt(i)))returntrue;」のようになります。解決策をありがとう-箱から出してすぐに考えることができます。
AlikElzin-kilaka 2011

9
この回答をありがとう、それは非常に役に立ちました。興味のある人のために、Gaksの回答に基づいてタイトルとテキストの色/サイズの両方を取得するために立ち寄ることができるよりも簡単なクラスをまとめました。これは、ここで見つけることができます:pastebin.com/sk08QGxs
NuSkooler

3
それはだから、この文の用心真実ではない(APIレベル10でギャラクシーエースでテスト): Solution by Malcolm works fine with API>=9。ご存知のとおり、Androidとメーカーは注意が必要です。すべてのプラットフォームにこのソリューションを使用してください。
cprcrack 2013

83

解決策は、組み込みのスタイルを使用することです。必要なスタイルはTextAppearance.StatusBar.EventContent、Android2.3およびAndroid4.xで呼び出されます。:アンドロイド5.xの材料の通知では、いくつかの他のスタイルを使用してTextAppearance.Material.NotificationTextAppearance.Material.Notification.TitleTextAppearance.Material.Notification.Line2。テキストビューに適切なテキストの外観を設定するだけで、必要な色が得られます。

私がこの解決策にどのように到達したかに興味がある場合は、これが私のパンくずリストです。コードの抜粋はAndroid2.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による回答を参照してください。


私はこの答えを理解していないと思います。最後の文は、これに使用できるカラーリファレンスがないことを示しています。この場合、どの色を使用する必要がありますか?
スティーブポメロイ2011年

そうは言っても、Androidの変更ログで、APIレベル9の時点でのみ、android:textAppearance = "@ androidstyle /TextAppearance.StatusBar.EventContent"が公開されていることに気づきました。それ以前は隠されていました。
スティーブポメロイ2011年

1
それはAndroid2.3の前に隠されていませんでした、それは単に存在していませんでした。当時、レイアウトにはハードコードされた値があり、デバイスベンダーがそれを変更することを決定した場合、あなたはそれについて何もすることができません。この値にアクセスできる色やスタイルはありませんでした。現在、まだ色はありませんが、この特定のテキストの色を取得するために適用できるスタイルがあります。意味がありますか?:)
マルコム

3
どんなローカルスタイル?私の答えのスタイルは、Androidソースから直接取得されています。他の組み込みスタイル(style="@android:style/TextAppearance.StatusBar.EventContent")と同じように適用し、テキストに必要な色を取得します。それはなるつもりだ#ff6b6b6bバニラのAndroidの場合、または任意の色は、デバイスのベンダが代わりにそこに設定しました。
マルコム

4
他の人に知らせるために、これはAndroid 6以降では機能しません
iGoDa 2015

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


テキストの色が必要ですか?親はすでにそれを設定していますね
Androidデベロッパー

13

2.3以降の場合(Androidドキュメントから):

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

android:TextAppearance.StatusBar.EventContent二次テキストのスタイルを使用します。

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

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

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

その他のリソース:これこれは機能しません。


5
2.3以降の手順はAndroid5では機能しませんでした。白い背景に白いテキストが生成されました。
サム

5

私は問題のTextViewでこれを使用します:

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

背景が黒の場合は白のテキスト、背景が白の場合は黒のテキストが表示されます。そして、少なくともAPI19までさかのぼって機能します。


2

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

例えば: android.R.color.primary_text_light

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


何色から使うのandroid.R.color?すべてのテキストの色には、「暗い」と「明るい」の両方のバリエーションがあります。
Veeti 2011

1
カスタムテーマのあるデバイスを持っていないので、どれを使用するかを実際にテストすることはできません。両方を試して、どちらがあなたに適しているかを確認してください。
オースティンマホニー2011

1

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

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

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


1
テキストの色を削除しても効果はありません。デフォルトでは通知の色と一致しません。
Veeti 2011

背景を変えてみましたか?これは深刻な問題だと思いますので、よろしくお願いします。Googleデベロッパーフォーラム/グループを試しましたか?
Lumis 2011


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:backgroundのように"@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" />

また、テキストビューの色はResource/color、シンプルカラーファイルおよびナイトモードカラーファイルのファイルと同様に、白黒を定義します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.