微信小程序自定义组件-城市选择「建议收藏」

微信小程序自定义组件-城市选择「建议收藏」微信小程序自定义组件-城市选择

大家好,又见面了,我是你们的朋友全栈君。

上篇文章有介绍一些小程序的自定义组件语法,这篇文章就不多做赘述,重点介绍组件的实现逻辑。

先把效果图贴出来,看看要实现的效果:

首先还是设置布局,从实现效果看,组件可分成三个部分:展示城市数据的二级列表、侧边的滑动栏以及中间的提示框。也就是一个scroll-view,一个view布局以及一个text。最终确定的wxml布局文件如下:

<scroll-view class='cityList' scroll-y scroll-into-view='{ 
    {currentIndex}}' scroll-top='{ 
    {scrollTop}}'>
     <view wx:for='{ 
    {allCities}}'>
          <view class='letter-class' id="id{ 
    {index}}">{
   
   {item.letter}}</view>
          <view class='item-class' wx:for='{ 
    {item.cityList}}' wx:for-item='cityItem' bindtap='citySelectEvent' data-city='{ 
    {cityItem.name}}' data-letter='{ 
    {cityItem.key}}'>{
   
   {cityItem.name}}</view>
     </view>
</scroll-view>

<view class='citySlide' catchtouchstart='slideStart' catchtouchmove='slideMove' catchtouchend='slideEnd'>
     <view class='citySlideItem' wx:for='{ 
    {allCities}}' data-index='{ 
    {index}}'>{
   
   {item.letter}}</view>
</view>

<text class='letterText' hidden='{ 
    {isLetterHidden}}' style='top:{ 
    {letterTop}}px;left:{ 
    {letterLeft}}px'>{
   
   {letterText}}</text>
复制代码

布局文件有了,我们就需要考虑该如何实现侧边栏与二级列表的联动效果了。这里我利用的是scroll-view的scroll-into-view属性,这个属性能让scroll-view滑动到对应id的view的位置,很符合我们的需求。

这里我们为列表的第一级布局view设置id,并为scroll-view设置scroll-into-view属性

<scroll-view class='cityList' scroll-y scroll-into-view='{ 
    {currentIndex}}' scroll-top='{ 
    {scrollTop}}'>
    .
    .
    .
//id不能以数字开头
<view class='letter-class' id="id{ 
    {index}}">{
   
   {item.letter}}</view>
复制代码

然后在.js中的data中初始化currentIndex为’id0′

/**
      * 组件的初始数据
      */
     data: {
          currentIndex: 'id0'
     }
复制代码

现在的问题就是如何计算出手指在侧边栏上触摸的是第几个letter,然后通过改变currentIndex的值,使scroll-view滑动到指定位置来达到联动的效果。

下面说下思路

首先确认侧边栏的高度,我是以屏幕高度减去80px作为侧边栏高度,在.wxss文件中通过样式设置。

.citySlide {
     display: flex;
     flex-direction: column;
     width: 60rpx;
     height: calc(100% - 80px);
     position: absolute;
     top: 40px;
     right: 16rpx;
     align-items: center;
     justify-content: center;
     background-color: #ccc;
     opacity: 0.6;
}
复制代码

然后在.js中通过把屏幕高度减去80px计算出侧边栏的具体高度。再除以数据源的一级数据数组长度,计算出每个letter的高度。

          wx.getSystemInfo({
               success: function (res) {
                    letterLineHeight = (res.windowHeight - 80) / that.data.allCities.length;
                    that.setData({
                         letterTop: res.windowHeight / 2 - 30,
                         letterLeft: res.windowWidth / 2 - 30
                    });
               }
          })
复制代码

计算出每个letter的高度后,我们就可以在侧边栏的触摸监听事件中,通过触摸的点的坐标位置,来计算出当前触摸的letter的序号index,然后再动态修改currentIndex的值为(‘id’+index)。就可以达到联动的效果了。

显示在屏幕中央的提示框的实现则比较简单,通过一个变量isLetterHidden控制text的显示与隐藏就可以轻松实现。

