4、通知样式与布局:标准样式、BigTextStyle、BigPictureStyle、InboxStyle、MessagingStyle、自定义布局
通知的样式,说白了就是通知长什么样。Android 系统给我们提供了几种现成的模板,也允许我们自己画。我刚开始接触通知时,觉得这玩意儿不就是弹个框吗?后来才发现,不同场景用对样式,用户体验能差出好几个档次。
今天咱们就把这几种样式挨个捋一遍。我会结合我踩过的坑,告诉你什么时候该用哪种。
4.1 标准样式(默认样式)
标准样式就是最普通的通知。你什么都不设置,系统就用这个。它包含图标、标题、内容文字、时间戳。嗯,够用,但不够出彩。
我个人的习惯是:如果只是简单提示用户“下载完成”、“同步成功”,用标准样式就够了。别为了炫技而用复杂样式,没必要。
- 单行文本,超出部分省略号
- 最多显示两行(展开后)
- 适合简短消息
// 标准样式示例
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle("下载完成")
.setContentText("文件已保存到本地")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
4.2 BigTextStyle(大文本样式)
BigTextStyle 就是用来展示长文本的。你想想看,如果一条消息有 200 个字,用标准样式只能看到前两行,用户得多难受。
我在项目中遇到过这样一个场景:用户收到一条系统公告,内容很长。如果用标准样式,用户必须点进应用才能看全文。用了 BigTextStyle 后,用户直接在通知栏就能展开阅读,点击率反而下降了——因为用户不需要点进去就能获取信息。这其实是个好现象,说明用户体验提升了。
// BigTextStyle 示例
NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle()
.bigText("这是一段很长的文本内容,用户可以在通知栏直接展开查看完整信息。不用进入应用就能获取全部内容,大大提升了阅读效率。")
.setBigContentTitle("系统公告")
.setSummaryText("点击查看详情");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setStyle(bigTextStyle)
.setContentTitle("系统公告")
.setContentText("这是一段很长的文本内容...");
setContentTitle 和 setContentText。因为通知在折叠状态下会显示这两个字段,展开后才显示 bigText 的内容。
4.3 BigPictureStyle(大图样式)
BigPictureStyle 就是通知里带一张大图。适合展示图片预览、商品图片、活动海报等场景。
我曾经犯过一个错误:直接把网络图片的 URL 传进去。结果通知一直显示空白。后来才意识到,BigPictureStyle 需要的是 Bitmap 对象,你得先把图片下载下来。
// BigPictureStyle 示例
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.big_image);
NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle()
.bigPicture(bitmap)
.setBigContentTitle("新商品上架")
.setSummaryText("点击查看详情");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setStyle(bigPictureStyle)
.setContentTitle("新商品上架")
.setContentText("限时优惠,点击查看");
4.4 InboxStyle(收件箱样式)
InboxStyle 适合展示多条消息的摘要。比如邮件列表、聊天记录、通知汇总。它会把多条内容逐行显示,每条一行。
我记得有一次做邮件客户端,用户反馈说“通知栏只能看到最新一封邮件,之前的都看不到”。后来改用 InboxStyle,用户可以在通知栏看到最近 5 封邮件的标题,体验好多了。
// InboxStyle 示例
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle()
.setBigContentTitle("5 封未读邮件")
.setSummaryText("点击查看全部")
.addLine("张三:项目进度报告")
.addLine("李四:会议纪要")
.addLine("王五:请假申请")
.addLine("赵六:报销审批")
.addLine("系统通知:密码即将过期");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setStyle(inboxStyle)
.setContentTitle("5 封未读邮件")
.setContentText("张三:项目进度报告");
4.5 MessagingStyle(消息样式)
MessagingStyle 是 Android 7.0 引入的,专门为聊天应用设计。它支持显示多条消息、发送者头像、消息时间戳,还能直接回复。
这个样式我特别喜欢。它让通知栏看起来就像一个迷你聊天窗口。用户甚至不用打开应用就能回复消息。
// MessagingStyle 示例
Person me = new Person.Builder()
.setName("我")
.setIcon(Icon.createWithResource(context, R.drawable.avatar_me))
.build();
Person friend = new Person.Builder()
.setName("小明")
.setIcon(Icon.createWithResource(context, R.drawable.avatar_friend))
.build();
NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle(me)
.setConversationTitle("群聊:项目组")
.addMessage("方案看完了吗?", System.currentTimeMillis() - 60000, friend)
.addMessage("看完了,有几个地方需要修改", System.currentTimeMillis() - 30000, me)
.addMessage("好的,下午开会讨论", System.currentTimeMillis(), friend);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setStyle(messagingStyle)
.setContentTitle("小明")
.setContentText("好的,下午开会讨论");
RemoteInput,并设置一个 PendingIntent 来处理回复。这个功能在 Android 7.0 以上系统上体验非常好。
4.6 自定义布局(RemoteViews)
如果系统提供的样式都不满足你的需求,那就自己画。使用 RemoteViews 可以完全自定义通知的布局。
我在项目中用过一次自定义布局:做一个音乐播放器的通知,需要显示专辑封面、歌名、进度条、播放/暂停按钮。系统样式根本做不到,只能用 RemoteViews。
// 自定义布局示例
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_custom);
// 设置文本
remoteViews.setTextViewText(R.id.notification_title, "歌曲名称");
remoteViews.setTextViewText(R.id.notification_artist, "歌手名");
// 设置点击事件
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notification_play_button, pendingIntent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setCustomContentView(remoteViews)
.setCustomBigContentView(remoteViews); // 展开后的布局
- RemoteViews 支持的控件有限,不支持自定义 View
- 布局文件不能有复杂的嵌套,否则渲染会卡顿
- 不同 Android 版本对 RemoteViews 的支持程度不同,建议做兼容测试
4.7 知识体系总览
下面这张图总结了通知样式的选择逻辑。你可以根据消息类型快速决定用哪种样式。
4.8 样式对比总结
| 样式 | 适用场景 | 展开后效果 | 我的建议 |
|---|---|---|---|
| 标准样式 | 简短提示、状态更新 | 最多两行文本 | 能用就用,简单高效 |
| BigTextStyle | 长文本公告、文章摘要 | 显示全部文本 | 文本超过 80 字就用它 |
| BigPictureStyle | 图片预览、商品展示 | 显示大图 | 注意图片大小和加载方式 |
| InboxStyle | 多条消息汇总 | 逐行显示多条内容 | 控制在 5 行以内 |
| MessagingStyle | 聊天、即时通讯 | 显示聊天记录 | 支持直接回复,体验极佳 |
| 自定义布局 | 特殊 UI 需求 | 完全自定义 | 最后的选择,兼容性要测好 |
好了,通知样式这块就讲到这里。每种样式都有它的用武之地,选对了,用户觉得舒服;选错了,用户可能直接划掉你的通知。嗯,多想想用户的使用场景,比什么都重要。