小程序开发之瀑布流布局

在实际开发中,有很多时候会用到瀑布流布局,应用场景最多的可能要属图片展示了。
下面记录一下在小程序中如何实现瀑布流布局。(都是美女小姐姐的图片->_->)
一、图片分列排列计算
我们要实现一个固定排列成两列的布局,将图片动态加载进来,而加载的图片会根据图片的尺寸自动决定排左还是排右。

/* 瀑布流 */
/*单张图片*/
.img_item {
  width: 48%;
  margin: 1%;
  display: inline-block;
  vertical-align: top;
}

以上是单张图片的样式,接下来是在js中通过代码来计算图片的排列顺序。
首先定义两个变量:col1H、col2H,用来计算排列顺序。

let col1H = 0;
let col2H = 0;

然后,在data中定义一些会用到的变量。

scrollH: 0,
    imgWidth: 0,//图片宽度
    loadingCount: 0,//图片总数
    images: [],//存放图片数据
    col1: [],//左
    col2: [],//右

在onload方法中,用下面的代码计算一些变量的值

wx.getSystemInfo({
      success: (res) => {
        let ww = res.windowWidth;
        let wh = res.windowHeight;
        let imgWidth = ww * 0.48;
        let scrollH = wh;

        this.setData({
          scrollH: scrollH,
          imgWidth: imgWidth
        });
        this.loadImages();
      }
    })

最后,通过具体的代码计算出哪些图片放左边,哪些图片放右边。

//通过计算,将图片分成两列
  onImageLoad: function(e) {
    let imageId = e.currentTarget.id;
    let oImgW = e.detail.width; //图片原始宽度
    let oImgH = e.detail.height; //图片原始高度
    let imgWidth = this.data.imgWidth; //图片设置的宽度
    let scale = imgWidth / oImgW //比例计算
    let imgHeight = oImgH * scale; //自适应高度
    let images = this.data.images;
    let imageObj = null;
    for (let i = 0; i < images.length; i++) {
      let img = images[i];
      if (img.id === imageId) {
        imageObj = img;
        break;
      }
    }
    imageObj.height = imgHeight;

    let loadingCount = this.data.loadingCount - 1;
    let col1 = this.data.col1;
    let col2 = this.data.col2;

    if (col1H <= col2H) {
      col1H += imgHeight;
      col1.push(imageObj);
    } else {
      col2H += imgHeight;
      col2.push(imageObj);
    }

    let data = {
      loadingCount: loadingCount,
      col1: col1,
      col2: col2
    };

    if (!loadingCount) {
      data.images = [];
    }
    this.setData(data);
  },
  loadImages: function() {
    let images = [
      {img:'../../images/1.jpg',height:0},
      { img: '../../images/2.jpg', height: 0 },
      { img: '../../images/3.jpg', height: 0 },
      { img: '../../images/4.jpg', height: 0 },
      { img: '../../images/5.jpg', height: 0 },
      { img: '../../images/6.jpg', height: 0 }, 
      { img: '../../images/7.jpg', height: 0 },
      { img: '../../images/8.jpg', height: 0 },
      { img: '../../images/9.jpg', height: 0 },
      { img: '../../images/10.jpg', height: 0 },
      { img: '../../images/11.jpg', height: 0 },
      { img: '../../images/12.jpg', height: 0 },
      { img: '../../images/13.jpg', height: 0 },
      { img: '../../images/14.jpg', height: 0 }
    ]
    let baseId = "img-" + (+new Date());
    for (let i = 0; i < images.length; i++) {
      images[i].id = baseId + "-" + i;
    }
    _this.setData({
      loadingCount: images.length,
      images: images,
    })
  },

二、布局

<view class="view-fp-container">
  <!--瀑布流-->
  <view style="display:none">
    <image wx:for="{{images}}" wx:key="id" id="{{item.id}}" src="{{item.img}}" bindload="onImageLoad"></image>
  </view>
  <scroll-view scroll-y="true" style="height:{{scrollH}}px" bindscrolltolower="scrollLower">
    <view style="width:100%">
      <view class="img_item">
        <view style="background-color:#fff;margin-bottom:10rpx;" wx:for="{{col1}}" wx:key="id">
          <image src="{{item.img}}" style="width:100%;height:{{item.height}}px" mode='aspectFill'></image>
        </view>
      </view>
      <view class="img_item">
        <view style="background-color:#fff;margin-bottom:10rpx;" wx:for="{{col2}}" wx:key="id">
          <image src="{{item.img}}" style="width:100%;height:{{item.height}}px" mode='aspectFill'></image>
        </view>
      </view>
    </view>
  </scroll-view>
</view>

三、样式

page {
  background-color: #f2f2f2;
}

.view-fp-container {
  display: flex;
  flex-direction: column;
  margin: 0 10rpx;
}

/* 瀑布流 */

.img_item {
  width: 48%;
  margin: 1%;
  display: inline-block;
  vertical-align: top;
}

四、最终效果
在这里插入图片描述
(注:展示效果和图片数量、宽高有关系)

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码的灵魂是bug!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值