微信小程序手把手教你实现类似Android中ViewPager控件效果

微信小程序手把手教你实现类似Android中ViewPager控件效果

  • 前言

  • 需求分析

  • 头部TAB

    • 滑动的内容部分
    • 最终版本
  • 尾巴

前言

在做Android开发的时候,ViewPager是开发者使用频率很高的一个控件,今天我们就用小程序来实现一个类似的demo,效果图如下:
在这里插入图片描述
下面就开始直接撸代码了。

需求分析

通过查看界面元素,发现主要由两部分组成:头部能点击的title和下面能滑动的内容。

头部TAB

这个比较简单:主要是根据你的业务要分为几块,则将屏幕宽度分成几个等宽的view即可。然后每个tab下面的指示器用view的下边框替代,只有该tab被选中时才显示。代码如下:

1// wxml布局文件 2<view class='page'> 3 <view class='item-parent'> 4 <view wx:for='{{titles}}' class='title-item' style='border-bottom: 5rpx {{current == index ? selectindicatorcolor : normalindicatorcolor}} solid' bindtap='taptab' data-index='{{index}}'>{{item}}</view> 5 </view> 6</view> 7 8
1// wxss文件 2.page { 3 display: flex; 4 flex-direction: column; 5} 6.item-parent { 7 display: flex; 8 flex-direction: row; 9} 10.title-item { 11 justify-content: center; 12 text-align: center; 13 width: 350rpx; 14 height: 50rpx; 15 display: flex; 16 flex-direction: row; 17 align-items: center; 18 font-size: 26rpx; 19} 20 21
1// js文件 2Page({ 3 data: { 4 titles: ['首页', '热点', '推荐'], 5 current: 0,//此属性暂时没有用到,后面会用到 6 selectindicatorcolor: 'red', 7 normalindicatorcolor: 'white' 8 }, 9 taptab(e) { 10 var index = e.currentTarget.dataset.index 11 this.setData({ 12 current: index 13 }) 14 }, 15 //此函数后面会用到 16 bindChange(e) { 17 this.setData({ 18 current: e.detail.current 19 }) 20 } 21}) 22 23

上面代码很简单,就不赘述了,接下来看效果图:
在这里插入图片描述

滑动的内容部分

到这里我们已经实现了头部TAB的功能了,那么下面我们那个可滑动内容需要怎么实现了?其实官方已经给我们提供了一个组件swiper(swiper官方教程)可以用作视图滚动,只不过一般来说我们只是用来做轮播图。既然作为视图滚动容器,肯定可以滚动其他控件的。选好了我们需要的组件,接下来就是动手实现了,我们在原先的wxml中加入swiper组件:

1// wxml布局文件 2<view class='page'> 3 <view class='item-parent'> 4 <view wx:for='{{titles}}' class='title-item' style='border-bottom: 5rpx {{current == index ? selectindicatorcolor : normalindicatorcolor}} solid' bindtap='taptab' data-index='{{index}}'>{{item}}</view> 5 </view> 6 <swiper current='{{current}}' bindchange="bindChange"> 7 <swiper-item> 8 <text>首页</text> 9 </swiper-item> 10 <swiper-item> 11 <text>热点</text> 12 </swiper-item> 13 <swiper-item> 14 <text>推荐</text> 15 </swiper-item> 16 </swiper> 17</view> 18 19

其他地方变动不大,这里通过current属性,已经绑定了swiper的change事件,结合前面js中给出的代码,从而实现了上下两部分的联动。接下来看效果图:
在这里插入图片描述
到这里,我们貌似完美实现了类似ViewPager效果了,真相真的是这样的么?细心的朋友可能发现,上面的图片中,我故意用鼠标在下面进行滑动,但是页面并没有跟着滚动,为什么会这样了?通过给swiper增加背景颜色发现,原来swiper的高度是固定的,不会随着里面组件的高度自适应变化,所以只有上面那部分会响应滚动事件,我们加上背景颜色瞧瞧。
在这里插入图片描述
这样就看的很清晰了,所以为了能使下面的内容充满屏幕,我们只能给swiper设置一个高度了,那么这个高度要设置多少合适了?从我们界面上看是我们整个可用窗体的高度减掉我们头部TAB的高度,然后我们在js中去计算这个高度。

1// js文件 2//data中增加一个属性 3... 4contentheight: 0 5... 6onLoad: function(res) { 7 //减号前面是获取当前窗体的高度单位为px,55是头部tab的高度,单位是rpx,减号后面部分是将rpx转px 8 var contentH = wx.getSystemInfoSync().windowHeight - 55 / 750 * wx.getSystemInfoSync().windowWidth; 9 this.setData({ 10 contentheight: contentH 11 }) 12} 13 14

wxml中设置swiper高度

1// wxml文件增加style 2... 3<swiper current='{{current}}' bindchange="bindChange" style='background: gray;height:{{contentheight}}px'> 4... 5 6

