
通知,指的是一条可在妳的程序的正常界面之外显示给用户的消息.当妳要求系统显示一条通知时,它首先会以通知区域中一个图标的形式出现.如果想要查看该通知的详情的话,用户就可以打开通知抽屉.通知区域和通知抽屉都是由系统控制的,用户可在任何时候查看.
图 1. 通知区域中显示的通知.
图 2. 通知抽屉中显示的通知.
通知设计
通知,作为安卓用户界面中的一个重要组成部分,有着它们自己的设计原则.要想学习如何设计通知以及它们的交互行为的话,就阅读一下安卓设计原则中的通知这个主题.
注意:除非另有说明,否则,这篇文档所指的是版本4的 支持库 中的 NotificationCompat.Builder 类。 Notification.Builder 这个类是从安卓3.0开始加入的.
通知抽屉中的通知消息可以显示出两种不同的视频风格,这取决于通知抽屉的版本及状态:
普通视图
通知抽屉中的标准通知视图。
大视图
当某条通知被展开时,会显示出来的一个较大视图。大视图是安卓4.1中的扩展通知栏特性中的一个部分。
以下小节中说明这两个样式。
普通视图状态的通知消息,会显示在一个最大高度为 64 dp 的区域中。即使妳创建了一个具有大视图风格的通知消息,在被展开之前它也仍然会以普通视图状态显示。这是普通视图的一个示例:
图 3. 普通视图状态下的通知。
图中的数字对应着以下内容:
1.内容标题
2.大图标
3.内容文字
4.内容信息
5.小图标
6.该通知的发出时间。妳可以使用 setWhen() 来显式地设置一个值;如果妳不设置的话,就会默认按照系统收到这个通知时的时间来显示。
只有当一个通知被展开时,才会显示大视图状态。有两种情况会导致通知被展开:该通知位于通知抽屉的顶端;或者用户使用手势来展开了该通知。从安卓4.1开始,可以支持可展开的通知。
以下截图显示的是一个收件箱风格的通知:
图 4. 大视图状态下的通知。
注意,大视图状态下的通知与普通视图状态下的通知共用了大部分视觉元素。唯一的区别就是图中标注数字7的地方,那是详情区域。每个大视图风格会以不同方式来显示这个区域。以下列出可用的风格:
大图片风格
在详情区域可显示一张最大高度为 256 dp 的位图。
大文字风格
在详情区域显示一块巨型文字块。
收件箱风格
在详情区域显示多行文字。
所有的大视图风格中都拥有以下在普通视图状态下没有的内容选项:
大内容标题
允许妳设置一个只会在被展开模式下才显示出来的内容标题,它会替换掉普通视图中的内容标题。
汇总文字
允许妳在详情区域下面加入一行文字。
在给一个通知对象应用一个大视图风格小节中说明了如何给一个通知对象应用大视图风格。
妳应当在一个 NotificationCompat.Builder 对象中指定通知对象的界面信息及相应的动作。要创建该通知对象本身的话,妳需要调用 NotificationCompat.Builder.build() ,它会返回一个包含着妳指定信息的 Notification 对象。要发出该通知的话,可调用 NotificationManager.notify() 来将该 Notification 对象传递给系统。
一个 Notification 对象必须包含以下内容:
•.一个小图标,使用 setSmallIcon() 来设置
•.一个标题,使用 setContentTitle() 来设置
•.详情文字,使用 setContentText() 来设置
其它的通知选项和内容都是可选的。欲知详情,就去阅读 NotificationCompat.Builder 的参考文档。
尽管它们是可选的,但是,妳应当向妳的通知加入最少一个动作。动作使得用户可以从通知中直接跳转到妳的程序中的某个 Activity ,然后他/她们就可以了解到一条或多条更详细的信息,并且做出处理。
一个通知可提供多个动作。对于每个通知对象,妳都应该定义好当该通知被点击时所触发的动作;通常情况下,这个动作会打开妳的程序中的某个 Activity 。妳还可以向该通知对象添加一些按钮以便用户进行更多的动作,例如把闹钟延后或者立即回复某条文字消息;从安卓4.1开始支持这个特性。如果妳使用附加的动作按钮的话,那么,妳还必须在妳的程序中某个 Activity 里面实现相应的功能;参考 处理兼容性 小节以了解更多信息。
在一个 Notification 中,动作本身是由 PendingIntent 对象来定义的,其中包含着一个能够启动妳的程序中某个 Activity 的 Intent 。要将该 PendingIntent 与某个手势关联起来的话,就调用 NotificationCompat.Builder 中相应的方法。例如,如果妳希望当用户点击通知抽屉中的通知文字时启动某个 Activity 的话,就应当调用 setContentIntent() 以添加对应的 PendingIntent 。
当用户点击通知对象时启动某个 Activity ,这是最常见的动作。妳还可以在用户清除某条通知时启动一个 Activity 。在安卓4.1及更高版本的系统中,妳还可以通过一个动作按钮来启动一个 Activity 。欲知更多信息,就去阅读 NotificationCompat.Builder 的参考文档。
以下代码片断展示的是一个简单的通知,当用户点击该通知时会启动一个活动(activity)。注意,这段代码中创建了一个 TaskStackBuilder 对象,并且使用它来创建该动作的 PendingIntent 。这种设计模式在启动一个 Activity 时维持导航关系小节中有详细说明::
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");
// 为妳的程序中某个Activity 创建一个显式的意图(intent)
Intent resultIntent = new Intent(this, ResultActivity.class);
// 栈构建器(stack builder)对象中会包含一个关于被启动的Activity 的人造(artificial)回
// 退栈。
// 这能够确保,当用户从该Activity 中一路后退时,
// 会按照正常流程退出妳的程序,而回到首页(Home)屏幕。
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// 添加该Intent 的后退栈(而不是该Intent自身)
stackBuilder.addParentStack(ResultActivity.class);
// 把用来启动该Activity 的Intent添加到栈顶
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 妳可以日后使用mId来更新这个通知。
mNotificationManager.notify(mId, mBuilder.build());
完了。现在妳的用户就会看到通知了。
要想创建一个在被展开时显示大视图的通知的话,首先要使用普通视图下的那些选项来创建一个 NotificationCompat.Builder 对象。然后,调用 Builder.setStyle() ,参数设置为一个大视图风格对象。
记住,在安卓4.1之前的系统中,不支持可展开的通知的。欲知如何在安卓4.1及更早版本的系统中处理通知的话,就去阅读 处理兼容性 小节。
例如,以下代码片段,展开了如何修改之前的示例代码以使用收件箱风格的大视图:
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Event tracker")
.setContentText("Events received")
NotificationCompat.InboxStyle inboxStyle =
new NotificationCompat.InboxStyle();
String[] events = new String[6];
// 为收件箱风格的大视图设置一个标题
inboxStyle.setBigContentTitle("Event tracker details:");
...
// 将事件添加到大视图中去
for (int i=0; i < events.length; i++) {
inboxStyle.addLine(events[i]);
}
// 将大视图风格对象添加到通知对象中去。
mBuilder.setStyle(inBoxStyle);
...
// 在这里发出通知。
即使相关的方法存在于支持库的 NotificationCompat.Builder 类当中,对于某个特定版本的系统,也并不是所有的通知特性都被支持的。例如,动作按钮,是依赖于可展开的通知对象的,它们就只会在安卓4.1及更高版本的系统中出现,因为只有安卓4.1及更高版本的系统才支持可展开的通知对象。
为了确保得到最好的兼容性效果,就要使用 NotificationCompat 及它的子类来创建通知对象,尤其是使用 NotificationCompat.Builder 。另外,当妳实现一个通知功能时,按照以下过程来做:
1.无论用户使用的是哪个版本的系统,都要为所有用户提供该通知相关的所有功能。要实现这一点,就要检查以确认所有的功能都可以在妳的程序的某个 Activity 中提供。妳甚至可能需要添加一个新的 Activity 。
例如,如果妳想使用 addAction() 来加入一个能够停止及启动多媒体播放的控制按钮的话,首先就要在妳的程序的某个 Activity 中实现这个控制功能。
2.当用户点击通知对象时启动该 Activity ,确保所有用户都可以使用到这些功能。要实现这一点,就创建一个对应于该 Activity 的 PendingIntent 。Call setContentIntent() to add the PendingIntent to the notification.
3.然后,将妳想要加入的可展开的通知特性都添加到该通知中。记住,妳所加入的任何功能都必须在用户点击该通知时启动的 Activity 中有对应的实现。
如果妳需要为同一种类型的事件发出多次通知的话,妳应当避免使用全新的通知对象。正确的做法是,妳应当考虑更新之前的通知对象,要么是改变其中的某些值,要么是向其中加入一些值,或者二者皆有。
例如,Gmail在收到新邮件时,会增加未读消息的数量值,并且向通知对象中插入新邮件的摘要信息。这种做法被称为通知信息的“堆积”("stacking");在通知设计原则中有详细说明。
注意:Gmail的这种特性依赖“收件箱”这个大视图风格,它是可展开的通知特性中的一部分,在安卓4.1及之后版本的系统中有效。
以下小节说明的是如何更新通知以及如何删除它们。
要想发出一个可在日后更新的通知的话,就要在发出的时候提供一个通知编号,这样调用 NotificationManager.notify(ID, notification) 。当妳在日后想要更新这个通知时,可更新之前已有的或创建一个新的 NotificationCompat.Builder 对象,使用它来构建一个 Notification 对象,并且使用之前的通知编号来发出这个新的 Notification 。如果之前发出的通知还在那里,那么,系统会使用新的 Notification 对象中的内容来更新它。如果之前的通知已经被清除了,那么就会创建一个新的通知。
以下代码片段,展示的是一个被更新以便反映所发生的事件数目的通知。它会将通知内容堆积起来,并且显示一个摘要:
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 设置一个通知编号,以便日后更新
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// 启动一个循环,用于处理数据,然后通知用户
...
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
// 因为通知编号没变,所以已有的通知会被更新。
mNotificationManager.notify(
notifyID,
mNotifyBuilder.build());
...
这将产生下图所示的通知:
图 5. 通知抽屉中显示的一个已更新的通知。
在发生以下任一事件之前,通知都会保持可见状态:
•.(如果该通知可被清除的话)用户单独清除掉该通知或者使用“清除全部通知”功能来清除通知。
•.用户点击了该通知,而妳在创建该通知时也调用了 setAutoCancel() 。
•.妳针对某个特定的通知编号调用了 cancel() 。这个方法也会删除掉正在发生的通知。
•.妳调用了 cancelAll() ,这会删除掉妳之前发出的所有通知。
当妳从通知中启动一个 Activity 时,必须维持好用户预期的导航体验。点击后退键时应当从该程序的界面中退出到首页屏幕,点击最近按钮时应当让该 Activity 显示为一个单独的任务。为了维持好导航关系,妳应当在一个全新的任务中启动该 Activity 。如何通过 PendingIntent 的选项来启动一个全新的任务,这取决于妳将要启动的那个 Activity 的特性。有两种普遍的解决方法:
一般活动
妳即使启动的 Activity 是程序的正常工作流中的一个。在这种情况下,设置该 PendingIntent 以启动一个全新的任务,并且给该 PendingIntent 提供一个后退栈以重现该程序的正常后退行为。
Gmail 程序中的通知就狠好地演示了这种处理方法。当妳点击针对某封邮件的通知时,妳会看到该邮件本身。一路点击后退会按照正常的流程退出Gmail,回到首页屏幕,就好像妳是直接从首页屏幕进入的Gmail,而不是从通知中进入的。
这种行为与妳在点击通知之前处于哪个程序中无关。例如,如果妳当时正在Gmail 中撰写一封新邮件,这个时候妳点击了通知来阅读别人发来的某封邮件,此时妳会直接进入该新邮件的阅读界面。当妳再点击后退时,会“返回”到收件箱,再次后退则会直接退出到首页屏幕,而不会“后退”到之前的撰写新邮件的界面。
特殊活动
只有当从通知中启动时,用户才会看到这个 Activity 。这种情况下,该 Activity 相当于该通知的延伸,显示出了在通知中难以显示的信息。对于这种情况,设置该 PendingIntent 以启动一个全新任务。无需再创建后退栈了,因为,新启动的这个 Activity 并不是程序的活动流中的一部分。此时点击后退按钮仍然会将用户带回到首页屏幕。
要建立一个直接启动某个 Activity 的 PendingIntent 的话,按照以下步骤来:
1.在清单(manifest)中定义好妳的程序的 Activity 层次关系。
1.添加对于安卓4.0.3及更早版本系统的支持。要实现这一点,就要在 <activity> 中添加一个 <meta-data> 元素,以为那个将被启动的 Activity 指定一个亲代活动对象。
对于这个元素,设置 android:name ="android.support.PARENT_ACTIVITY"。设置 android:value ="<parent_activity_name>",其中,<parent_activity_name> 就是其亲代 <activity> 元素的 android:name 值。参考以下XML示例。
2.还要加入对安卓4.1及更高版本的支持。要实现这一点,就给妳将要启动的 Activity 对应的 <activity> 元素添加一个 android:parentActivityName 属性。
最终产生这样的XML:
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ResultActivity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>
2.基于用来启动该 Activity 的 Intent ,创建一个后退栈:
2.通过调用 TaskStackBuilder.create() 来创建一个栈构建器。
3.通过调用 addParentStack() 来将后退栈添加到栈构建器。对于妳在清单中定义的层次结构中的每个 Activity ,在该后退栈中都会包含一个用于启动该 Activity 的 Intent 对象。这个方法也会添加那些会以一个全新任务的方式来启动该栈的标志位。
注意:尽管 addParentStack() 的参数是被启动的 Activity 的一个引用,但是,这个方法并不会将那个用于启动该 Activity 的 Intent 加入进去。那个动作是在下一步进行的。
4.通过调用 addNextIntent() ,将那个用于启动该 Activity 的 Intent 添加到通知对象中。将妳在第一步中创建的 Intent 作为 addNextIntent() 的参数。
5.如果妳需要的话,可调用 TaskStackBuilder.editIntentAt() 来将参数传递给栈中的 Intent 对象。这个在某些时候是有必要的,可用来确保,当用户使用后退按钮切换到该 Activity 时,它能够显示出有意义的数据。
6.调用 getPendingIntent() ,以获取对应于这个后退栈的 PendingIntent 。然后,妳可以将这个 PendingIntent 作为 setContentIntent() 的参数。
以下代码片段展示了这个过程:
...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// 添加后退栈
stackBuilder.addParentStack(ResultActivity.class);
// 将Intent添加到栈的顶部
stackBuilder.addNextIntent(resultIntent);
// 获取一个包含着整个后退栈的PendingIntent
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
以下小节说明了如何创建一个对应于特殊活动的 PendingIntent 。
特殊的 Activity 不需要后退栈,所以,妳不需要在清单文件中定义它的 Activity 层次关系,也不需要调用 addParentStack() 来构建一个后退栈。仅仅需要做的事情就是,在清单文件中定义好该 Activity 的任务选项,以及调用 getActivity() 来创建对应的 PendingIntent :
1.在清单文件中,给将要被启动的 Activity 的 <activity> 元素添加以下属性
android:name =" activityclass "
这个活动的完整类名。
与妳在代码中设置的 FLAG_ACTIVITY_NEW_TASK 组合之后,就能够确保这个 Activity 不会被合并到程序的默认任务中去。任何与该程序保持默认关系的已有任务都不受影响。
android:excludeFromRecents ="true"
将这个新任务从最近应用中排队,这样,用户就不会偶然误操作切换回到这个任务了。
以下代码片段展示了对应的元素:
<activity
android:name=".ResultActivity"
...
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>
...
2.构建并且发出通知:
2.设置该 Activity ,让它启动一个新的空白任务。具体做法就是调用 setFlags() ,并且将标志位设置为 FLAG_ACTIVITY_NEW_TASK 和 FLAG_ACTIVITY_CLEAR_TASK 。
3.对该 Intent 设置任何其它妳想设置的选项。
4.调用 getActivity() ,以利用该 Intent 创建一个 PendingIntent 。然后,妳可以将这个 PendingIntent 用作 setContentIntent() 的参数。
以下代码片段演示了这个过程:
// 实例化一个Builder对象。
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// 为该Activity创建一个Intent
Intent notifyIntent =
new Intent(new ComponentName(this, ResultActivity.class));
// 设置该Activity,使得它在一个全新的空白任务中启动
notifyIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
// 创建对应的PendingIntent
PendingIntent notifyIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent
PendingIntent.FLAG_UPDATE_CURRENT
);
// 将该PendingIntent加入到通知构建器中
builder.setContentIntent(notifyIntent);
// 将通知发送到NotificationManager 系统服务,就可以发出通知了。
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 使用构建器来构建一个匿名的Notification对象,然后将它发送给
// NotificationManager
mNotificationManager.notify(id, builder.build());
通知中可以包含一个动态的进度指示器,以向用户显示一个进行中的操作的进度。如果妳可以估计这个操作所需的时间,并且在任何时候估计出完成程度,那么,就使用指示器的“确定”形式(一个进度条)。如果妳无法估计这个操作所需的时间,那么,使用指示器的“非确定”形式(一个活动指示器)。
进度指示器是利用当前平台的 ProgressBar 类来显示的。
要在安卓4.0及更高版本的系统中使用进度指示器的话,就调用 setProgress() 。对于之前版本的系统,妳必须创建妳自己的自定义通知布局,其中带上一个 ProgressBar 视图。
以下小节说明的是如何使用 setProgress() 来在通知中显示一个进度。
要想显示一个确定状态的进度条的话,就通过调用 setProgress(max, progress, false) ( ☯:原文是 setProgress() setProgress(max, progress, false) )来将这个进度条添加到通知中,然后发出该通知。当妳的操作正在进行时,增加progress 的值,然后更新该通知。在操作的最后时刻,progress应当等于max。一个常见的调用 setProgress() 的方式就是,将max设置为100,然后将progress按照操作的完成度的百分比来增大。
当操作完成时,妳可以让进度条保持显示状态,也可以删除它。无论是哪种情况,都不要忘记更新通知中的文字内容,以告知该操作已经完成。要删除进度条,就调用 setProgress(0, 0, false) ( ☯:原文是 setProgress() setProgress(0, 0, false) )。例如:
...
mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
.setContentText("Download in progress")
.setSmallIcon(R.drawable.ic_notification);
// 在一个后台线程中启动一个耗时较长的操作
new Thread(
new Runnable() {
@Override
public void run() {
int incr;
// 做20次“耗时”操作
for (incr = 0; incr <= 100; incr+=5) {
// 设置进度指示器的最大值,当前的完成值,以及“确定”状态
mBuilder.setProgress(100, incr, false);
// 第一次显示进度条。
mNotifyManager.notify(0, mBuilder.build());
// 线程睡眠,模仿一个耗时操作
try {
// 睡眠5秒
Thread.sleep(5*1000);
} catch (InterruptedException e) {
Log.d(TAG, "sleep failure");
}
}
// 当循环完毕之后,更新通知
mBuilder.setContentText("Download complete")
// 删除进度条
.setProgress(0,0,false);
mNotifyManager.notify(ID, mBuilder.build());
}
}
// 通过调用它的Runnable的run()方法来启动该线程
).start();
所产生的通知见图6所示。左边是操作过程中的通知的截图;右边是操作完成之后的通知的截图。
图 6. 操作进行中及操作完成后的进度条。
要显示一个非确定状态的活动指示器的话,就使用 setProgress(0, 0, true) 来将它添加到妳的通知对象中(前两个参数会被忽略),然后发出这个通知。所产生的结果就是,出现一个与进度条相同风格的指示器,不过其动画是持续运行的。
在操作开始时就发出这个通知。在妳修改妳的通知之前,动画都会保持运行状态。当操作完成之后,调用 setProgress(0, 0, false) ( ☯:原文是 setProgress() setProgress(0, 0, false) ),然后更新该通知,以删除活动指示器。记得要做这件事;否则,即使妳的操作完成了,动画也会继续运行。另外要记得修改通知内容文字,以告知该操作已经完成。
要想学习如何使用活动指示器的话,参考之前的代码片段。找到以下几行:
// 设置进度指示器的最大值,当前的完成值,以及“确定”状态
mBuilder.setProgress(100, incr, false);
// 发出通知
mNotifyManager.notify(0, mBuilder.build());
使用以下代码来替换它们:
// 设置一个活动指示器,表示一个不确定时间长度的操作
mBuilder.setProgress(0, 0, true);
// 发出通知
mNotifyManager.notify(0, mBuilder.build());
所产生的指示器如图7所示:
图 7. 一个进行中的活动指示器。
通知框架允许妳设置一个自定义的通知布局,其中会使用一个 RemoteViews 对象来定义通知的外观。自定义布局的通知与普通的通知是类似的,不过它们是基于一个XML 布局文件中定义的 RemoteViews 。
自定义通知布局的可用高度取决于通知视图。普通视图的布局不能超过64 dp,展开状态的视图布局不能超过256 dp。
要定义一个自定义通知布局的话,首先实例化一个从XML 布局文件中渲染出界面的 RemoteViews 对象。然后,不要调用 setContentTitle() 这些方法,而是调用 setContent() 。要想设置自定义通知中的详细内容的话,直接使用 RemoteViews 的方法来设置该视图的子代对象的值就可以了:
1.创建一个单独的XML 布局文件,用于显示该通知对象。妳可以任意起文件名,但后缀名必须是.xml
2.在程序中,使用 RemoteViews 的方法来定义通知对象的图标和文字。通过调用 setContent() 来将该 RemoteViews 对象添加到 NotificationCompat.Builder 中。不要向妳的 RemoteViews 对象设置一个背景 Drawable ,因为这可能导致妳的文字颜色都看不清。
RemoteViews 类也包含了一些有用的方法,可用于轻易地添加一个 Chronometer 或 ProgressBar 到通知布局中。欲知更多关于创建自定义通知布局的信息,就去读 RemoteViews 的参考文档。
注意:当妳使用自定义通知布局时,要特别注意确保妳的自定义布局在不同的设备方向及分辨率下都正常显示。当然,这个建议对于所有的View 布局都成立,但是对于通知对象是尤其重要的,因为通知抽屉中的空间是严格受限的。不要把妳的自定义布局搞得太复杂了,并且要确保在不同的配置情况下都做一些测试。
对于自定义通知,一定要使用样式资源来设置文字内容的外观。不同设备和系统版本中的通知区域背景色是千差万别的,使用样式资源可以助妳通吃这些设备。从安卓2.3开始,系统定义了一个样式,用于标准的通知布局文字。如果,妳的程序以安卓2.3及更高版本系统为运行目标,并且使用了相同的样式风格,则,妳可以确保通知中的文字对于背景色是可见的。
未知美人
HxLauncher: Launch Android applications by voice commands