Android N 带来的新通知栏- Roger的博客
文章推薦指數: 80 %
如果我们使用setCustomBigContentView() 方法而没有用setCustomContentView() 方法设置折叠状态的layout,这时我们的notification 将会简单的折叠成一个只 ...
Togglenavigation
Roger'sBlog
Home
AboutMe
Tags
AndroidN带来的新通知栏
原文链接:AndroidN:IntroducingupgradedNotifications
原文作者:JoeBirch
译者:rogero0o
AndroidN带来的新通知栏
在介绍过AndroidN新功能图中图后,我决定深入研究另一个预览版中发布的新功能-notifications。
AndroidN增加了许多新的notificationsAPI,让我们来看看增加了什么新功能,并且如何在我们的app中实现新功能。
为了能方便的查看所有的新功能,我创建了一个APP-Notifi,一个简单的Androidproject用来展示所有的例子。
在AndroidN中,notifications鸟枪换炮啦!现在在我们应用中对通知栏的展现,以及动画的控制都增强了许多,更被赋予了许多新的功能,在和notifications打交道时,用户体验将得到极大的提高。
所以到底葫芦里卖的什么药呢?主要有以下几点:
新的系统notifications的Layout模板,更加简单和简洁,使得notifications不再如此凌乱
Bundling(绑定)意味着现在notifications不会再充斥着用户的状态栏了,相关的notifications现在可以在设计在一个可扩展的notificationgroup中展示
使用新的内联回复动作使得用户可以直接在notifications中回复文本,不再需要打开别的app或者切换当前页面
新的自定义views使我们的notifications样式更加丰富多彩,更加让人喜欢
这些看起来都很腻害对不对?所以让我们继续深入并且看看具体实现方法。
Notification模板
AndroidN介绍了一些在显示notification时使用的新的模板。
这些新的模板重新排版了之前SDK版本的模板,使他们看起来更加的简洁清爽。
这些新的模板将自动的被系统适配使用,所以我们不需要改变代码来创建一个notification。
之前我们创建一个notification可能像是这样的:
NotificationCompat.Builderbuilder=newNotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
.setContentTitle(title)
.setContentText(message)
.setLargeIcon(largeIcon)
.setAutoCancel(true);
之前的版本,使用上述代码显示的notification效果将如下图:
现在在AndroidN上,新的模板(使用的代码并未改变)现在将展示成这样:
这个新的notification样式模板看起来并不是那么简洁,但是我觉得这带来了更多的视觉方面的焦点并且减少了notification内容展示空间中令人分心的部分。
并且,你完全不需要更改你的代码-系统将自动默认的显示新的样式。
注释:请记得你可以使用一些样式来设置你的notification并且通过在创建时调用setColor()来设置notification的颜色值。
NotificationCompat.Builderbuilder=newNotificationCompat.Builder(context)
//Otherproperties
.setColor(ContextCompat.getColor(context,R.color.primary));
使用上述代码将设置notification图标和标题的颜色,和添加到notification中的任何动作都是一样的。
绑定notification
在AndroidN中,我们可以绑定notification了,这是一组相关的notification,我们可以在一个单独的notification头部下显示多个notification。
当你发送多个相关的notification时,你应该确认他们在一个组中来避免这些notification塞满了用户的状态栏。
这会使用户感到非常的不友好,所以管理任何有关系的notification能明显的提升用户的体验。
所以为了实现绑定notification的功能我们首先需要设置一个我们的notification来当做‘小组概要’的notification,这个小组概要的notification将不会出现在notification的堆栈中,但在点击前将是唯一显示在设备上的notification,点击展开后,将作为我们的notification栈头的唯一通知。
组中的notification是这个notification栈的主要内容。
注意:你必须设置一个notification作为‘小组标题’,不然你的notification将不会以组的形式展现。
接下来,我们可以在创建notification实例时使用setGroup()来设置一个string类型的组ID用来组织我们的notification,像这样:
NotificationCompat.BuilderbuilderOne=newNotificationCompat.Builder(context)
//Otherproperties
.setGroupSummary(true)
.setGroup(KEY_NOTIFICATION_GROUP);
NotificationCompat.BuilderbuilderTwo=newNotificationCompat.Builder(context)
//Otherproperties
.setGroupSummary(true)
.setGroup(KEY_NOTIFICATION_GROUP);
NotificationCompat.BuilderbuilderThree=newNotificationCompat.Builder(context)
//Otherproperties
.setGroupSummary(true)
.setGroup(KEY_NOTIFICATION_GROUP);
这将通知notificationmanager这些notification都是属于同一个组的,这样系统将会把这些notification为我们绑定到一起-就是这么简单!这是一个重新定义我们展示notification的绝妙的方法,现在我们能将他们组织到一个notification之下使他们能在同一时间被用户看到,产生的效果如下图所示:
BundledNotifications的动作
如果这都不能满足你,就像标准的notification一样我们可以对notification使用动作,这也是绑定功能的一部分。
首先,这些将会被折叠成notification的一部分并且不被用户所见-然而用户可以点击在描述notification上的箭头来揭示这些动作,就像下图所示:
这些动作将会以标准方法相同的处理方式作用在notification上,所以不需要任何额外的工作。
所有我们需要做的都只是创建一个新的动作实例并且将它指向我们的notification,像下面这样:
PendingIntentarchiveIntent=PendingIntent.getActivity(...);
NotificationCompat.ActionreplyAction=...;
NotificationCompat.ActionarchiveAction=...;
NotificationCompat.Builderbuilder=newNotificationCompat.Builder(context)
//Otherproperties
.setGroup(KEY_NOTIFICATION_GROUP)
.addAction(replyAction)
.addAction(archiveAction);
直接回复
使用RemoteInputAPI(远程输入API)(从APIlevel4开始就支持了)我们就可以展示能让用户直接回复的notification,不需要让用户进入app来回复。
这是通过显示一个内联回复动作来实现的,本质上来说就是显示一个添加按钮在notification上来允许用户输入直接输入回复文本。
这使得用户与我们的APP相处的更加融洽,不需要经常打开应用,让用户更好的专注在正在处理的事情上。
当用户使用notification内置回复动作时,文本将会被由我们动作指定的intent发送到我们的app中(可能是activity,service等等),在那我们获得用户输入的文本并进行下一步处理。
添加inlineactions(内联回复行为)
现在我们已经学习了关于新的内联回复行为,但是我们该如何实现呢?为了将内联回复加到notificaiton,第一步我们需要创建一个新的RemoteInput实例:
RemoteInputremoteInput=newRemoteInput.Builder(KEY_TEXT_REPLY)
.setLabel(LABEL_REPLY)
.build();
在创建RemoteIput实例时需要设置一个认证身份的KEY(在上面代码中为KEY_TEXT_REPLY),在后面我们需要在我们的应用中使用这个KEY来取回用户在notification中输入的文本。
完成之后,我们就能简单的设置用于快速回复动作的提示语(也可以是空的)。
快速回复的提交按钮已经被系统自动的显示在notificaiton中。
接下来,我们需要创建PendingIntent实例用来发送用户提交的数据。
这些用于notification的PendingIntent与之前并没有太大的区别:
PendingIntentreplyIntent=PendingIntent.getActivity(context,
REPLY_INTENT_ID,
getDirectReplyIntent(context,LABEL_REPLY),
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntentarchiveIntent=PendingIntent.getActivity(context,
ARCHIVE_INTENT_ID,
getDirectReplyIntent(context,LABEL_ARCHIVE),
PendingIntent.FLAG_UPDATE_CURRENT);
privatestaticIntentgetDirectReplyIntent(Contextcontext,Stringlabel){
returnMessageActivity.getStartIntent(context)
.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
.setAction(REPLY_ACTION)
.putExtra(CONVERSATION_LABEL,label);
}
现在我们创建了这些PendingIntents,自然要让他们用起来!这里是remoteInput实例使用的地方。
我们需要开始创建回复动作,让我们来看看以下的replayAction实例:
NotificationCompat.ActionreplyAction=
newNotificationCompat.Action.Builder(R.drawable.ic_reply,
LABEL_REPLY,replyIntent)
.addRemoteInput(remoteInput)
.build();
NotificationCompat.ActionarchiveAction=
newNotificationCompat.Action.Builder(R.drawable.ic_archive,
LABEL_ARCHIVE,archiveIntent)
.build();
这里我们创建一个普通的活动然后调用addRemoteInput()方法来把这个remoteInput实例添加到这个活动中。
这里描述了当这个活动被触发时,我们希望给用户展示内联回复动作在notification 中。
当用户点击提交了快速回复的提交按钮时,输入的内容将会包含在我们的 replyIntent中。
在这之后,我们可以简单的添加动作到NotificationBuilder像下面这样(这里再次像之前的版本一样),我们不需要为内联回复动作添加任何新的代码来实现他。
NotificationCompat.Builderbuilder=newNotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
.setContentTitle(title)
.setContentText(message)
.setLargeIcon(largeIcon)
.addAction(replyAction);
.addAction(archiveAction);
.setAutoCancel(true);
一旦我们实现了以上的代码,那么实现的效果将会像如下展示:
从内联动作中获取数据
我们实现了内联回复动作并且这看起来很棒,但是为了让它变得有效我们需要获取到用户提交的数据。
下面是个简单的例子:
Bundlebundle=RemoteInput.getResultsFromIntent(intent);
if(remoteInput!=null){
returnbundle.getCharSequence(NotificationUtil.KEY_TEXT_REPLY);
}
在这里我们使用了RemoteInputAPI来重新得到intent中的输入数据。
此时,如果返回结果存在,我们就能将数据从bundle中取得。
我们通过使用之前用来存储数据的key来获取数据,在例子中就是之前提到的KEY_TEXT_REPLY。
内联回复样式
我们同样能设置内联回复动作的颜色,方法是在创建时使用setColor()方法来实现。
这看起来是不是很不错?
同时你也可以看到这设置了notification的所有组件。
我们可以通过以下代码实现:
NotificationCompat.Builderbuilder=newNotificationCompat.Builder(context)
//Otherproperties
.setColor(ContextCompat.getColor(context,R.color.primary));
浮动通知
浮动通知动作正如在Marshmallow(棉花糖)版本中一样,然而现在他们在AndroidN中使用了升级后的模板。
这赋予了我们一个新的notification,如下所示:
AndroidN中的浮动通知很棒的功能是我们可以自定义Layouts来装饰我们的notification,下一章中我们将详细解析。
自定义视图的notification
在android之前的版本中,我们仍然可以使用自定义布局来显示我们的notification.这意味着我们可以使用我们自己的布局资源来装饰notification的样子。
这样的好处有:
显示之前不被NotificationsAPI支持的组件
在你的notification中显示更有意义、更方便查看的信息,给用户提供更有意义的信息而不需要打开应用
在你的notification中添加商标来让notification和你的应用统一外观
综上所述,你需要确认保持你的notification设计是最简洁的。
我们不想要用过多的信息来淹没用户,特别是在这样小的一个空间。
允许用户从你的notification中获取到他想要的,同时仍然保持细节和设计上的简洁。
所以,请牢记保持简洁,接下来我们就能创建一个自定义的layout了!其实这相当的简单,我们可以通过使用RemoteViews类来创建我们的自定义notification.
RemoteViewsremoteViews=newRemoteViews(context.getPackageName(),R.layout.notif_custom_view);
remoteViews.setImageViewResource(R.id.image_icon,iconResource);
remoteViews.setTextViewText(R.id.text_title,title);
remoteViews.setTextViewText(R.id.text_message,message);
remoteViews.setImageViewResource(R.id.image_end,imageResource);
第一步,创建一个RemoteView的实例,传入我们的应用包名(系统处理notifications时需要用到),再传入我们需要应用到notification中的layout。
接下来我们可以使用由RemoteView类提供的方法来设置layout中的view需要使用到的数据/资源。
在RemoteView类中,我使用了以下方法:
setImageViewResource(viewId,resource)-image的resource和我们需要展示图片的view的ID
setTextViewText(viewId,text)-我们需要展示的文本和需要展示文本的view的ID
这个类允许我们设置给view的数据类型有datavalues,resources,listeners等等。
如果想要查看完成的说明,请查阅文档。
我们现在创建了一个RemoteView的实例,我们需要使用一个notification来展示我们想到达到的效果。
折叠视图
在上一章中我们将RemoteView实例中的layout和它的视图中使用的数据申明在一起,所以当我们创建notification时我们需要做的只是传递RemoteView实例到builder的setCustomContentView()这个方法中。
在下面这个例子中,我们提供了折叠(正常)状态的notification的自定义视图:
Notification.Builderbuilder=newNotification.Builder(context)
.setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
.setCustomContentView(remoteViews)
.setStyle(newNotification.DecoratedCustomViewStyle());
.setAutoCancel(true);
为折叠状态的notification设置一个自定义视图将会单独展现一个折叠了的noti1.我们还没设置展开的状态,所以notification将不会展开,效果如下图所示:
展开视图
如上所述,我们同样可以提供一个自定义视图给展开状态的notification,只需要传递一个RemoteViews实例到setCustomBigContentView()方法中:
Notification.Builderbuilder=newNotification.Builder(context)
.setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
.setCustomBigContentView(bigRemoteView)
.setStyle(newNotification.DecoratedCustomViewStyle());
.setAutoCancel(true);
如果我们使用setCustomBigContentView()方法而没有用setCustomContentView()方法设置折叠状态的layout,这时我们的notification将会简单的折叠成一个只显示应用名称的状态,如下图所示:
所谓最佳实践,如果你提供了展开大小的notification视图那么你应该也提供一个折叠状态的视图。
这是因为没有折叠状态的视图将与用户没有任何的交互,这是与notification的设计初衷相违背的!如果你只用到展开或是折叠中的其中一个状态,那么你应该只使用折叠状态。
使用能折叠和展开的视图
如果我们希望我们的notification又能折叠和展开,那么我们在创建RemoteView实例时就应该调用setCustomContentView()和setCustomBigContentView()这两个方法。
Notification.Builderbuilder=newNotification.Builder(context)
.setSmallIcon(R.drawable.ic_phonelink_ring_primary_24dp)
.setCustomContentView(remoteView)
.setCustomBigContentView(bigRemoteView)
.setStyle(newNotification.DecoratedCustomViewStyle());
.setAutoCancel(true);
现在我们设置了一个既能折叠又能展开的notification,用户能展开notification来查阅更加丰富的信息。
自定义悬浮视图
我们同样能在悬浮notification中使用自定义视图。
使用上一章中同样的方法来创建一个notification,我们可以简单的调用setCustomContentView()方法来设置RemoteVews的自定义视图。
最后
我们简单的查阅了一个新的notifications在AndroidN中并且学习了怎么实现它,那么现在就把这些应用到你的旧的或是新的应用中去吧!我想这些新功能对于安卓平台来说也是棒棒的,这些notifications的新功能不仅强大,而且我还期待在应用中更加强大的notification展示。
如果你有任何问题,请联系作者的tweet或是直接到原文留言:)。
p.s别忘了到原文中点击推荐按钮哦!
←PreviousPost
NextPost→
FEATUREDTAGS
Life
AndroidFramework
AndroidUI
读书笔记
翻译
OpenGLES
FRIENDS
daimajia
Drakeet
Trinea
stormzhang
延伸文章資訊
- 1android.support.v4.app.NotificationCompat$Builder - Java
setCustomContentView(notRemoteView) .setCustomBigContentView(bigNotRemoteView);
- 2Create custom big notification inflate - android - Stack Overflow
setCustomBigContentView(remoteViews) doesn't working? And why I cant use my custom TextView ? thi...
- 3问答- 腾讯云开发者社区-腾讯云
请注意,NotificationCompat.Builder.setCustomBigContentView的文档说明:. 提供自定义RemoteViews以代替扩展表单中的平台模板。这将覆盖原...
- 4创建自定义通知布局| Android 开发者
您还可以选择调用 setCustomBigContentView() 为展开后通知设置不同的布局。 注意:如果要为媒体播放控件创建自定义通知,请采纳同样的建议,但改用 ...
- 5RemoteViews在项目中遇到的问题 - 简书
setCustomBigContentView(remoteViews);// 默认高度256 超出则显示不全. 其中RemoteViews的布局最外层是这样,当我设置layout_height...