uni-app 全局消息通知弹窗(App端)

实现效果

实现一个顶部的全局消息通知,并且可以常驻,除非手动关闭。

效果图如下

收到告警通知 弹窗从顶部向下弹出,可点击跳转到对应页面,可上滑关闭弹窗,弹窗出现期间不能阻塞其他操作(切换页面、点击其他按钮…)…

  1. 全局通知
  2. 可以常驻,不影响其他操作(页面跳转、点击事件)
  3. 点击消失(触发回调)、向上滑动消失(触发回调)
  4. 带点动画

实现

思索与翻找文档良久,未得容易的实现方式,转而向 HTML5+ 寻求解答,得一解决方案,遂记之,以留痕迹便与他人。

plus.nativeObj.View 原生控件对象

文档传送门

文档说明:

原生控件对象可用于在屏幕上绘制图片或文本内容,后显示的覆盖先显示的; 调用Webview窗口对象的append方法添加到Webview中,显示在父窗口所有子Webview的上面;不添加到Webview窗口对象,显示在所有Webview的上面。

注意事项

  1. 这东西无法写阴影( box-shadow

不过可以用图片替代

  1. 自带的 startAnimation 没啥效果(也许是我用错了)

可以通过定时器自己去实现动画效果

代码展示

内含详细注释

const { statusBarHeight } = uni.getSystemInfoSync();
class NativeMsg {// 整个区域的宽高viewStyle = {backgroundColor: "rgba(255,255,255,0)",top: "0px",left: "0px",width: "100%",// 取图片的高度(带阴影的尺寸)height: `${uni.upx2px(239)}px`};constructor(item, cb) {// 记录内容信息,以供回调使用this.item = item;// 弹出、消失动画要用this.offsetTop = -statusBarHeight - uni.upx2px(159);// 上边界this.startTop = -statusBarHeight - uni.upx2px(159);// 下边界this.endTop = statusBarHeight;// 上滑关闭要用this.clientY = 0;// nativeObj.View 实例this.view = null;// 背景图片this.bgBitmap = null;// 回调函数this.cb = cb || null;// 隐藏过程flag,防止重复执行this.hiding = false;// 标记当前弹窗状态this.status = "active";this.create();}// 创建区域以及背景create() {this.loadBg().then(() => {let _view = null;// 创建 View区域_view = new plus.nativeObj.View(`alarmMsg-${this.item.alarmId || "ins"}`, this.viewStyle);// 画背景_view.drawBitmap(this.bitmap,{},{ width: this.viewStyle.width, height: this.viewStyle.height, left: 0, top: 0 },"alarm-bg");// 拦截触摸事件: 开启后 区域内的触摸事件不会透传到下面_view.interceptTouchEvent(true);// 增加点击事件监听_view.addEventListener("click", () => {if (this.hiding) return;this.hiding = true;this.cb && this.cb({ type: "click", result: this.item });this.animationHide();});// 触摸事件监听_view.addEventListener("touchstart", res => {this.clientY = res.clientY;});// 触摸事件监听_view.addEventListener("touchmove", res => {const { clientY } = res;let offsetY = this.clientY - clientY;if (offsetY > 25 && !this.hiding) {this.hiding = true;this.cb && this.cb({ type: "move", result: this.item });this.animationHide();}});// 保存this.view = _view;// 画内容this.drawInfo();// 显示this.animationShow();});}// 加载背景图片loadBg() {// 创建Bitmap图片this.bitmap = new plus.nativeObj.Bitmap("nativeMsg-bg");// 以Promise方式封装 图片加载过程return new Promise((resolve, reject) => {// 加载图片, 路径需要注意this.bitmap.load("_www/static/tpt/alarm-bg.png",() => {resolve();},error => {console.log(" ====> error", error);reject();});});}// 画内容drawInfo() {const { warningTypeStr, projectName, description } = this.item;this.view.draw([{tag: "font",id: "mainFont",text: warningTypeStr,textStyles: { size: `${uni.upx2px(36)}px`, color: "#262626", weight: "bold", align: "left" },position: { top: `${uni.upx2px(60)}px`, left: `${uni.upx2px(80)}px`, height: "wrap_content" }},{tag: "font",id: "projectFont",text: projectName,textStyles: { size: `${uni.upx2px(24)}px`, color: "#7B7B7B", align: "right", overflow: "ellipsis" },position: {top: `${uni.upx2px(60)}px`,left: `50%`,width: `${uni.upx2px(750 / 2 - 40 - 20)}px`,height: "wrap_content"}},{tag: "font",id: "infoFont",text: description,textStyles: { size: `${uni.upx2px(28)}px`, color: "#7B7B7B", align: "left", overflow: "ellipsis" },position: {top: `${uni.upx2px(117)}px`,left: `${uni.upx2px(80)}px`,width: `${uni.upx2px(670 - 40 - 10)}px`,height: "wrap_content"}}]);}// 简易向下出现动画animationShow() {this.view.show();this.view.setStyle({...this.viewStyle,top: `${this.offsetTop++}px`});if (this.offsetTop >= this.endTop) {this.status = "active";return;}setTimeout(() => {this.animationShow();}, 0);}// 简易向上消失动画animationHide() {this.view.setStyle({...this.viewStyle,top: `${this.offsetTop--}px`});if (this.offsetTop <= this.startTop) {this.view.close();this.hiding = false;this.status = "close";return;}setTimeout(() => {this.animationHide();}, 0);}// 获取当前状态getStatus() {return this.status;}// 不用动画,直接消失hide() {this.view.hide();this.view.close();}
}// 对外暴露一个创建实例的方法
export function createAlarm(item, cb) {return new NativeMsg(item, cb);
}

简单描述过程

createAlarm 方法创建并返回一个 NativeMsg 的实例。

NativeMsg 类创建弹窗过程:

  1. 生成Bitmap背景图片对象 ,并加载。 方法: loadBg (异步)
  2. 在加载完成背景图片的回调里面创建弹窗区域以及把背景图画上去方法: create
  3. 区域和背景画好之后根据传递来的 item 画内容,以及绑定点击 click 事件和滑动 touch 事件。
    1. 点击事件:

      1. 点击设置 this.hiding 状态为真,防止重复触发
      2. 执行回调 this.cb
      3. 关闭弹窗 animationHide 向上消失效果
    2. 滑动事件
      1. touchstart 记录当前 this.clientY = res.clientY;
      2. touchmove 对比当前 clientYthis.clientY 之间距离,达到一定距离触发收起事件,和点击事件差不多,区别在于回调传递的 type 不同。
  4. 根据UI设计把内容话上去 drawInfo
  5. 以动画的方式显示弹窗 animationShow

使用

import { createAlarm } from "@/utils/nativeMsg";
// ...
// 接收到消息
function onReceived(data) {// #ifdef APP-PLUS// 调用showAlarmMsg(message);// #endif
}// 定义一个全局变量保存 NativeMsg 实例
let alarmMsgInstance = null;
function showAlarmMsg(msg) {console.log(" ====> msg", msg);// #ifdef APP-PLUS//    业务需求只保留一个弹窗, 当存在的时候要干掉if (alarmMsgInstance && alarmMsgInstance.getStatus() === "active") {let _oldIns = alarmMsgInstance;alarmMsgInstance = null;//延迟300 等新的弹窗出来后再消失,视觉上比较好看setTimeout(() => {_oldIns.hide();}, 300);}// 创建一个新的弹窗(新的会覆盖在旧的上面)alarmMsgInstance = createAlarm(item, res => {// 这里是点击或者滑动的回调 点击type是‘click’,滑动是‘move’// result 是传递过去的msg,原封不动的返回过来了。const { type, result } = res;if (type === "move") return;uni.navigateTo({url: `/pages/xxxxxx?id=${result.id}`});});// #endif// #ifndef APP-PLUSconsole.log(" ====> 收到消息", msg);// #endif
}

为什么不做成单例模式?

一开始是打算弄成单例模式,之后发现第二条消息来的时候动画效果不太满意,所以改成现在这种可以创建多个,等第二个出来之后在把底下那个干掉。

SubNvues原生子窗体?

需要挂载在某个页面下,场景不太适合

真机效果

Android 真机实测无啥问题。

Ios 受限于设备问题,暂无法测试

uni-app 全局消息通知弹窗(App端)相关推荐

  1. app 服务器维护通知,启用 App Store 服务器通知

    概览 App Store 服务器通知是一项适用于自动续期订阅的服务.App Store 将订阅状态的实时变化通知发送到您的服务器.有关这些服务器通知中包含的所有栏位的信息,请参阅"App S ...

  2. android 通知_Android 全局消息通知框架实现(类似EventBus)

    Github项目地址 https://github.com/532268948/MessageDemo 一.介绍 随着页面的增多,页面之间的信息交流也会越来越多,比如一个社交类app,你在个人中心修改 ...

  3. Laravel 论坛系统之消息通知功能

    消息通知 这篇文章我们来开发消息通知功能,当话题有新回复时,我们将通知作者『你的话题有新回复,请查看』类似的信息. Laravel 的消息通知系统 Laravel 自带了一套极具扩展性的消息通知系统, ...

  4. Android中集成Jpush实现推送消息通知与根据别名指定推送附示例代码下载

    场景 经常会有后台服务向Android推送消息通知的情况. 实现 首先在Android Studio中新建一个Android应用 在Project根目录的build.gradle中配置了jcenter ...

  5. Android 判断当前应用是否开启消息通知

    NotificationUtil.kt object NotificationUtil {/*** 打开手机设置页面* @param context Context*/fun setNotificat ...

  6. [经验教程]手机上微信新消息不提示也不显示微信消息通知怎么办?

    微信来新消息手机上不提示也不显示新消息提醒通知,主要因为二个方便:一是微信设置新消息通知未启,另一个是手机微信应用未开通消息提醒通知.只要按下面的教程分别排查开启新消息通知即可恢复微信消息通知提醒正常 ...

  7. win10提醒软件桌面消息通知怎么打开

    我们在使用电脑工作的时候,会习惯把很多事项都记录在上面,方便随时打开查看.如果比较重视效率和专注度,也会使用软件设置提醒事项,让自己更加安心地应对眼前的工作,等到桌面出现提醒消息通知,再进行下一项任务 ...

  8. 拼团商城小程序高保真原型模板、支付、优惠券、客服、物流、收藏、足迹、优惠券、订单管理、评价、设置、地址、售后、拼团、消息通知、商城小程序、电商小程序、拼团电商、移动端电商、高保真电商、电商app

    主要功能:首页:(轮播图.活动快速入口.商品推荐).搜索 分类: 商品分类(三级显示).商品详情.拼团or单独购买.订单结算.拼团状态  消息:(客服.通知.物流.活动)我的:收藏.足迹.优惠券.订单 ...

  9. Axure高保真家政服务用户端app全局说明+家政服务员工移动端app+家政服务web端管理信息系统(订单管理+服务管理+报表统计+财务管理+营销管理+人员管理)

    作品介绍:把家政带入互联网,这也不算什么新鲜事了.这几年来,在手机下单,上门服务已经是常态.如今的消费已经是趋向于智能消费,例如不想做饭就可以叫外卖,出门不想开车就叫网约车.衣食住行可以靠一部智能手机 ...

最新文章

  1. Chapter 2 Open Book——29
  2. svm通俗讲解_机器学习算法:SVM
  3. matlab结构阵列设计,ROM阵列及其版图结构的制作方法
  4. POJ1679判断最小生成树的唯一性
  5. 博士申请 | 上海交通大学叶南阳助理教授招收机器学习方向博士生
  6. Web安全——服务器端请求伪造(SSRF)
  7. 响应式网页设计代码_消除响应式网站建设设计中的缺陷
  8. 数据结构栈和队列_使您的列表更上一层楼:链接列表和队列数据结构
  9. quasar 异步回调_Java IO基准测试:Quasar与异步ForkJoinPool与ManagedBlock
  10. java 重构 if else_项目中的if else太多了,该怎么重构?
  11. JAVA并发包内容_java并发包
  12. mysql转txt_MyToTxt-MySQL转Txt工具下载 v3.6 官方版 - 安下载
  13. 2021年58个最佳个人WordPress博客主题
  14. 【JY】YJK前处理参数详解及常见问题分析(六):地震信息
  15. python+iOS自动化环境搭建
  16. 光纤通信原理实验装置,QY-JXSY03
  17. 【OpenCV】基于Qt的“破产版”全能扫描王
  18. 英语拼音怎么在计算机上拼出来的,英语拼音怎么写
  19. 服务器建网站要数据库,云服务器建网站需要数据库
  20. 浏览器工作模式之标准模式/怪异模式/近似标准模式

热门文章

  1. Vue - 实现验证码输入组件
  2. win7安装vs2005+qt4.8.5全过程
  3. 某短视频直播X-Bogus
  4. Linux下刻录光盘cdrecord
  5. 深入理解js中的yield
  6. 小P的故事——神奇的Dota
  7. Excalidraw 安装部署中文手绘/手写字体
  8. Google数据可视化团队:数据可视化指南
  9. WebRTC -- 认识WebRTC
  10. QCC3040---earbud State Machine module