这两天在仿图虫,其中涉及到一个需求就是很多页面需要进行瀑布流加载,网上搜了很多教程,其中有一个思路挺好的,稍微有点复杂,但确实是我想要的效果。
图片被压缩的不像样了,实例可以参考成品小程序:图虫下载
(点击下方图片即可进入)
首先定义2个变量 leftHight、rightHight,来分别记录leftList、rightList数组中图片的高度。当leftHight 大于 rightHight时,把数据放入rightList,并让rightHight叠加数据中图片的高度。当rightHight大于 leftHight 时,把数据放入leftList,并让leftHight 叠加数据中图片的高度。
var leftList = new Array();//左侧集合
var rightList = new Array();//右侧集合
var leftHight = 0, rightHight = 0, itemWidth = 0, maxHeight = 0;
if (leftHight == rightHight) { //第1个item放左边
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else if (leftHight < rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else {
rightList.push(tmp);
rightHight = rightHight + tmp.itemHeight;
}
瀑布流展示图片的时候,需要知道图片的宽高,然后根据图片的宽高比来设置 image组件的宽高。所以如果你们的数据没有宽高或宽高比,很难实现瀑布流。虽然可以通过<image>bindload获得图片宽高,但会对性能以及用户体验有很大影响,不推荐这么做。可以和后台商量下,看如何加上宽高数据。
然后计算图片实际宽度
onLoad: function (options) {
var imGwidth = app.globalData.windowWidth - 40;//考虑到边距问题,留40px
var imgwidth = imGwidth / 2;
this.setData({
imgwidth: imgwidth,
});
},
其中app.js中配置的全局变量
//app.js
App({
onLaunch: function() {
// 获取系统状态栏信息
wx.getSystemInfo({
success: e => {
this.globalData.screenHeight = e.screenHeight;
this.globalData.windowWidth = e.windowWidth;
this.globalData.windowHeight = e.windowHeight;
}
})
},
globalData: {
},
})
然后全部逻辑代码
var app = getApp()
var common = require('../../utils/common.js')
var leftList = new Array();
var rightList = new Array();
var leftHight = 0, rightHight = 0, itemWidth = 0, maxHeight = 500;
Page({
data: {
windowWidth: app.globalData.windowWidth,
CustomBar: app.globalData.CustomBar,
screenHeight: app.globalData.screenHeight,
page:1
},
onLoad: function (e) {
var imGwidth = app.globalData.windowWidth - 40;
var imgwidth = imGwidth / 2;
this.setData({
imgwidth: imgwidth,
});
this.photo();
},
photo(){
var that = this;
var leftList = new Array();
var rightList = new Array();
var url = "请求地址"
common.get(url).then((res) => {
var postList = res.data;
for (let i = 0, len = postList.length; i < len; i++) {
let tmp = postList[i];
tmp.width = tmp.width; //获取图片真实宽度
tmp.height = tmp.height;//获取图片真实高度
tmp.itemWidth = this.data.imgwidth;//获取图片显示宽度
let per = tmp.width / tmp.itemWidth; /*获取图片显示比例*/
tmp.itemHeight = tmp.height / per;/*获取图片显示高度*/
if (tmp.itemHeight > maxHeight) {
tmp.itemHeight = maxHeight;//超限时候设置图片高度为默认高度,防止被刷屏
}
if (leftHight == rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else if (leftHight < rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else {
rightList.push(tmp);
rightHight = rightHight + tmp.itemHeight;
}
}
that.setData({
leftList: leftList,
rightList: rightList,
});
})
},
getbottom(){
var that = this;
var page = that.data.page + 1;
that.setData({
page: page
});
var url = "请求地址"
common.get(url).then((res) => {
var postList = res.data.data.post_list;
for (let i = 0, len = postList.length; i < len; i++) {
let tmp = postList[i];
tmp.width = tmp.width; //获取图片真实宽度
tmp.height = tmp.height;//获取图片真实高度
tmp.itemWidth = this.data.imgwidth;//获取图片显示宽度
let per = tmp.width / tmp.itemWidth;
tmp.itemHeight = tmp.height / per;
if (tmp.itemHeight > maxHeight) {
tmp.itemHeight = maxHeight;//超限时候
}
if (leftHight == rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else if (leftHight < rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else {
rightList.push(tmp);
rightHight = rightHight + tmp.itemHeight;
}
}
that.setData({
leftList: leftList,
rightList: rightList,
});
})
},
})
其中getbottom为触底加载函数,小程序内,可使用页面的onReachBottom方法,但是最常用的方法还是scroll-view的
bindscrolltolower方法,这个要靠自己多做项目感悟。
onReachBottom(){
this.getbottom();
},
还有上面调用了一个common.js函数,这是为了代码臃肿,封装的一个get请求,具体代码在这篇文章:使用promise对象进行wx.request二次封装
wxml代码
<view class="contents">
<view class="left">
<block wx:for="{{leftList}}">
<image src="{{item}}" style='width:{{imgwidth}}px;border-radius:10px;' mode="widthFix" lazy-load"true"></image>
</block>
</view>
<view class="right">
<block wx:for="{{rightList}}">
<image src="{{item}}" style='width:{{imgwidth}}px;border-radius:10px;' mode="widthFix" lazy-load="true"></image>
</block>
</view>
</view>
wxss代码
.content{
margin: 13px;
text-align: justify;
}
.left,.right{
display: inline-block;
vertical-align: top;
width: 49%;
}
.right{
float: right;
}
这两部分建议封装成模板文件调用的,但是写文章不方便,实际写时候稍微注意点就行了
如果开发中遇到啥子疑难杂症,可在以下评论区中留言,等有时间了我会挨个回复的。