学堂 学堂 学堂公众号手机端

如何制作滚动选择器,代码是什么

lewis 1年前 (2024-04-21) 阅读数 18 #技术
这篇文章给大家分享的是如何制作滚动选择器,代码是什么。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。




最近项目里有个需求要做个滚动选择器,在网上找了半天也没找到合适的demo,没办法只能发挥我的聪明才智创造一个,上代码。

js:

// pages/xuanzeqi/xuanzeqi.js
Page({

 /**
 * 页面的初始数据
 */
 data: {
  list: ['0分', '1分', '2分', '3分', '4分', '5分', '6分', '7分', '8分', '9分', '10分', '11分', '12分', '13分', '14分', '15分', '16分', '17分', '18分', '19分', '20分', '21分', '22分', '23分', '24分', '25分', '26分', '27分', '28分', '29分', '30分', '31分', '32分', '33分', '34分', '35分', '36分', '37分', '38分', '39分', '40分', '41分', '42分', '43分', '44分', '45分', '46分', '47分', '48分', '49分', '50分', '51分', '52分', '53分', '54分', '55分', '56分', '57分', '58分', '59分'],
  box_height: 0,//选择器的高度(非控制项,自动计算),单位px
  picker:{ //选择器的控制变量
   box_width: 200,//选择器宽度,单位px
   choose_item_height: 30,//选择器中每一项选项的高度,单位px
   choose_item_font_size:25,//选择器中每一项选项字体大小,单位px
   scroll_animation: true,//是否使用动画过渡
   choose_item_number: 13,//选择器内选项的个数(要求为单数)
   bgColor:'#01356f',//选择器的背景颜色
   choose_item_font_color:'white',//选择器选项的字体颜色
  },
  mid_item:0,
  scroll_into_view:'item_0',//滚动到选项的id
  item_height_list:[],//存储每一项距离顶端的y轴数据
  picker_value:null,//选择器的值
  opacity_list:[],//透明阶梯
  cover_list: [],//遮盖层属性列表
  touchY: -1,
  scrollTop:0,
 },
 touchMove: function (e) {
  let that = this
  let touY = e.touches[0].pageY;
  if(that.data.touchY == -1){
   that.data.touchY = touY
  } else{
   let cha = that.data.touchY - touY
   that.setData({
    scrollTop: that.data.scrollTop + cha
   })
   that.data.touchY = touY
  }
  if (that.coverEndTimer) {
   clearTimeout(that.coverEndTimer);
   that.coverEndTimer = null;
  }
  that.coverEndTimer = setTimeout(function () {
   that.data.touchY = -1
  }, 200);
 },
 //监听选择器滚动事件
 bindscrollevent:function(e){
  let that = this
  // that.flashOpacity(e.detail.scrollTop)
  console.log(e)
  if (that.scrollEndTimer) {
   clearTimeout(that.scrollEndTimer);
   that.scrollEndTimer = null;
  }
  that.scrollEndTimer = setTimeout(function () {
   console.log("滑动结束");
   // that.flashOpacity(e.detail.scrollTop)
   that.itemToMid(e.detail.scrollTop)
   that.data.scrollTop = e.detail.scrollTop
  }, 200);
 },
 //更新透明度
 flashOpacity:function(e){
  let that = this
 
  that.setData({
   item_height_list: that.data.item_height_list
  })
  for (let i in that.data.item_height_list) {
   if (that.data.item_height_list[i].bottom > e && that.data.item_height_list[i].top >= e) {
    for(let j = 0; j < that.data.opacity_list.length; j++){
     if(i - (j + 1) >= 0){
      that.data.item_height_list[i - (j + 1)].opacity = that.data.opacity_list[j]
     }
     let a = parseInt(i)
     if(a + (j + 1) < that.data.list.length){
      that.data.item_height_list[a + (j + 1)].opacity = that.data.opacity_list[j]
     }
    }
    let a = parseInt(i)
    for (let j in that.data.item_height_list) {
     if (!(j >= a - that.data.opacity_list.length && j <= a + that.data.opacity_list.length)){
      that.data.item_height_list[j].opacity = 0
     }
    }
    that.setData({
     item_height_list: that.data.item_height_list
    })
    break;
   }
  }
 },
 //根据滚动距离滚动到选项中间
 itemToMid:function(e){
  let that = this
  console.log("执行了",e)
  for (let i in that.data.item_height_list) {
   if (that.data.item_height_list[i].bottom > e && that.data.item_height_list[i].top <= e) {
    console.log(that.data.item_height_list[i].bottom, that.data.item_height_list[i].top)
    if (i < that.data.mid_item - 1) {
     that.setData({
      scroll_into_view: 'cushion_top_' + i
     })
    } else {
     console.log(parseInt(i) - that.data.mid_item + 1)
     that.setData({
      scroll_into_view: 'item_' + (parseInt(i) - that.data.mid_item + 1)
     })
    }
    that.setData({
     picker_value : that.data.list[i]
    })
    break;
   }
  }
 },
 //初始化
 init:function(e){
  let that = this
  //先计算该选择器的高度(根据每项高度和项目个数计算)单位px
  //如果选择器个数填写为双数,则强制-1变为单数
  if (that.data.picker.choose_item_number % 2 == 0){
   that.setData({
    ['picker.choose_item_number'] : that.data.picker.choose_item_number - 1
   })
  }
  //通过乘积计算选择器高度
  that.setData({
   box_height : that.data.picker.choose_item_number * that.data.picker.choose_item_height
  })
  //计算选择器中间项应该是第几项
  that.setData({
   mid_item : (that.data.picker.choose_item_number + 1) / 2
  })
  //初始化遮盖层透明阶梯透明度从(0.1到0.9)
  let unit = Math.round(80 / (that.data.mid_item - 1)) /**阶梯单元 */
  for(let i = 0; i < that.data.mid_item - 1; i++){
   that.data.opacity_list.push((80 - i * unit) / 100)
  }
  that.setData({
   opacity_list: that.data.opacity_list
  })
  //初始化遮盖层列表
  for(let i = 0; i < that.data.opacity_list.length; i++){
   let row = {opacity: that.data.opacity_list[i]}
   that.data.cover_list.push(row)
  }
  that.data.cover_list.push({ opacity: 0 })
  for(let i = 0; i < that.data.opacity_list.length; i++){
   let row = { opacity: that.data.opacity_list[that.data.opacity_list.length - 1 - i] }
   that.data.cover_list.push(row)
  }
  that.setData({
   cover_list: that.data.cover_list
  })
  //初始化选择器中每一项高度
  //初始化选项透明度,用于突出选中选项
  for(let i in that.data.list){
   let row = { top: 0, bottom: 0};
   // let topBase = (that.data.mid_item - 1) * that.data.picker.choose_item_height//顶端空白区域占用大小
   let topBase = 0
   row.top = topBase + i * that.data.picker.choose_item_height
   if(i == that.data.list.length - 1){
    row.bottom = topBase + (parseInt(i) + 1) * that.data.picker.choose_item_height + 100
   }else{
    row.bottom = topBase + (parseInt(i) + 1) * that.data.picker.choose_item_height
   }
   that.data.item_height_list.push(row)
   that.setData({
    item_height_list: that.data.item_height_list
   })
  }
 },
 /**
 * 生命周期函数--监听页面加载
 */
 onLoad: function (options) {
  let that = this
  that.init();
 },

 /**
 * 生命周期函数--监听页面初次渲染完成
 */
 onReady: function () {

 },

 /**
 * 生命周期函数--监听页面显示
 */
 onShow: function () {

 },

 /**
 * 生命周期函数--监听页面隐藏
 */
 onHide: function () {

 },

 /**
 * 生命周期函数--监听页面卸载
 */
 onUnload: function () {

 },

 /**
 * 页面相关事件处理函数--监听用户下拉动作
 */
 onPullDownRefresh: function () {

 },

 /**
 * 页面上拉触底事件的处理函数
 */
 onReachBottom: function () {

 },

 /**
 * 用户点击右上角分享
 */
 onShareAppMessage: function () {

 }
})

