Mi aplicación muestra algunas notificaciones y, según las preferencias del usuario, puede usar un diseño personalizado en una notificación. Funciona bien, pero hay un pequeño problema: los colores del texto . Stock de Android y casi todas las máscaras de los fabricantes usan texto negro sobre un fondo claro para el texto de notificación, pero Samsung no: su menú desplegable de notificaciones tiene un fondo oscuro y el texto en el diseño de notificación predeterminado es blanco.
Entonces, esto causa un problema: las notificaciones que no usan ningún diseño elegante se muestran bien, pero la que usa un diseño personalizado es difícil de leer porque el texto es negro en lugar del blanco predeterminado. Incluso la documentación oficial solo establece un #000
color para a TextView
, por lo que no pude encontrar ningún puntero allí.
Un usuario tuvo la amabilidad de tomar una captura de pantalla del problema:
Entonces, ¿ cómo utilizo el color de texto de notificación predeterminado del dispositivo en mis diseños? Prefiero no comenzar a alterar dinámicamente el color del texto según el modelo de teléfono, ya que eso requiere mucha actualización y las personas con ROM personalizadas aún pueden tener el problema, dependiendo de la máscara que estén usando.
Respuestas:
La solución de Malcolm funciona bien con API> = 9. Aquí está la solución para API más antiguas:
El truco consiste en crear el objeto de notificación estándar y luego recorrer el predeterminado
contentView
creado porNotification.setLatestEventInfo(...)
. Cuando encuentre el TextView correcto, simplemente obtenga eltv.getTextColors().getDefaultColor()
.Aquí está el código que extrae el color y el tamaño del texto predeterminados (en píxeles de densidad escalados - 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; } }
Llame
extractColors
ie. en onCreate () de su servicio. Luego, cuando esté creando la notificación personalizada, el color y el tamaño del texto que desea están ennotification_text_color
ynotification_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);
fuente
Solution by Malcolm works fine with API>=9
. Ya sabes, Android y los fabricantes son algo complicado. Utilice esta solución para cada plataforma.La solución es utilizar estilos integrados. El estilo que necesita se llama
TextAppearance.StatusBar.EventContent
en Android 2.3 y Android 4.x. En Android 5.x notificaciones materiales utilizan varios otros estilos:TextAppearance.Material.Notification
,TextAppearance.Material.Notification.Title
, yTextAppearance.Material.Notification.Line2
. Simplemente configure la apariencia de texto apropiada para la vista de texto y obtendrá los colores necesarios.Si está interesado en cómo he llegado a esta solución, aquí está mi rastro de migas de pan. Los extractos del código se tomaron de Android 2.3.
Cuando usa
Notification
y configura el texto usando medios integrados, la siguiente línea crea el diseño:RemoteViews contentView = new RemoteViews(context.getPackageName(), com.android.internal.R.layout.status_bar_latest_event_content);
El diseño mencionado contiene lo siguiente
View
que es responsable de ver el texto de notificación:<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" />
Entonces, la conclusión es que el estilo necesario es
TextAppearance.StatusBar.EventContent
, cuya definición se ve así:<style name="TextAppearance.StatusBar.EventContent"> <item name="android:textColor">#ff6b6b6b</item> </style>
Debe tener en cuenta aquí que este estilo en realidad no hace referencia a ninguno de los colores incorporados, por lo que la forma más segura es aplicar este estilo en lugar de algún color incorporado.
Una cosa más: antes de Android 2.3 (API nivel 9), no había estilos ni colores, solo había valores codificados. Si tiene que admitir versiones tan antiguas por algún motivo, consulte la respuesta de Gaks .
fuente
style="@android:style/TextAppearance.StatusBar.EventContent"
) y obtiene el color necesario para el texto. Será#ff6b6b6b
en el caso de Android vainilla, o cualquier color que haya establecido el proveedor del dispositivo.Aquí hay una solución para cualquier versión de SDK que utilice solo recursos.
<?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>
<?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>
... <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: Los valores codificados de forma rígida se utilizan para 2.2-. Por lo tanto, pueden ocurrir problemas con algunos firmwares personalizados antiguos raros.
fuente
Para 2.3+ (de la documentación de Android ):
Utilice el estilo
android:TextAppearance.StatusBar.EventContent.Title
para el texto principal.Utilice el estilo
android:TextAppearance.StatusBar.EventContent
para el texto secundario.Para 2.2-, haga lo que Gaks sugirió en otra respuesta a este hilo.
Si desea compilar contra 2.2 y admitir 2.3+, y admitir toda la variedad de dispositivos que existen, la solución de Gaks es la única que conozco.
Por cierto, lo que Google sugirió sobre el uso del valor
?android:attr/textColorPrimary
de 2.2-, no está funcionando. Pruébalo usando el emulador. El camino de Gaks es el único camino.Más recursos: esto y esto no funcionan.
fuente
Yo uso esto en el TextView en cuestión:
style="@style/TextAppearance.Compat.Notification.Title"
Me da texto blanco si el fondo es negro y texto negro si el fondo es blanco. Y funciona al menos desde API 19.
fuente
Debe utilizar los colores especificados en
android.R.color
Por ejemplo:
android.R.color.primary_text_light
Se supone que los desarrolladores de ROM personalizados y los diseñadores de máscaras de Android deben actualizarlos para que los colores de su aplicación puedan estar en línea con el resto del sistema. Esto incluye asegurarse de que su texto se muestre correctamente en todo el sistema.
fuente
android.R.color
? Todos los colores del texto tienen variaciones tanto "oscuras" como "claras".Mira estas instrucciones: http://developer.android.com/guide/topics/ui/notifiers/notifications.html#CustomExpandedView Si configuras tu color de fondo para el contenedor LinearLayout, entonces puedes tener tus colores en notificaciones para texto y el fondo.
Si la aplicación del iniciador define el color predeterminado para el texto de la notificación, no podrá recuperarlo de la configuración predeterminada de Android a menos que el iniciador comparta esta información.
Sin embargo, ¿ha intentado eliminar esta línea android: textColor = "# 000" de su diseño para que pueda obtener automáticamente el color predeterminado?
fuente
Encontré una solución muy simple que cambia directamente el nombre del atributo proporcionado por Android.
Como puedes ver en este tutorial: http://www.framentos.com/android-tutorial/2012/02/20/how-to-create-a-custom-notification-on-android/
Solo necesita usar un atributo diferente:
<item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
¡Espero que esto le pueda ayudar!
fuente
Sé que es una pregunta antigua, pero podría ayudar a otra persona; ) Hago esto en mi aplicación y funciona perfecto en algunas líneas:
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; }
fuente
La solución de @Malckom no me ayudó en Lolipop con un fondo de notificación oscuro debido a TextAppearance.Material.Notification.Title es un color codificado del sistema. La solución de @grzaks lo hizo, pero con algunos cambios dentro del proceso de creación de notificaciones:
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(); } } // ...
fuente
Esto es lo que funcionó para mí para resolver este error. Agregue lo siguiente a 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>
fuente
En su diseño expandible o contraído, establezca
android:background
como un"@android:color/transparent"
porque esto automáticamente toma el color del tema de notificación de su dispositivo y lo establece como fondo<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" />
Y el color de su vista de texto define el blanco y negro como en un
Resource/color
archivo en un archivo de color simple y como un archivo de color en modo nocturnofuente