slideStart: function (e) {
   //手指触摸的y坐标值
   var touchY = e.touches[0].clientY;
   //布局距离屏幕顶端距离
   var offsetTop = e.currentTarget.offsetTop;
   var index = parseInt((touchY - offsetTop) / letterLineHeight);
   this.setData({
		currentIndex: 'id' + index,
		isLetterHidden: false,
		letterText: this.data.allCities[index].letter
   });
},

slideMove: function (e) {
   var touchY = e.touches[0].clientY;
   var offsetTop = e.currentTarget.offsetTop;
   var index = parseInt((touchY - offsetTop) / letterLineHeight);
   this.setData({
		currentIndex: 'id' + index,
		isLetterHidden: false,
		letterText: this.data.allCities[index].letter
   });
},

slideEnd: function (e) {
   var that = this;
   wx: setTimeout(function () {
		that.setData({
			 isLetterHidden: true
		});
   }, 200);
}
复制代码

这里有一点要注意,设置侧边栏触摸事件的时候,要选择catchtouchxxxx事件,不能使用bindtouchxxxx,因为bind事件不会阻止事件冒泡,这样手指在侧边栏滑动时,会影响到下方的列表的滑动,而catch事件阻止了事件冒泡,就不会出现滑动影响的问题。

再说下城市的数据源格式要求,要求是一个二维数组,然后子项要有name和key两个字段,分别代表城市名和类别letter。

项目GitHub地址:github.com/RaoMeng/Tem…

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107155.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • Normalized Mutual information

    Normalized Mutual information在写论文做数据测试时有用到一个nmi(normalizedmutualinformation)评价聚类的一种方法,不是很清楚,然后上网找了一下资料。首先在理解nmi前,先说说mutualinformation这个东西。我们先举个例子:比如说,标准结果是大圆里面的叉叉圈圈点点,上图呢是我们算法聚类出来的结果,那么如何来看我们算法的聚类效果呢,如何计算呢?我们把上图中的图形用字母来表示…

    2022年9月2日
  • WPF基础五:UI①布局元素WrapPanel[通俗易懂]

    WPF基础五:UI①布局元素WrapPanel[通俗易懂]目录WrapPanelWrapPanel类XAML范例:C#代码WrapPanel按从左到右的顺序位置定位子元素,在包含框的边缘处将内容切换到下一行。后续排序按照从上至下或从右至左的顺序进行,具体取决于Orientation属性的值。WrapPanel包含UIElement对象的集合,这些对象位于Children属性中。WrapPanel的所有子元素都接收ItemWidth与ItemHeight大小相乘的布局分区。WrapPanel类名称…

    2022年7月22日
  • Folium_个人基础信息介绍

    Folium_个人基础信息介绍folium基础内容介绍1.简介​ folium是js上著名的地理信息可视化库leafet.js为Python提供的接口,通过它,我们可以通过在Python端编写代码操纵数据,来调用leaflet的相关功能,基于内建的osm或自行获取的osm资源和地图原件进行地理信息内容的可视化,以及制作优美的可交互地图,是通过不断添加图层元素来定义一个Map对象,最后以几种方式将Map对象展现出来。​ 而在Map对象的生成形式上,可以在定义所有的图层内容之后,将其保存为html文件在浏览器中独立显示,也可以基于j

    2022年10月29日
  • 大数据教程(13.1)Flume使用

    大数据教程(13.1)Flume使用

    2021年6月30日
  • python产生随机数的方法_产生随机数的代码

    python产生随机数的方法_产生随机数的代码Python产生随机数:一.Python自带的random库1.参生n–m范围内的一个随机数:random.randint(n,m)2.产生0到1之间的浮点数:random.random()3.产生n—m之间的浮点数:random.uniform(1.1,5.4)4.产生从n—m间隔为k的整数:random.randrange(n,m,k)5.从序列中随机选取一个元素:random.choice([1,2,3,4,5,6,7

    2022年10月28日
  • QListWidget的QSS用法「建议收藏」

    QListWidget的QSS用法「建议收藏」本文完全是转载如下网址博客内容,如有侵权,请及时通知,博主会删除。原文地址:https://blog.csdn.net/u011125673/article/details/51753997QListWidget和QTableWidget的使用和属性,QTableWidget和QListWidget样式表的设置,滚动条的样式设置一、QListWidget的使用//一、QListWidgetli…

    2022年6月5日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号