利用原生子窗体解决悬浮窗口播放的问题及踩坑记录

  实现效果如图:参考得到app交互,音频课程返回时,app下方展示悬浮窗口播放,可暂停、播放、关闭,点击可返回至音频文章查看文章。关闭app,再进入有缓存上次音频课程,可点击继续播放。上滑显示悬浮框,下滑隐藏悬浮框。

一、原生子窗体

  subNVues 是 vue 页面的原生子窗体。用于解决App中 vue 页面中的层级覆盖和原生界面灵活自定义用的。

  它不是全屏页面,也不是组件,就是一个原生子窗体。它是一个 nvue 页面,使用 weex 引擎渲染,提供了比 cover-view、plus.nativeObj.view 更强大的原生排版能力,方便自定义原生导航或覆盖原生地图、视频等。

  详细配置见这个:原生子窗体

  请详读:subNVues 开发指南

  如何获取原生子窗体实例及实例方法,见这篇:subNVue原生子窗体

  请先熟读:如何配置  —  开发指南  —  实例及方法

二、解决方案

1、在需要展示的页面增加原生子窗体配置

        {
            "path": "pages/course/course",
            "style":{
                "app-plus":{
                    "subNVues":[{
                        "id": "course-bgAudio",
                        "path": "pages/subNVue/bgAudio",
                        "style": {
                            "width": "710rpx",
                            "height": "100rpx",
                            "bottom": "30rpx",
                            "margin": "auto",
                            "background": "transparent"
                        }
                    }]
                }
            }
        },

  注意:

  id需唯一不能重复;

  margin:auto; 代表左右居中。

  path代表子窗体页面路径。我们这个需求都是要一样的窗口展示,所以可以共用一个nvue页面。页面路径指南上有说,只要可以正确引入即可。

2、在pages/subNVue/bgAudio.nvue页面编写自己的页面样式及代码逻辑即可,这个就不多说了。

3、上滑滚动、下滑隐藏。这里我们接可以写一个mixin  - submixin.js

export const submixin = {
    data() {
        return {
            curTop: 0
        }
  },
    methods: {
        showSubOrNot(subId) {
            if(!uni.getStorageSync('curArticle')) {
                const _sub = uni.getSubNVueById(subId + '-bgAudio')
                _sub.hide()
            }else{
                const _sub = uni.getSubNVueById(subId + '-bgAudio')
                _sub.show()
            }
        },
        pageScroll(subId, top) {
            if(!uni.getStorageSync('curArticle')) return
            const _sub = uni.getSubNVueById(subId + '-bgAudio')
            top > this.curTop ? _sub.hide() : _sub.show()
            this.curTop = top
        }
    }
}
// 如何使用
// 1、引入submixin
import { submixin } from '@/mixins/submixin.js'

// 2、注册mixins
mixins:[submixin],

// 3、onShow的时候控制sub窗口展示与否的逻辑
// 4、onPageScroll的时候控制sub窗口滚动显示的逻辑
onShow() {
    this.showSubOrNot('course')
},
onPageScroll(top) {
    this.pageScroll('course', top.scrollTop)
},

  业务逻辑处理,肯定是需要结合 vuex 状态管理了。

三、踩坑点

1、获取sub窗口实体的方法易踩坑:

  uni.getSubNVueById(subNvueId):通过 ID 获取 subNVues 原生子窗体的实例。

  uni.getCurrentSubNVue():在一个subnvue窗体的nvue页面代码中,获取当前 subNVues 原生子窗体的实例。

  我刚开始为了简便不写sub窗口的id,以为可以使用 uni.getCurrentSubNVue() 任意获取当前页面的子窗体实例,但是好像不是这样的,这样用的话,就很容易卡死不动。不知道为啥,后来认真看了官网上对 2 种获取实例的方法描述。uni.getCurrentSubNVue() 说的是在一个subnvue窗体的nvue页面代码中,获取当前 subNVues 原生子窗体的实例。所以猜到可能是这里的问题,然后换成 uni.getSubNVueById(subNVueId) 之后就 ok 了。具体原因不详,只能说是个踩坑点。

2、不知道是否有设置公共的子窗体的配置,查了一下,没找到。

  目前我是需要悬浮窗体播放的几个页面,就加了 子窗体 的配置,不需要的不加即可。

  不过也确实应该是这样,总不可能所有页面都放子窗体,对用户也不那么友好。看得到也是在个别与音频播放相关和tabbar列表的页面加了悬浮窗体播放,其他位置就没加。

  通过这个原生子窗体感觉就可以做很多事情了,比如这篇博客说的这个:视频聊天,可以了解下:uniapp 使用原生子窗体进行视频聊天

  其实之前就想做这个东西,之前研究的是通过 Html5+ 的接口:plus.webview.create 去做这个事情,也可以实现置顶悬浮,但是那个悬浮窗口的样式包括业务逻辑就不好控制了,研究了好久也没有很好的解决方案。后来看到这个原生子窗体,感觉挺可以,一试确实可以,感觉挺不错。

原文地址:https://www.cnblogs.com/goloving/p/14836690.html