微信小程序列表加载动画
- 微信小程序列表加载动画示例
- 实现思路
- 什么是动画?
- 导航栏设置
- 列表动画加载
- 完整代码demo
微信小程序列表加载动画示例
初学微信小程序开发,记录一下。网上找了很久这种效果,帖子很少,都没看到想要的,自力更生,翻翻官方文档自己写。
效果:
实现思路
什么是动画?
接触一项技术前,阅读官方文档是必不可少的,明白了原理才能进行开发,微信开发文档上面有详细介绍 https://developers.weixin.qq.com/miniprogram/dev/api/ui/animation/wx.createAnimation.html
导航栏设置
页面的导航栏,这里推荐学习尚硅谷提供的微信小程序入门教程,针对一个高仿网抑云音乐项目来进行讲解,对萌新来说很有帮助,上面的老师讲得挺详细的,跟着去做的时候,千万别看一点做一点,最好做到统筹全局,把一个章节看完再去动手,反复看几遍,能避免踩坑。
https://www.bilibili.com/video/BV12K411A7A2?p=44
上面视频链接做了详细的导航栏切换效果的实现。
列表动画加载
首先要明确的是,需要加载的列表数据需要滚动,这样的话,需要用一个scroll-view来进行包裹,相信静态数据显示大家都不会有问题,so easy,使用wx:for来进行列表数据加载。
当静态数据搭建好后,看起来总是怪怪的,静止的画面总感觉缺了什么,不够高大上?
重头戏开始,首先,附上wxml代码。
<scroll-view scroll-x class="navScroll" enable-flex scroll-into-view="{{'scroll'+navId}}" scroll-with-animation>
<view id="{{'scroll'+item.id}}" class="navItem" wx:for="{{navList}}" wx:key="id">
<view class="navContent {{navId===item.id?'active':''}}" bindtap="changeNav" data-id="{{item.id}}">
{{item.name}}
</view>
</view>
</scroll-view>
<view class="hr"></view>
<scroll-view scroll-y class="srollDataCard" bindrefresherrefresh="handleAnnounceRefresh"
refresher-enabled="{{isRefresher}}" refresher-triggered="{{isTriggered}}" bindscrolltolower="handleToLower">
<view wx:if="{{navId == 0}}" wx:for="{{announceList}}" wx:key="pk_bill" wx:for-index="id">
<view class="announceCard" animation="{{ani[id]}}" style="opacity:{{opacity}};transform:{{transform}};" bindtap="showAnnounceDetail">
{{item.pk_bill}}
<!--卡片内容自行设置-->
</view>
</view>
</scroll-view>
<!--模拟弹窗画布-->
<view class="mask" bindtap="closeAnnounceDetail" wx:if="{{isShowModal}}"></view>
<!--模拟弹窗-->
<view class="modalDlg" animation="{{annDetailAni}}">
<view class="annDetailcloseBtnArea">
<button bindtap="closeAnnounceDetail" size="mini"
style="width:60rpx;height:60rpx;line-height:60rpx;font-size:30rpx;margin-right:2rpx;display:inline;float:right;">×</button>
</view>
</view>
scroll-view参数解析:
scroll-y:实现y轴滚动
refresher-enabled、bindrefresherrefresh:实现下拉刷新,bindrefresherrefresh绑定下拉刷新的方 法。refresher-enabled,开启刷新,boolean值。
refresher-triggered:加载数据完成让下拉刷新的三个点…消失的标记,boolean值。
bindscrolltolower:绑定了触底加载的方法。
此处有个小坑,实践证明refresher-enabled不要直接写死把它恒等于true,这样会出现初次进入界面,数据拿到了,界面无法渲染成功的问题,出现一片空白。解决方法:在初次加载界面的时候在data里初始为false,在拿到数据后再设置为true。
其余参数解析:
navId :导航栏下标,这边用第一个导航栏,即下标为0。
pk_bill:数据列表的主键。
id:for循环每次执行的下标,相当于java里for循环一般这么写for(int i=0,i<2;i++) 这个id就相当于这个i
ani[id]:动画数组。
showAnnounceDetail:绑定了列表的卡片,弹出拟态窗口的方法。
JS代码
const app = getApp();
let navList = [{
id: 0,
name: "页面导航0"
}, {
id: 1,
name: "页面导航1"
}, {
id: 2,
name: "页面导航2"
}, {
id: 3,
name: "页面导航3"
}, {
id: 4,
name: "页面导航4"
}, {
id: 5,
name: "页面导航5"
}];
Page({
/**
* 页面的初始数据
*/
data: {
navList: navList, //导航栏tag选项
navId: 0, //标识导航栏下标
isTriggered: true, //标志下拉刷新
announceList: [], //列表卡片列表
isShowScroll: false, // 是否出现滚动条
isRefresher: false, // 这一个条件很重要,如果不这样设置,数据加载会出现问题,会出现需要下拉才加载出数据
ani: [],
currentpage: 1,
pagesize: 6,
totalcount: 1,
opacity: 0,
transform: "",
annDetailAni: "",
isShowModal: false, //点击卡片详情 背景画布显示
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log("已进入系统主页");
// 当前微信用户的权限校验 加载数据区域 默认第一个导航栏页签 公告大厅
wx.showLoading({
title: '正在加载',
})
// 当前微信用户的权限校验过滤
this.checkUserAuth();
// 查询列表卡片
this.queryList(1);
// 查询总页数
this.queryPageCount();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 当前微信用户的权限校验过滤
*/
checkUserAuth() {
// 权限过滤 省略
},
queryList(currentpage) {
/**
* 这里可以被视为发起请求 之后的回调操作
* currentpage传过来是分页查询参数:当前页
* 下面是造出来的数据 上拉触底加载即是把数据追加到list尾部
*/
let announceList = [];
if (currentpage == 1) {
announceList = [{
"pk_bill": "卡片1",
}, {
"pk_bill": "卡片2",
}, {
"pk_bill": "卡片3",
}, {
"pk_bill": "卡片4",
}, {
"pk_bill": "卡片5",
}, {
"pk_bill": "卡片6",
}];
}
if (currentpage == 2) {
let nextAnnounceList = [{
"pk_bill": "卡片7",
}, {
"pk_bill": "卡片8",
}];
announceList = this.data.announceList.concat(nextAnnounceList);
}
// 必须在执行滑动前初始化动画数组
this.setData({
announceList: announceList,
isRefresher: true,
opacity: 0,
transform: `translateY(${200*this.data.pagesize}rpx)` // 根据分页的数量 计算初始隐藏(透明)的位置 如果这个位置露出了当前屏幕一点点,那么动画将不会显示效果
});
// 设置setTimeout的时间 是因为:一般执行回调 请求会有一个时间,加载动画需要这个时间来反应,如果没有一点点延迟,那么动画加载便失效
// 这个时间可以很短很短 短到1ms 但就是需要 如果是写在接口回调里 则去掉这个setTimeout
setTimeout(() => {
this.slideDown(this.data.announceList);
}, 1);
wx.hideLoading({})
console.log("加载数据完成,当前数据:", JSON.stringify(this.data.announceList));
},
queryPageCount() {
// 自行编写查询分页总数代码
this.setData({
totalcount: 2
});
},
// 公告大厅加载动画
slideDown(dataList) {
// 关于微信小程序动画的参数 请查看官方文档
const that = this;
let duration = 600;
for (let a in dataList) {
let animation = wx.createAnimation({
duration: duration,
timingFunction: 'ease',
});
that.setAni(that, animation);
duration = duration + 200;
}
},
// 设置动画数组
setAni(that, animation) {
let ani = that.data.ani;
ani.push(animation.translateY(0).opacity(1).step().export());
that.setData({
ani: ani
})
console.log("设置动画中");
},
/**
* 导航点击切换事件
*/
changeNav(e) {
// 通过id进行传参会自动转化为String,需要进行*1处理成number e.currentTarget.id * 1
// 通过data-id进行传参则不会
this.setData({
navId: e.currentTarget.dataset.id,
});
},
/**
* 下拉刷新
*/
handleAnnounceRefresh() {
console.log("下拉刷新");
wx.showLoading({
title: '正在加载',
})
if (this.data.navId == 0) {
// 重新加载须清空当前页面数据和动画数组
this.setData({
announceList: [],
ani: [],
currentpage: 1
})
// 重新加载第一页数据
this.queryList(1);
// 查询公告大厅总页数
this.queryPageCount();
// 此处设置setTimeout的目的是不让下拉刷新的三个... 立即消失 避免回弹太快产生错觉
setTimeout(() => {
this.setData({
isTriggered: false
});
}, 200);
}
wx.hideLoading({})
},
/**
* 上拉触底加载
*/
handleToLower() {
if (this.data.currentpage + 1 <= this.data.totalcount) {
let currentpage = this.data.currentpage + 1;
console.log("当前页:", currentpage);
this.setData({
currentpage: currentpage,
})
if (this.data.navId == 0) {
// 加载数据区域 页面导航0
wx.showLoading({
title: '正在加载',
})
this.queryList(currentpage);
setTimeout(() => {
wx.hideLoading({})
}, 200);
}
} else {
wx.showToast({
title: "已经到底啦!",
icon: "none",
duration: 1000
})
}
},
/**
* 弹出卡片详情
*/
showAnnounceDetail: function () {
// 省略
},
/**
*关闭弹窗
*/
closeAnnounceDetail: function () {
// 省略
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
// 隐藏返回按钮
wx.hideHomeButton();
},
})
上拉触底加载,其实就是把下一页的内容追加到list的尾部,然后设置动画,就很美观了。
代码里都有很多注释啦,相信聪明的你们,能看懂的!
完整代码demo
以上代码拥有了核心的逻辑思想,有了灵魂,如果想得到整体,程序员进阶从初学到放弃,工资微薄,实属不易,请各位哥哥打赏一下小弟,之后附上下载链接。