我想在我的应用程序中显示消息通知。在以前的 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>
我在 Lollipop 中的通知显示如下:
如何使通知背景变暗或透明,就像在以前的 Android 版本中一样?
最佳答案
这个答案描述了 哈克更改通知背景颜色的方法。
注意:这是一个未记录的解决方法 ;它基于反射,可能会在自定义固件上被破坏;仅适用于 Android Lollipop 和 Marshmallow 版本;它不会工作在 Android N 及更高版本上。我建议坚持使用默认颜色,除非您有充分的理由避免使用它。
为什么
没有为自定义通知设置背景颜色的合法方法。 Google 根据 Material Design 决定通知必须是白色或浅灰色,具体取决于其优先级。然而,谷歌也对这条规则做了两个异常(exception):
背景;
MediaStyle
创建的通知可以是任何颜色。 由于第二个异常(exception),这种限制看起来不合逻辑且不合理,这是您仍然想使用自定义颜色而不是谷歌推荐(或强制?)的唯一可能的借口。
里面有什么
让我们看看
BaseStatusBar
看看这个限制是如何施加的。唯一计算通知背景颜色的地方是applyColorsAndBackgrounds method .if
的第一个分支声明适用于遗留应用程序。到达这里的唯一方法是将应用程序的目标 SDK 设置在 Build.VERSION_CODES.LOLLIPOP
以下。 .在这种情况下,背景将变为黑色。我们对
entry.row.setTintColor
感兴趣陈述。要达到它,应该通过几项检查,包括 isMediaNotification method 中的一项。 .他们来了:com.android.internal.R.id.status_bar_latest_event_content
作为它的 ID。 com.android.internal.R.id.media_actions
的小部件作为它的 ID。 如何
最有问题的是 ID,只要它们在内部资源中声明并且不能从应用程序的布局 XML 访问。
第二个问题是
RemoteViews
通知中使用的只是应用程序内布局资源的ID,不能在代码中构造。因此,我们无法添加具有通过上述所有检查所需的 ID 的布局。然而,谷歌添加了
addView
和 removeAllViews
方法到 RemoteViews
满足他们的需要(它们在 MediaStyle
通知中使用)并且忘记将它们设为私有(private)。所以,最终的想法很简单:
removeAllViews
删除所有内容addView
添加我们的自定义布局media_actions
在我们的自定义布局中隐藏 View (通过第三次检查)缺点:
解决方案
我们的自定义大 View 必须包含
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
在顶层操作大 View 的高度。搜索合适的here在 notification_template_xxx.xml 文件中。但不要忘记把 media_actions
进入层次结构。
关于android - Android Lollipop 中的通知背景是白色的。我怎样才能改变它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28169474/