82 votes

Dispositions de notification personnalisées et couleurs du texte

Mon application affiche des notifications, et selon les préférences de l'utilisateur, il pourrait utiliser une mise en page personnalisée dans une notification. Il fonctionne bien, mais il y a un petit problème, les couleurs de texte. Stock Android et presque tous les fabricants de peaux d'utiliser du texte noir sur un fond clair pour la notification texte, mais Samsung n'est pas le cas: leur notification déroulant a un fond noir et le texte du défaut de notification de la mise en page est blanche.

Si cela pose un problème: les notifications qui n'utilisent pas toute fantaisie dispositions montrent bien, mais celui qui utilise une mise en page personnalisée est difficile à lire parce que le texte est noir au lieu de la valeur par défaut blanc. Même la documentation officielle ne fait qu'un #000 couleur pour un TextView, donc je ne pouvais pas trouver toutes les pointeurs.

Un utilisateur a eu la gentillesse de prendre une capture d'écran du problème:

Screenshot

Alors, comment puis-je utiliser la valeur par défaut de notification de la couleur de texte à partir de l'appareil dans ma présentation? Je préfère ne pas commencer à modifier dynamiquement la couleur du texte basé sur le modèle de téléphone, car cela demande beaucoup de mise à jour et les gens avec des custom ROM pourriez encore avoir le problème, en fonction de la peau qu'ils utilisent.

87voto

Malcolm Points 14261

La solution est d'utiliser les styles intégrés. Le style dont vous avez besoin est - TextAppearance.StatusBar.EventContent. Il suffit d'appliquer ce style et il sera de définir la couleur du texte par défaut pour les notifications (ne pas oublier android: préfixe, bien sûr).

Si vous êtes intéressé comment j'en suis arrivé à cette solution, voici mon trail de la chapelure.

  1. Lorsque vous utilisez Notification et définir le texte à l'aide intégrée dans les moyens, la ligne suivante crée la mise en page:

    RemoteViews contentView = new RemoteViews(context.getPackageName(),
            com.android.internal.R.layout.status_bar_latest_event_content);
    
  2. Le parlé de la mise en page contient les éléments suivants View qui est responsable de l'affichage de la notification texte:

    <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. Donc la conclusion est que le besoin style est - TextAppearance.StatusBar.EventContent, définition qui ressemble à ceci:

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

    Vous devriez noter ici que ce style n'est pas fait référence à aucun des couleurs, donc le moyen le plus sûr est d'appliquer ce style à la place de certaines couleurs intégré.

Une chose de plus: ce style n'existe que depuis Android 2.3 (API de Niveau 9). Avant cela, il n'y avait ni de styles, ni les couleurs, il y avait seulement des valeurs codées en dur. Pour une solution qui fonctionne sur Android 2.2 et les versions antérieures, voir la réponse par Gaks.

63voto

Gaks Points 906

Solution par Malcolm fonctionne très bien avec les API>=9. Voici la solution pour les anciens de l'API:

L'astuce est de créer un standard de notification objet puis traverser la valeur par défaut contentView créé par Notification.setLatestEventInfo(...). Lorsque vous trouvez la bonne TextView, qui vient d'obtenir l' tv.getTextColors().getDefaultColor().

Voici le code qui extrait le texte par défaut de la couleur et de la taille du texte (à l'échelle de la densité de pixels - 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;
    }
}

Appelez extractColors ie. dans onCreate() de votre service. Puis, quand vous êtes en train de créer la fonction de notification personnalisée, la couleur et la taille du texte que vous voulez sont en notification_text_color et 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);

17voto

A-IV Points 1315

Voici une solution pour toute version de SDK utilisant uniquement des ressources.

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: les valeurs codées en dur sont utilisées pour 2.2-. Ainsi, des problèmes peuvent survenir avec certains anciens firmwares personnalisés.

13voto

Pour 2.3+ (à Partir de Android documentation):

Utiliser le style android:TextAppearance.StatusBar.EventContent.Title pour le texte principal.

Utiliser le style android:TextAppearance.StatusBar.EventContent pour le texte secondaire.

2.2-, faire ce que Gaks suggéré dans une autre réponse à ce fil.

Si vous voulez compiler contre 2.2 et de soutien 2.3+, et le soutien toute la variété d'appareils, Gaks solution est le seul que je connaisse.

BTW, ce que Google a suggéré sur l'utilisation de la valeur ?android:attr/textColorPrimary 2.2-, n'est-ce pas de travail. Il suffit de l'essayer à l'aide de l'émulateur. Gaks chemin est le seul moyen.

Plus de ressources: Ce et cela ne fonctionne pas.

2voto

Austyn Mahoney Points 4252

Vous devez utiliser les couleurs spécifiées dans android.R.color

Par exemple: android.R.color.primary_text_light

Les développeurs de ROM personnalisés et les concepteurs de skin Android sont supposés les mettre à jour afin que les couleurs de votre application puissent être en ligne avec le reste du système. Cela inclut de vous assurer que votre texte apparaît correctement dans tout le système.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X