接下来,我们再看下效果:
在这里插入图片描述
这个时候我们可以看到,swiper已经充满了整个屏幕了,并且不管从哪个地方都能进行滑动。到了这里,那我们就可以做很多事情了,可以给每个tab加上各种不同的布局来实现不同的业务逻辑了。那么我们这里先来实现一个能滚动的列表试试,修改首页的item中的代码:

1// wxml布局文件 2//将原来首页swiper-item中的子元素修改如下: 3... 4<view class='page'> 5 <text wx:for='12314312312312312sdfsfsdfsdfsfdfdf'>首页{{item}}</text> 6</view> 7... 8 9

接下来,我们看下效果图:
在这里插入图片描述
我们看到,虽然布局竖向超过了屏幕范围,但是却无法上下滚动。为什么会有这样的现象了?我猜想大概是微信小程序的限制罢了。既然这样无法实现我们常用的上下滚动列表效果,那我们只能曲线救国了,在外层再套一个能竖向滚动的scroll-view,稍微坐下改动:

1// wxml布局文件 2//将原来首页swiper-item中的子元素修改如下: 3... 4<scroll-view style='height:100%' scroll-y> 5 <view class='page'> 6 <text wx:for='12314312312312312sdfsfsdfsdfsfdfdf'>首页{{item}}</text> 7 </view> 8</scroll-view> 9... 10 11

再看效果图:
在这里插入图片描述
哈哈,完美搞定。

最终版本

在实际应用中,我们每个页面可能有非常复杂的界面和业务逻辑,我们的业务代码和UI代码最好不要都写在一个wxml中,防止业务混乱。为了业务和UI解耦,我们每个swiper-item中的内容最好能单独成一个模块,然后我们再引用,所以我们通过封装组件来解耦UI和业务。这里以首页组件封装为例:

  • 项目根目录建立component目录
  • 在component目录下右键,选择新建Component子菜单项
  • 自定义名字,然后就会生成跟pages中页面一样的目录

在这里插入图片描述
我们对index组件目录中的文件稍加修改,使其能展示一个类似新闻列表的页面。

1// wxml布局文件 2<view class='item' wx:for='{{data}}'> 3 <view class='title'>{{item}}</view> 4 <view class='bottom'> 5 <view>新华网</view> 6 <view class='comment'>2344</view> 7 </view> 8</view> 9 10
1// wxss文件 2.item { 3 display: flex; 4 flex-direction: column; 5 border-bottom: 1rpx #ccc solid; 6 justify-content: center; 7 padding: 20rpx; 8} 9.title { 10 font-size: 35rpx; 11} 12.bottom { 13 display: flex; 14 flex-direction: row; 15 font-size: 20rpx; 16 color: gray; 17 margin-top: 10rpx; 18} 19.comment { 20 margin-left: 30rpx; 21} 22 23
1// js文件,这里比较简单,只是在data中增加一个data属性 2... 3 data: { 4 data: ['狗狗是人类最好的朋友', '90%长痘的人都不知道,药店里不起眼的东西,睡前抹一抹,祛痘很快', '保时捷Cayenne,即刻驾驭梦想','沙漠极限挑战:三台空调挑战70度极限高温,谁先宕机?','德牧带大的二哈,二哈现在离不开她了,一刻不见就想德牧','为什么说达到第四宇宙速度就可以逃出银河系?','许久没去草坪的边牧,来到公园,开心的像个孩子'] 5 }, 6... 7}) 8 9 10

其他两个页面组件跟这个类似,这里就不演示了。然后我们在需要使用的页面json文件中引用:

1// json文件,引用组件,前面的名字可自定义,会在wxml中使用 2{ 3 "usingComponents": { 4 "index": "../../component/index/index", 5 "hot": "../../component/hot/hot", 6 "recommend": "../../component/recommend/recommend" 7 } 8} 9 10
1// wxml中使用组件 2... 3<swiper current='{{current}}' bindchange="bindChange" style='height:{{contentheight}}px'> 4 <swiper-item> 5 <scroll-view style='height:100%' scroll-y> 6 <index />//引用首页组件,注意名字要和json中的定义的名字相同 7 </scroll-view> 8 </swiper-item> 9 <swiper-item> 10 <scroll-view style='height:100%' scroll-y> 11 <hot />//引用首页组件 12 </scroll-view> 13 </swiper-item> 14 <swiper-item> 15 <scroll-view style='height:100%' scroll-y> 16 <recommend />//引用首页组件 17 </scroll-view> 18 </swiper-item> 19</swiper> 20... 21 22

到这里,我们就完全实现了我们文章开始所展示的效果了,基本做到了和Android中的ViewPager相同的效果。

尾巴

下一篇微信小程序自定义下拉刷新,我将给大家带来自定义下拉刷新功能。如果文章中有错误的地方,欢迎大家留言指正。如果你喜欢我的文章,也欢迎给我点赞,评论,谢谢!

代码交流 2021