小程序:模仿美团商品列表

最近需求是做一个类似外卖软件的商品列表,左边类型标题栏一个滚动区域右边商品栏一个滚动区域这样子,两边的滚动是互相响应的。

搜了一下github,小程序好像还没有人开源出这个轮子来,当然安卓,ios,js这样的也是有的。所以就写了个demo~


实现功能

右边商品栏滚动到不同区域时:

1,左边类型标题栏会自动切换选中,并且滚动到中间位置。

2,最上标题切换。

点击左边标题栏一项时:

1,右边商品栏滚动到响应区域,标题切换。


备注

1,这里我用了wepy框架。其实这根框架没有一点关系,只不过我懒惰费事改回原生而已。wepy对象就相当于原生的wx对象,然后repeat其实就是个循环,没其他了。

2,存在的问题还是有的,虽然处理了,但是还是不清楚为什么会这样。scroll-top属性是不会跟随scroll-view滚动的而改变的,所以要自己手动改变,例如本来默认是0的,当你滑动到最底的时候他的值还是0,所以我每次滚动前先将scroll-top设置成目前值+0.00001(先做一个超级不明显的改变),再做赋值,这样就不会出现不生效的情况,但是不支持同步赋值,例如我先设置为0再设置设置成1,也是不生效的,所以我这里用了setTimeout异步了一下,就生效了。


实现思路

  • 其实就两个事件,一个右边商品栏的滚动事件,一个就是左边标题栏的每一项的点击事件
  • 初始化拿到数据的时候计算高度,距离,添加到每一项。
  • 用的是scroll-view组件 然后通过改变scroll-top属性来控制滚动区域滚动,至于为什么我没有用scroll-into-view,上面说到了目前值+0.00001,scroll-into-view传的是id,试过改成一个不存在的id没结果是不起作用的,所以我还是选择用scroll-top。


实现代码

data

data = {
  goodsList: [
    {
      title: '类型1',
      good: ['0-1', '0-2', '0-3']
    },
    {
      title: '类型2',
      good: ['1-1', '1-2', '1-3', '1-4']
    },
    {
      title: '类型3',
      good: ['2-1', '2-2', '2-3']
    },
    {
      title: '类型4',
      good: ['3-1', '3-2', '3-3']
    },
    {
      title: '类型5',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型6',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型7',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型8',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型9',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型9',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型9',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型9',
      good: ['4-1', '4-2', '4-3']
    },
    {
      title: '类型9',
      good: ['4-1', '4-2', '4-3']
    }
  ],
  inScroll: 0, // 滚动子项id
  scrollTop: 0.00001, // 商品栏离顶部距离
  typeTop: 0.000001, // 类型导航栏离顶部距离
  // 屏幕高度
  windowHeight: 0, // 获得可用窗口高度
  goodsType: null // 商品栏上面固定的标题
}复制代码

  1. methods

methods = {
  /**
   * 点击左边的标题栏的一项,把那一项的序号传进来就完事了
   * @param index
   */
  toScrollItem (index) {
    this.scrollTop = this.scrollTop += 0.00001
    setTimeout(() => {
      this.scrollTop = this.goodsList[index].top.begin
      this.$apply()
    })
  },
  /**
   * 这里监听商品栏滚动条
   * @param detail
   */
  handleScroll({detail}) {
    // 每次滚动都需要循环匹配,找寻滚动条到达那个区域,匹配到了或者到最后了就停止,是真的蛋疼。
    for (let i = 0; i < this.goodsList.length; i += 1) {
      // 进入循环了,这个商品列表的数组是经过加工的,在初始化的时候计算了每个种类项区域(top)和左边标题(typeTop)离顶部距离。
      let v = this.goodsList[i]
      // 如果滚动条与顶部的距离 >= 这一项开头的与顶部的距离 < 这一项结尾与顶部的距离,那么现在正显示的就是这个区域了。
      if (detail.scrollTop >= v.top.begin && detail.scrollTop < v.top.end) {
        // 记录下现在显示的是第几个区域。
        this.inScroll = i
        // 位于商品栏区域上面的标题跟着变成现在显示的区域。
        this.goodsType = v.title
        // 左边标题栏也跟着滚动到,如果可以(看标题栏有多长囖),将对应的区域移到中间。
        this.typeTop = v.typeTop
        // 匹配到了,并且做完该做的东西就跳出循环,免得他继续匹配。
        break
      }
    }
  }
}复制代码

onLoad

async onLoad() {
  // 制作顶部距离,盒子高度,子项滚动id属性。
  let [top, typeTop] = [0, 0]
  this.goodsList.map((v, i) => {
    // 这个商品栏区域总高度,因为每个子项高度都是固定的,x长度就是他的总高度。
    this.goodsList[i].height = (v.good.length * 200 + 30)
    // 计算这个商品栏的开头和结尾离头部的距离,就是此区域的位置,用来判断目前显示区域的。
    // top就是这个区域开头与滚动区顶部的位置
    this.goodsList[i].top = {begin: top, end: top + (v.good.length * 200 + 30)}
    // 计算此项商品标题在商品类型标题栏的高度
    this.goodsList[i].typeTop = typeTop
    // 计算之后这个top就自增一个上一个区域的总高度的单位
    top += (v.good.length * 200 + 30)
    // 左边标题栏也自增一个固定长度单位,可以改的 ,看样式定义多少
    typeTop += 100
  })
  // 获取屏幕总高度
  const {windowHeight} = await wepy.getSystemInfoSync()
  this.windowHeight = windowHeight
  //
  this.goodsType = this.goodsList[0].title
}复制代码

