小程序实现瀑布流
近期在做APP转成小程序的相关开发,需将APP里面的部分页面抽离出来,做成小程序。
其中有个页面是瀑布流(参差不齐的多栏布局)的形式。
Android客户端一般是通过RecyclerView的方式来进行实现,但在小程序中并没有类似的控件,所以我们只有通过自己的改编来进行实现。特此记录!
- 实现效果如图
一:需求分析
-
页面主要分成两列,每个条目的高度不固定,条目主要由封面图+标题+头像+发布者昵称组成
-
多列排列要求,第一条在左侧,第二条在右侧,后续的根据左右两栏的高度,依次放置在高度较低的一侧。
二:技术实现思路
-
1、将整个页面分成左右两栏,两侧各对应一个数据集。
-
2、定义变量,记录左右两侧的累计高度,然后依次将条目放置在高度较低的一侧。从而我们可以得到左右两侧的数据集,后续只需要进行页面的渲染就行了;
-
3、图片高度的确定,单个条目中图片宽度=(单列条目宽度/图片的原始宽度)*图片原始高度;
三:思路有了,接下来就是开始编写代码了
-
1、编写布局,将整个页面分成两栏xml代码如下
-
wxml
<view class='content'>
<view class='left'>
<block wx:for="{{leftList}}" wx:key="index">
<image class='pic' style='height:{{item.CoverHeight}}' src='{{item.Cover}}'></image>
</block>
</view>
<view class='right'>
<block wx:for="{{rightList}}" wx:key="index">
<image class='pic' style='height:{{item.CoverHeight}}' src='{{item.Cover}}'></image>
</block>
</view>
</view>
wxss
page{
width: 100%;
margin: 0;
background: #F2F2F2;
}
.content{
display: flex;
flex-direction: row;
margin: 20rpx;
overflow: hidden;
}
.left{
width: 345rpx;
}
.right{
width: 345rpx;
margin-left: 20rpx;
}
.pic{
border-radius: 10rpx;
width: 345rpx;
}
重要部分
js
Page({
/**
* 页面的初始数据
*/
data: {
noramalData: [{
"Cover": "http://dashus.oss-cn-shenzhen.aliyuncs.com/DefaultImage/Game/20190306144842/1001.png",
"CoverHeight": 467,
"CoverWidth": 350
},
{
"Cover": "http://dashus.oss-cn-shenzhen.aliyuncs.com/DefaultImage/Game/20190313090409/完美9.png",
"CoverHeight": 871,
"CoverWidth": 672
}
],
leftList: [],
rightList: [],
leftHight: 0,
rightHight: 0
},
//以本地数据为例,实际开发中数据整理以及加载更多等实现逻辑可根据实际需求进行实现
onLoad: function(options) {
var that = this;
var allData = that.data.noramalData;
//定义两个临时的变量来记录左右两栏的高度,避免频繁调用setData方法
var leftH = that.data.leftHight;
var rightH = that.data.rightHight;
var leftData = [];
var rightData = [];
for (let i = 0; i < allData.length; i++) {
var currentItemHeight = parseInt(Math.round(allData[i].CoverHeight * 345 / allData[i].CoverWidth));
allData[i].CoverHeight = currentItemHeight + "rpx";//因为xml文件中直接引用的该值作为高度,所以添加对应单位
if (leftH == rightH || leftH < rightH) {//判断左右两侧当前的累计高度,来确定item应该放置在左边还是右边
leftData.push(allData[i]);
leftH += currentItemHeight;
} else {
rightData.push(allData[i]);
rightH += currentItemHeight;
}
}
//更新左右两栏的数据以及累计高度
that.setData({
leftHight: leftH,
rightHight: rightH,
leftList: leftData,
rightList: rightData
})
},})
四:实现该效果需要注意的点。
- 1.左右两栏布局的确定
- 2.每张图片高度的计算
- 3.根据左右两栏的高度,确定每个item的摆放位置。