Android Lollipop中的通知背景为白色。我该怎么改变它?

时间:2015-01-27 11:31:51

标签: android background notifications android-5.0-lollipop transparent

我想在我的应用中显示消息通知。在以前的Android版本中,一切都很好,但在Lollipop中,通知背景是白色的。 我在layout_message_notification.xml中使用了这个XML代码进行通知布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_messageNotification"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight=".2"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent">

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitCenter"
            android:src="@drawable/message_icon"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight=".8"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent">

        <TextView
            android:id="@+id/textView_notification_title"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:gravity="right|center_vertical"
            android:layout_margin="15dp"/>

    </LinearLayout>

</LinearLayout>

我在棒棒糖中的通知显示如下: notification style in lollipop

如何使通知背景变暗或透明,就像以前版本的Android一样?

3 个答案:

答案 0 :(得分:7)

最后,如果您想关注官方材料设计specification

  

始终将样式资源用于自定义通知的文本

并使用您的通知的自定义布局,您可能会考虑不覆盖默认背景,但由于API版本而更改文本样式。您可以通过创建两个资源样式文件并根据当前API版本使用它们来实现它:

<强>值-V21 / notification_styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <!-- according to official recommendation custom notifications should has the same text style as default one-->
  <style name="NotificationHeader" parent="@android:style/TextAppearance.Material.Notification.Title" />
  <style name="NotificationContent" parent="@android:style/TextAppearance.Material.Notification.Line2" />
</resources>

<强>值/ notification_styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <!-- according to official recommendation custom notifications should has the same text style as default one-->
  <style name="NotificationHeader" parent="@android:style/TextAppearance.StatusBar.EventContent.Title" />
  <style name="NotificationContent" parent="@android:style/TextAppearance.StatusBar.EventContent" />
</resources>

答案 1 :(得分:6)

这个答案描述了一种改变通知背景颜色的 hacky 方法 注意:这是一个无证的解决方法;它基于反射,可能会在自定义固件上被破坏;它仅适用于Android Lollipop和Marshmallow版本;在Android N及更高版本上无效。我建议坚持使用默认颜色,除非你有充分的理由避免它。

<强> WHY
没有合法的方法为自定义通知设置背景颜色。根据 Material Design ,Google决定通知必须为白色或浅灰色,具体取决于其优先级。但是,Google也对此规则提出了两个例外:

  1. 旧应用程序的通知显示为黑色 背景
  2. 使用MediaStyle创建的通知可以是任何颜色。
  3. 由于第二个例外,这种限制看起来不合逻辑且不合理,这是唯一可能的借口,为什么你仍然想要使用自定义颜色而不是谷歌推荐(或强制?)的颜色。 / p>

    内在的内容
    让我们看看BaseStatusBar,看看如何施加这种限制。计算通知背景颜色的唯一位置是applyColorsAndBackgrounds method if语句的第一个分支用于遗留应用程序。到达此处的唯一方法是将应用程序的目标SDK设置为Build.VERSION_CODES.LOLLIPOP以下。在这种情况下,背景将变为黑色 我们对entry.row.setTintColor声明感兴趣。为了达到它,应该通过几个检查,包括isMediaNotification method中包含的检查。他们在这里:

    1. 通知必须包含常规视图和大视图。
    2. 两个视图中的顶级布局必须以com.android.internal.R.id.status_bar_latest_event_content作为其ID。
    3. 大型布局必须包含com.android.internal.R.id.media_actions作为其ID的小部件。
    4. 如何
      最有问题的是ID,只要它们在内部资源中声明,并且无法从应用程序的布局XML访问。
      第二个问题是通知中使用的RemoteViews只是应用程序中布局资源的ID,不能在代码中构造。因此,我们无法添加具有通过上述所有检查所需的ID的布局。

      但是,Google将addViewremoveAllViews方法添加到RemoteViews中以满足他们的需求(在MediaStyle通知中使用它们)并忘记将其设为私有。< / p>

      所以,最后的想法很简单:

      • 根据Google定义的内部布局构建通知(通过第二次检查)
      • 使用removeAllViews
      • 删除所有内容
      • 使用addView
      • 添加我们的自定义布局
      • 大视图的特殊情况:将包含media_actions的Google定义的布局添加到自定义布局中的隐藏视图(通过第3次检查)

      缺点:

      • 对未使用的视图进行充气(在充气后立即将其删除)
      • 复杂而深入的布局层次结构

      <强>解
      我们的自定义大视图必须包含FrameLayout,其中android.R.id.empty为其ID。实际上,这里可以使用任何ID,只需确保在代码中引用相同的ID(见下文)。

      // We need theese ids to use internal Android resources
      int topId = Resources.getSystem().getIdentifier("status_bar_latest_event_content", "id", "android");
      int topBigLayout = Resources.getSystem().getIdentifier("notification_template_material_big_media_narrow", "layout", "android");
      int topSmallLayout = Resources.getSystem().getIdentifier("notification_template_material_media", "layout", "android");
      
      RemoteViews viewSmall = ...; // Create our custom view here
      RemoteViews viewBig = ...; // Create our custom big view here
      
      // This is invisible inner view - to have media_actions in hierarchy
      RemoteViews innerTopView = new RemoteViews("android", topBigLayout);
      viewBig.addView(android.R.id.empty, innerTopView);
      
      // This should be on top - we need status_bar_latest_event_content as top layout
      RemoteViews topBigView = new RemoteViews("android", topBigLayout);
      topBigView.removeAllViews(topId);
      topBigView.addView(topId, viewBig);
      
      // This should be on top - we need status_bar_latest_event_content as top layout
      RemoteViews topSmallView = new RemoteViews("android", topSmallLayout);
      topSmallView.removeAllViews(topId);
      topSmallView.addView(topId, viewSmall);
      
      Notification.Builder builder = new Notification.Builder(this);
      
      builder.setSmallIcon(R.drawable.ic_notification)
              .setTicker("Some text")
              .setColor(0xff000000) // The desired color!
              .setContent(topSmallView);
      
      Notification n = builder.build();
      n.bigContentView = topBigView;
      
      // Use our notification "n" here as usual
      

      可以在顶层使用另一个布局而不是notification_template_material_big_media_narrow来操纵大视图的高度。在notification_template_xxx.xml文件中搜索适当的一个here。但是不要忘记将media_actions放入层次结构中。

答案 2 :(得分:3)

这是通知的正确行为。

如果您希望直接控制此方面,我建议您执行以下操作:

  • 在文件夹layout_message_notification.xml

  • 中创建res/layout-v21的替代版本
  • 通过更改外部布局的背景颜色对此新版本稍加更改:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_messageNotification"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/gray">
//...