返回介绍

构造通知

发布于 2024-12-23 22:17:23 字数 4060 浏览 0 评论 0 收藏 0

在我们使用 NotificationCompat.Builder 对象设置完各种参数(小/大图标,标题,内容等)后,最后会调用 build 方法来得到一个 Notification,然后使用 NotificationManager 来发出通知。我们就先来看看 build 方法做了什么事。

NotificationCompat 是 v4 包中的一个类,做了 android 各个版本的兼容,但是不论是哪个版本,最后 build 方法都是调用的 Notification 的 build 方法,所以我们直接看 Notification 的 build 方法。

frameworks/base/core/java/android/app/Notification.java

/**
 * Combine all of the options that have been set and return a new {@link Notification}
 * object.
 */
public Notification build() {
  ... 
  //设置通知的默认信息
  Notification n = buildUnstyled();

   //设置通知的样式信息
  if (mStyle != null) {
    n = mStyle.buildStyled(n);
  }
  ...
  return n;
}

方法的注释说得很清楚了,就是将所有的设置选项联合在一起返回一个新的通知。

buildUnstyled

其中 buildUnstyled() 所说的默认信息就是在 android4.0 以前还不能展开的时候所包括的所有信息,包括大/小图标,时间,标题,内容,自定义 view 等信息。

/**
 * Apply the unstyled operations and return a new {@link Notification} object.
 * @hide
 */
public Notification buildUnstyled() {
  Notification n = new Notification();
  n.when = mWhen;
  n.icon = mSmallIcon;
  ...
  setBuilderContentView(n, makeContentView());
  n.contentIntent = mContentIntent;
  ...
  setBuilderBigContentView(n, makeBigContentView());
  setBuilderHeadsUpContentView(n, makeHeadsUpContentView());
  // Note: If you're adding new fields, also update restoreFromNotitification().
  return n;
}

setBuilderContentView 用于设置通知栏的 ContentView 属性

private void setBuilderContentView(Notification n, RemoteViews contentView) {
  n.contentView = contentView;
  ...
}

makeContentView() 是构造出所需要填充的 view

private RemoteViews makeContentView() {
  if (mContentView != null) {
    return mContentView;
  } else {
    return applyStandardTemplate(getBaseLayoutResource());
  }
}

如果你没有使用自定 view,将会使用标准的模板样式

private int getBaseLayoutResource() {
   return R.layout.notification_template_material_base;
}

这里只讲了 setBuilderContentView(n, makeContentView()); 方法, 后面的 setBuilderBigContentView(n, makeBigContentView());setBuilderHeadsUpContentView(n, makeHeadsUpContentView()); 方法与其类似都是设置通知的相应属性,直接给出结果,不再累述

setBuilderHeadsUpContentView --> n.headsUpContentView
setBuilderBigContentView --> n.bigContentView = bigContentView;

这样,通知的显示内容就已经构造好了。

  1. 可以看出,在构造阶段,并没有对通知栏的自定义 view 高度做出限制,但最后显示的时候却是一个固定高度,why?
  2. 先记住这里的 bigContentView 属性,后面会在提到。

buildStyled

4.0 后如果设置了 BigText,BigPic 等样式,则会调用 buildStyled 方法。buildStyled 是 Notification.Style 中的一个方法

public Notification buildStyled(Notification wip) {
  ...
  populateBigContentView(wip);
  ...
  return wip;
}

populateBigContentView 是一个 protected 所修饰的方法,具体的实现是在所设置的 Style 中,这里里 BigPic Style 为例,在 BigPictureStyle 类中,重写了该方法

@Override
public void populateBigContentView(Notification wip) {
  mBuilder.setBuilderBigContentView(wip, makeBigContentView());
}
private RemoteViews makeBigContentView() {
  RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource());
  contentView.setImageViewBitmap(R.id.big_picture, mPicture);
  ...
  return contentView;
}
private int getBigPictureLayoutResource() {
  return R.layout.notification_template_material_big_picture;
}

如果是 BigPic Style 样式的通知,其实也是调用了系统中设置的一个模板布局 notification_template_material_big_picture.
这里又调用了一次 mBuilder.setBuilderBigContentView ,前面提到了该方法是给 notification 的 bigContentView 的属性赋值。所以如果设置了样式,则会覆盖默认的 bigContentView 值

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文