盒子
盒子
文章目录
  1. 原理
    1. 通知栏的显示
      1. 延迟意图PendingIntent
        1. 配置Intent
          1. 注意点
            1. 第一点
            2. 第二点
        2. 创建PendingIntent
      2. 通知Notification构建
      3. 发送通知
    2. 消息数的显示
      1. 创建BadgeView实例
      2. 构建文本
      3. 显示
  2. 效果图
  3. 一系列文章

Android高仿微信之mvp实现(四)

前面把聊天的基本功能都实现了,最近有点忙,因为快到学期末了,考试就来了,所以后面可能会慢点。大家都反映没有消息提醒,所以抽了点时间把聊天的提醒简单的实现了下,下面简单的介绍下。

原理

我这里用到得原理主要就两个知识点

  • Notification
  • BadgeView

只要你解决了这两项以后的消息提醒神马的都能轻松搞定。首先来解释下他们的应用,对于Notification我想应该很多都接触了,但还是简单的说下,我这里使用它就是实现我们日常看到的消息通知框的出现,不过其中的使用要注意几点,下面会详细指出。至于BadgeView这是一个开源库,它的功能就是我们日常看到的在应用中显示的未读消息数。

原理介绍完了下面来看看实现

通知栏的显示

这里除了Notification还有一个重要的是PendingIntent(延迟意图)就是实现点击通知栏后的操作

延迟意图PendingIntent

既然是意图自然要使用Intent指定我们点击后的应用操作

配置Intent

1
2
3
4
5
6
7
8
Intent intent = new Intent(App.getAppContext(), MainActivity.class);
//防止开启重复的Activity
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Bundle bundle = new Bundle();
//防止pendingIntent相同
intent.setData(Uri.parse("message://" + regId));
bundle.putInt("_id", _id);
intent.putExtras(bundle);

我这里是点击都自动跳转到主界面,然后在主界面做相应的操作。在这里要注意下我前面说的注意点。

注意点
第一点

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

这句代码是防止我们点击通知栏后开启指定的界面,后退栈时界面重复。如果你没有清空栈,就会出现重复创建的现象。可能这里有人会说可以使用launchMode的模式,没错当我们使用signalTop或者其它的如singleTask能解决重复界面的创建,但是这里有个问题如signalTop当在栈顶是并不会重新创建该Activity而是会直接复用原来的。所以这样就会导致页面不会更新未读消息数。

第二点

intent.setData(Uri.parse("message://" + regId));
intent设置不同的数据源,虽然PendingIntent提供了四个这方面的参数,但都是针对相同对象的延迟意图

  • FLAG_ONE_SHOT 意思就是你设置的延迟意图只可使用一次,说明以后通过它的都不会实现
  • FLAG_NO_CREATE 这个更简单了就是不存在也就不会创建了直接返回null
  • FLAG_CANCEL_CURRENT 这个就是存在就取消原来的,使用新的,新的只改变要传递的数据
  • FLAG_UPDATE_CURRENT 跟上面的相差不大,它会更新原来的数据

上面的对要开启不同的界面都没有作用,都会覆盖原来的意图,导致不同的人发送消息时,点击通知栏的不同通知显示同一个聊天界面。这里使用regId做唯一标识就能消除这方面的问题。

创建PendingIntent

1
PendingIntent pi = PendingIntent.getActivity(App.getAppContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

通知Notification构建

这里我就直接贴代码了都是很容易理解的了。

1
2
3
4
5
6
7
8
9
10
Notification notification = new Notification.Builder(App.getAppContext())
.setSmallIcon(R.drawable.icon)
.setAutoCancel(true)
.setTicker("高仿微信有新消息")
.setContentTitle(userName)
.setContentText("[" + unReadNum + "条] " + rMessage)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS)
.setContentIntent(pi)
.setWhen(System.currentTimeMillis())
.build();

发送通知

获取系统通知管理

1
manager = (NotificationManager) App.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);

发送通知

1
manager.notify(_id, notification);

通知栏的构建就完美结束了

消息数的显示

既然前面都说了借助了开源库,所以实现就相对来说就简单了,我这里把它总结成三步

创建BadgeView实例

1
BadgeView badgeView = new BadgeView(context, view);

其中view代表你要依附的视图

构建文本

1
2
3
4
5
6
badgeView.setTextColor(Color.WHITE);
badgeView.setText(textValue);
badgeView.setBackground(context.getResources().getDrawable(R.drawable.dot_bg));
badgeView.setTextSize(12);
badgeView.setBadgePosition(BadgeView.POSITION_TOP_RIGHT);
badgeView.setBadgeMargin(0, 0);

上面的肯定没问题吧,简单明了,显示位置badgeView.setBadgePosition默认是右上角,但我感觉效果不明显,不是我们要得效果,没有像微信那样视图出去了部分,所以我都后面看了下源码,发现了badgeView.setBadgeMargin(0, 0);能使该效果明显些。

显示

1
badgeView.show();

到这里所有的消息提醒功能就完成了,最后看下效果

效果图

效果

一系列文章

Android高仿微信之mvp实现(一)
Android高仿微信之mvp实现(二)
Android高仿微信之mvp实现(三)

项目地址:https://github.com/idisfkj/HightCopyWX

转载请指明出处 idisfkj博客:https://idisfkj.github.io

支持一下
赞赏是一门艺术