小程序實現瀑布流
近期在做APP轉成小程序的相關開發,需將APP里面的部分頁面抽離出來,做成小程序。
其中有個頁面是瀑布流(參差不齊的多欄布局)的形式。
Android客戶端一般是通過RecyclerView的方式來進行實現,但在小程序中并沒有類似的控件,所以我們只有通過自己的改編來進行實現。特此記錄!
- 實現效果如圖
index.png
一:需求分析
頁面主要分成兩列,每個條目的高度不固定,條目主要由封面圖+標題+頭像+發布者昵稱組成
多列排列要求,第一條在左側,第二條在右側,后續的根據左右兩欄的高度,依次放置在高度較低的一側。
二:技術實現思路
1、將整個頁面分成左右兩欄,兩側各對應一個數據集。
2、定義變量,記錄左右兩側的累計高度,然后依次將條目放置在高度較低的一側。從而我們可以得到左右兩側的數據集,后續只需要進行頁面的渲染就行了;
3、圖片高度的確定,單個條目中圖片寬度=(單列條目寬度/圖片的原始寬度)*圖片原始高度;
三:思路有了,接下來就是開始編寫代碼了
-
1、編寫布局,將整個頁面分成兩欄xml代碼如下
<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>
-
2、編寫樣式代碼如下
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的擺放位置。