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("这是一段很长的文本内容...");
小技巧: 使用 BigTextStyle 时,记得同时设置 setContentTitlesetContentText。因为通知在折叠状态下会显示这两个字段,展开后才显示 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("限时优惠,点击查看");
注意: 大图不要太大。我建议压缩到 2MB 以内,否则通知栏渲染会卡顿。另外,别忘了在子线程中加载图片,别在主线程搞网络请求。

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("张三:项目进度报告");
最佳实践: InboxStyle 最多显示 5-7 行。超过这个数量,用户反而觉得信息过载。我一般控制在 5 行以内,再加一个“查看全部”的入口。

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("好的,下午开会讨论");
提示: MessagingStyle 支持直接回复功能。你需要添加一个 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 知识体系总览

下面这张图总结了通知样式的选择逻辑。你可以根据消息类型快速决定用哪种样式。

通知样式选择流程图 收到通知消息 消息类型? 短文本 长文本 图片/多媒体 标准样式 简单提示、状态更新 BigTextStyle 公告、长消息 具体场景? 多条消息 聊天 自定义 InboxStyle 邮件列表、通知汇总 MessagingStyle 聊天应用、即时通讯 自定义布局 音乐播放器、特殊UI

4.8 样式对比总结

样式 适用场景 展开后效果 我的建议
标准样式 简短提示、状态更新 最多两行文本 能用就用,简单高效
BigTextStyle 长文本公告、文章摘要 显示全部文本 文本超过 80 字就用它
BigPictureStyle 图片预览、商品展示 显示大图 注意图片大小和加载方式
InboxStyle 多条消息汇总 逐行显示多条内容 控制在 5 行以内
MessagingStyle 聊天、即时通讯 显示聊天记录 支持直接回复,体验极佳
自定义布局 特殊 UI 需求 完全自定义 最后的选择,兼容性要测好

好了,通知样式这块就讲到这里。每种样式都有它的用武之地,选对了,用户觉得舒服;选错了,用户可能直接划掉你的通知。嗯,多想想用户的使用场景,比什么都重要。

公众号:蓝海资料掘金营,微信deep3321