WXML:

<view class="box" style="height:{{box_height}}px;width:{{picker.box_width}}px;background:{{picker.bgColor}};">
 <scroll-view class="scroll_box" scroll-y="{{true}}" scroll-with-animation="{{picker.scroll_animation}}" bindscroll="bindscrollevent" scroll-into-view="{{scroll_into_view}}" scrollTop='{{scrollTop}}'>
  <view wx:for="{{mid_item - 1}}" class="cushion" style="height:{{picker.choose_item_height}}px;line-height:{{picker.choose_item_height}}px;font-size:{{picker.choose_item_font_size}}px;color:{{picker.bgColor}}" id="cushion_top_{{index}}">·</view>
  <view wx:for="{{list}}" class="choose_item" style="height:{{picker.choose_item_height}}px;line-height:{{picker.choose_item_height}}px;font-size:{{picker.choose_item_font_size}}px;color:{{picker.choose_item_font_color}}" id="item_{{index}}">{{item}}</view>
  <view wx:for="{{mid_item - 1}}" class="cushion" style="height:{{picker.choose_item_height}}px;line-height:{{picker.choose_item_height}}px;font-size:{{picker.choose_item_font_size}}px;color:{{picker.bgColor}};" id="cushion_bottom_{{index}}">·</view>
 </scroll-view>
 <!-- 透明度遮盖 -->
 <view style="position: fixed;top: 0;left: 70px;width:60px;z-index:9" bindtouchmove="touchMove" >
  <view wx:for='{{cover_list}}' style="height: {{picker.choose_item_height}}px;width: 100%;background: {{picker.bgColor}};opacity: {{item.opacity}}" ></view>
</view>
</view>
<view>{{picker_value}}</view>

wxss:

.box{
}
.scroll_box{
 height: 100%;
 width: 100%;
}
.choose_item{
 width: 100%;
 text-align: center;
}
.cushion{
 width: 100%;
 text-align: center;
}
.zhegai{
 height: 30px;
 width: 100%;
 position: absolute;
 top: 0;
 left: 0;
 background: #01356f;
 opacity: 0.9
}

效果图

需要修改选择器直接修改data中picker内属性即可。选项逐渐变浅的效果比较让人头疼,最初的做法是对list内每个选项都加一个属性代表该选项的透明度,每次滑动都会修改显示的选项透明度,但是实际使用起来发现给选项赋值透明度的过程非常明显,导致体验不好。最后采用了现在这种方法,在文字上加了一排遮盖的view,这些view有不同的透明度从而展示出来渐变的效果,省去了每次滑动都要给选项修改透明度的烦恼。


到此这篇关于“如何制作滚动选择器,代码是什么”的文章就介绍到这了,更多相关内容请搜索博信以前的文章或继续浏览下面的相关文章,希望大家以后多多支持博信!
版权声明

本文仅代表作者观点,不代表博信信息网立场。

热门