uni-app原生TabBar动画解决方案

Author Avatar
Amos
发表:2020-07-19 18:17:00
修改:2022-05-11 01:05:21

思考在uni-app的原生TabBar上实现模拟按下回弹的动画(也可衍生其他动画效果),
在查阅官方文档以及各方搜寻后,发现还没有相关文章说明(或许是太简单了😂),我这里记录个相对简单的解决方案(可自行举一反三)。

PS:如果是自定义TabBar有更容易且合理的实现方式,这里只是说明uni-app的原生TabBar(可能不合理)。


🎉 效果


模拟按下回弹

简单模拟按下回弹




可模拟更完整的例子(如招商掌上生活APP)



🎇 问题及思路

问题:在pages.json中配置 原生tabBar的selectedIconPath 图片地址时用GIF图。
虽然选中菜单可达到触发模拟的动画效果,
但这会出现如:多次点击菜单重复触发GIF、小程序不兼容直接配置GIF报错 等不符合需求的情况……

为解决这一系列问题,有个解决的思路:
1.在每次触发对应TabBar菜单选中时,利用 页面生命周期的onShow 检测触发,
2.触发时 动态设置TabBar对应菜单的selectedIconPath 为GIF,
3.并在动画完成后再 动态设置TabBar对应菜单的selectedIconPath 为动画最后一帧的静态图片。

归纳为: 开始触发 -> 动画 -> 静态结束 一整个流程


🧤 实现

1、准备素材

未选中时的图片,选中时的GIF,选中后的图片(一般为GIF的最后一帧)

素材

我这里简单利用 Photoshop 制作GIF

GIF制作


2、pages.json 配置 TabBar

TabBar部分,具体查看 配置tabBar

"tabBar": {
    "list": [
        {
            "pagePath": "pages/circle/index",
            "iconPath": "static/tabBar/circle.png", // 未选中时的图片 图标 40kb 81*81
            "selectedIconPath": "static/tabBar/circle-selected.png", // 选中后的图片(一般为GIF的最后一帧)
            "text": "浏览"
        },
        {
            "pagePath": "pages/message/index",
            "iconPath": "static/tabBar/message.png",
            "selectedIconPath": "static/tabBar/message-selected.png",
            "text": "消息"
        },
        {
            "pagePath": "pages/user/index",
            "iconPath": "static/tabBar/user.png",
            "selectedIconPath": "static/tabBar/user-selected.png",
            "text": "我的"
        }
    ]
}


3、触发动画

在对应TabBar菜单页面中,利用 页面生命周期的onShow 检测触发,
动态设置TabBar对应菜单的selectedIconPath 为GIF,
并在动画完成后再 动态设置TabBar对应菜单的selectedIconPath 为动画最后一帧的静态图片。

触发方法,我这里是写在common/util.js中

/**
 * TabBar切换动画
 * @param {Number} index      tabBar下标(如:第一个菜单为0)
 * @param {String} imgUrl     选中后图片地址(GIF最后一帧)
 * @param {String} gifUrl     GIF地址
 * @param {Number} delayTime  动画时间 毫秒(取GIF时间)
 */
function animationTabBar({index, imgUrl, gifUrl, delayTime}) {
    delayTime = delayTime != '' ? delayTime : 0; // 延迟触发时间
    // 切换GIF触发动画
    uni.setTabBarItem({
        index: index,
        selectedIconPath: gifUrl
    });
    // 为了避免重复触发,延迟切换回选中后的图片
    setTimeout(()=>{
        uni.setTabBarItem({
            index: index,
            selectedIconPath: imgUrl
        });
    }, delayTime);
}

module.exports = {
    animationTabBar: animationTabBar // TabBar切换动画
}

对应TabBar进行页面触发

// 引入方法
import { animationTabBar } from '@/common/util.js';
export default {
    onShow() {
        animationTabBar({
            index: 2, // tabBar下标(如:第一个菜单为0)
            imgUrl: "static/tabBar/user-selected.png", // 选中后图片地址(GIF最后一帧)
            gifUrl: "static/tabBar/user-selected.gif", // GIF地址
            delayTime: 100 // 动画时间 毫秒(取GIF时间,自行估算)
        });
    }
}

转载请遵循 协议许可
本文所有内容严禁任何形式的盗用
本文作者:Amos Amos
本文链接:https://amoshk.top/2020071901/

评论
✒️ 支持 Markdown 格式
🖼️ 头像与邮箱绑定 Gravatar 服务
📬 邮箱会回复提醒(也许会在垃圾箱内)