view

<template>
  <view class="goods" style="height: {{windowHeight}}px">

    <!--种类栏-->
    <scroll-view
      scroll-y
      class="goods_type_list"
      scroll-with-animation
      scroll-top="{{typeTop > (windowHeight/2) ? (typeTop - (windowHeight/2)) : 0}}"
    >
      <repeat for="{{goodsList}}">
        <view class="goods_type_item {{inScroll === index ? 'active' : ''}}"
              @tap="toScrollItem({{index}})">
          {{item.title}}
        </view>
      </repeat>
    </scroll-view>

    <!--商品栏-->
    <view class="goods_list">

      <view class="goods_type_fixed goods_type_title">{{goodsType}}</view>

      <scroll-view scroll-y
                   scroll-top="{{scrollTop}}"
                   scroll-with-animation
                   bindscroll="handleScroll">
        <repeat for="{{goodsList}}">
          <view class="scroll_item">
            <view class="goods_type_title" wx:if="{{index !== 0}}">title:{{item.title}}</view>
            <view class="goods_type_title" wx:else></view>
            <repeat for="{{item.good}}">
              <view class="goods_item">{{item}}</view>
            </repeat>
          </view>
        </repeat>
      </scroll-view>
    </view>
  </view>
</template>复制代码

style

<style>
  .goods{
    position: relative;
  }
 .goods_item{
    background: #ffd900;
    height: 200px;
  }
 .goods_type_item{
   height: 70px;
 }

 .scroll_item:nth-last-child(1){
   min-height: 100.1%;
 }
  scroll-view{
    height: inherit;
  }
  .goods_type_item.active{
    background: #ffd888;
  }
  .goods_type_title{
    height: 30px;
    line-height: 30px;
    font-size: 17px;
    background-color: white;
    width: 100%;
  }
 .goods_type_list{
   position: absolute;
   width: 100px;
 }
  .goods_list{
    margin-left: 100px;height: inherit;position: relative;
  }
  .goods_type_fixed{
    position: absolute;top: 0;z-index: 1;
  }
</style>复制代码


然后做出来就是这样样子的


各位大佬如果觉得我有什么写的不对的地方或者更有方案的建议,可以私信或者评论告诉我,我这个是比较粗糙的版本,只是一个基本的实现思路,第一次写练练文笔请多包涵。


转载于:https://juejin.im/post/5c3bf6bfe51d451bd166472a

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1,实现的需求 1)首页:标题栏获取用户当前位置,使用腾讯api实现定位,不用弹窗出现用户授权, 进入首页,获取附近商铺列表 轮播图: 导航栏: (1)向后台发送请求来获取展示的商铺列表,综合排序,筛选实现根据用户 条件请求数据 (2)导航栏出现偏移 商铺列表: (1)带参跳转店铺 网络中断情况: 新页面提示没网,可点击刷新 2)店铺:根据店铺id获取店铺相关信息 头部:动态显示店铺的相关优惠 导航:分别切换菜单,评价,商家 菜单: 商品列表展示:左右联动,动态出现添加数量以及按钮 商品详情展示:弹窗卡片,展示详情,可动态出现添加数量以及按钮 购物车:展示添加进购物车的商品信息,清空结算,计算合价,差多少配送, 结算:(未实现),跳转支付,传后台购物车数据,用户信息,当前时间等订单 需求信息 评价:根据店铺id获取店铺的所有评价list展示 商家:展示商家优惠信息,需求(呼叫商家,查看食品安全档案) 3)订单 全部订单:根据用户信息获取相关全部订单,实现详情,再来一点(需要根据店铺 id) 待评价:需求:实现评价功能(提交:店铺id,评价信息) 退款:评价,详情 4)个人 用户信息展示: 登录: 未登录:(登录,注册实现) 用户地址: 管理地址:添加新地址,编辑地址(地址id,用户id) 客服中心:接入客服(公众号后台可设置客服人员) 退出账号:清空本地用户信息
如果您想要使用 Android Studio 模仿美团应用的开发过程,可以按照以下步骤进行: 1. 需求分析:确定应用的功能和特点,考虑用户的需求和使用场景。可以参考美团应用的功能和设计,了解其特点和用户需求。 2. UI设计:设计界面,制定设计规范,提高用户体验。可以参考美团应用的设计风格,设计出美观易用的界面,并保证各组件的交互逻辑正确。 3. 数据库设计:建立适合的数据库,存储和管理数据。可以参考美团应用的数据结构和数据库设计,制定自己的数据结构和数据库。 4. 后端开发:实现应用的服务端,提供数据支持。可以参考美团应用的接口和服务端代码,实现自己的服务端,提供数据支持。 5. 前端开发:实现应用的前端功能,包括用户界面和交互逻辑。可以参考美团应用的前端代码和开发框架,实现自己的前端功能。 6. 测试和发布:测试应用的各项功能,发布到应用商店或其他渠道。可以测试自己的应用功能,并发布到应用商店或其他渠道。 在具体的开发过程中,您需要掌握 Java 或 Kotlin 编程语言,熟悉 Android 系统和开发框架,如 Android SDK、Android Studio、Android Jetpack 等。同时,您需要了解网络编程、数据库设计、UI 设计和开发等方面的知识。 在开发过程中,可以参考一些开源项目和教程,如 GitHub 上的美团开源项目和各种开发社区。同时,也可以参考官方文档和开发者手册,提高自己的开发水平。 希望这些信息能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值