微信小程序直播间实现下拉刷新(目前全网最优最美观的方法)

微信小程序直播间实现下拉刷新
先上效果:
1.下拉距离一定时出现动画,保持下拉直到距离足够大时触发函数加载直播间列表,而且在足够大距离时会有振动反馈,增强用户体验
在这里插入图片描述
2.下拉小距离出现动画,此时释放不会触发函数加载直播间
在这里插入图片描述
3.左滑右滑触发函数加载直播间列表
在这里插入图片描述
4.点击tab对应分栏触发函数加载直播间列表在这里插入图片描述
感谢两位博主对这篇文章代码的贡献
1.动画部分引用:《微信小程序中使用Animation实现简约Loading效果》链接在此
2.《微信小程序 监听手势滑动切换页面》
下面是具体实现方法:链接在此
1.index.wxml


<view class='main'>
  <view class='tab'>
    <view bindtap='tabFun' data-index="{{1}}">
      <text class='{{tabIndex==1?"active":""}}'>直播中</text>
    </view>
    <view bindtap='tabFun' data-index="2">
      <text class='{{tabIndex==2?"active":""}}'>未开始</text>
    </view>
    <view bindtap='tabFun' data-index="3">
      <text class='{{tabIndex==3?"active":""}}'>已结束</text>
    </view>
    <view bindtap='tabFun' data-index="4">
      <text class='{{tabIndex==4?"active":""}}'>其它</text>
    </view>
  </view>
 <!-- 手指拖动的距离,实现scroll-view的拖拽效果 >
  <view style="height:{{touchMoveHeight}}px;">
  </view-->
  
 
   <scroll-view class='list' scroll-y bindscroll="bindscroll" bindtouchstart="touchStart" bindtouchend="touchEnd" bindtouchmove="touchMove">
 <!--view class="container" style="height:{{touchMoveHeight/2}}px;"-->
  <view class="loading" wx:if="{{show}}">
  <view class="dot" animation="{{alpha[0]}}"></view>
  <view class="dot" animation="{{alpha[1]}}"></view>
  <view class="dot" animation="{{alpha[2]}}"></view>
  <view class="dot" animation="{{alpha[3]}}"></view>
  <view class="dot" animation="{{alpha[4]}}"></view>
</view>
<!--/view-->
      <view class='item' wx:if="{{!isEdit}}" wx:for="{{listcf[tabIndex-1]}}">
     
      <navigator class='content' hover-class="none"  url="plugin-private://wx2b03c6e691cd7370/pages/live-player-plugin?room_id={{item.roomid}}">
        <view class='text' wx:if="{{item.start_YMD==item.end_YMD}}">
          <view class='title'>{{item.start_YMD}}</view>
          <view class='title'>{{item.start_hms}} - {{item.end_hms}}</view>
           
        </view>
        <view class='text' wx:else>
          <view class='title'>{{item.start_YMD}}</view>
          <view class='title'>{{item.start_hms}}</view>
           <view class='title'>-</view>
           <view class='title'>{{item.end_YMD}}</view>
          <view class='title'>{{item.end_hms}}</view>
        </view>
        <image src='{{item.share_img}}' mode="aspectFill" class="share_img"></image>
        <view class='text' >
          <view class='name'>{{item.name}}</view>
          <view class='spec'>{{item.creat_date}}</view>
          <view class='roomid'>
            <text>房间号   {{item.roomid}}</text>
          </view>
          <view class='anchor_name'>
            <text>主播   {{item.anchor_name}}</text>
          </view>
        </view>
      </navigator>
</view>

  </scroll-view>
  
</view>
	

2.index.wxss

/* pages/live/index.wxss */

.main{
  height: 100vh;
}

.tab{
  height: 7vh;
  display: flex;
  line-height: 7vh;
}

.tab view{
  flex: 1 0 auto;
  font-size: 14px;
  color: #333333;
  text-align: center;
}
.tab .active{
  color: #ff5f19;
  border-bottom: 1px solid #ff5f19;
  padding-bottom:1.8vh;
}

.list{
  
  background-color: #fff;
  height:93vh;
}

.list .item{
  display: flex;
  border-bottom: 1px solid #EDEDED;
  padding: 0 16px;
  height:120px;
  align-items: center;
}

.list .label{
  flex: 0 0 auto;
  padding:10px 0;
}

.list .content{
  flex-grow: 1;
  display:flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.list .content image{
  flex: 0 0 auto;
 height: 76px;
  width: 250rpx;
  padding:20rpx;
}

.list .content .text{
  flex-grow: 1;
  font-size: 14px;
  width:210rpx;
}
.list .content .name{
  flex-grow: 1;
  font-size: 16px;
  
  font-weight: bold;
  
  text-overflow: -o-ellipsis-lastline;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  align-content: center;
}

.list .content .title{
  overflow: hidden;
  text-align: center;
}

.list .content .spec{
  font-size: 12px;
  color: #333333;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  line-height: 20px;    
  max-height: 20px;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

.list .content .roomid,.list .content .anchor_name{
  display: flex;
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  line-height: 20px;    
  max-height: 20px;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

.list .content .roomid text:nth-child(1),.list .content .anchor_name text:nth-child(1){
  color: #fbb8ac;
  flex: 1 0 50%;
}

.list .content .price text:nth-child(2){
  color: #999999;
  flex: 1 0 50%;
  text-align: right;
}
 
.data-loading {
  height: 100rpx;
  line-height: 100rpx;
  background-color: #eee;
  text-align: center;
  font-size: 14px;
}
.container {
  height:40rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 0;
  box-sizing: border-box;
} 
/** loading.wxss **/
.loading {
  width: 100%;
  position: absolute;
  /*bottom: 150rpx;*/
  top:0 vh;
  justify-content: center;
  text-align: center;
}
 
.loading .dot{
  background-color: rgb(172, 7, 7);
  display: inline-block;
  /**圆点大小在这里设置,高宽一致,圆角值为高宽的一半**/
  width: 16rpx;
  height: 16rpx;
  border-radius: 8rpx;
  margin: 0 10rpx;
  opacity: 0;
}

3.index.js

// pages/coupon/index.js

const app = getApp();
var util = require("../../utils/util.js");
var touchDot = 0;//触摸时的原点
var time = 0;// 时间记录,用于滑动时且时间小于1s则执行左右滑动
var interval = "";// 记录/清理时间记录
Page({

  /**
   * 页面的初始数据
   */
  data: {
    tabIndex: 1,
    list: [],
    listcf:{},
   /**
     * 用于控制当 scroll-view 滚动到底部时,显示 “数据加载中...” 的提示
     */
    hidden: true,
    /**
     * 用于显示文章的数组
     */
    articles: [],
    /**
     * 数据是否正在加载中,避免用户瞬间多次下滑到底部,发生多次数据加载事件
     */
    loadingData: false,
    switchtab:false,
    //是否触发下拉刷新
    isTop: true,//是否在顶部
    touchStartY: 0,//刚触碰屏幕时 距离顶部的距离
    touchMoveHeight: 0, //触碰屏幕时 手指移动的距离
    scrolltoupper: false,//判断是否正在下拉刷新
    scrolltolower: false,//判断是否正在上拉加载
    maxtouchMoveHeight:120,
    refreshtext:"下拉刷新",
    show:false,
    alpha: [1,1,1,1,1],
    timer:'',
    Isdraged:false,
    Isvibrate:false,
  },
  tabFun(e) {
    var that=this;
    that.setData({
      tabIndex: e.currentTarget.dataset.index
    })
    wx.showLoading({
      title: '加载中'
    });
    that.getList(() => {
      that.setData({
        scrolltoupper: false,
        scrolltolower: false,
        touchMoveHeight: 0,
      })
      wx.hideLoading();});
      //console.log("test")
   // this.getList()
  },
  getList:function(callback){
    var that=this;
    
    wx.request({
      url:'https://vircom.top/api/getliverooms.php',//改成你自己的链接
      header:{
      'Content-Type':'application/x-www-form-urlencoded'
      },
      data:{
        //id:app.globalData.openid,
        
      },
      method:'GET',
      success:function(res){
        //console.log(res.data);
        that.setData({
          list:res.data.liverooms,
        });
        var list=that.data.list;
        var list1=[];
        var list2=[];
        var list3=[];
        var list4=[];
        var listcf={};
        //console.log(list.length);
        for(let i=0;i<list.length;i++){
          //console.log(list[i].live_status);
          list[i].start_YMD=util.formatTime(list[i].start_time,'Y/M/D');
          list[i].start_hms=util.formatTime(list[i].start_time,'h:m');
          list[i].end_YMD=util.formatTime(list[i].end_time,'Y/M/D');
          list[i].end_hms=util.formatTime(list[i].end_time,'h:m');
          switch(list[i].live_status){
            case "101":{
              list1.push(list[i]);
            }break;
            case "102":{
              list2.push(list[i]);
            }break;
            case "103":{
              list3.push(list[i]);
            }break;
            default:{
              list4.push(list[i]);
            }break;
          }

        }
        listcf[0]=list1;
        listcf[1]=list2;
        listcf[2]=list3;
        listcf[3]=list4;
        that.setData({
         listcf:listcf
        })
        if(callback){
          callback();
        }
       },
      fail:function(res){
      console.log(res.data)
      }
      });

 
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.setData({
      tabIndex: options.type||1
    })
    this.getList();
   // let self = this;
  
    //var sjc = 1592637818;
    //console.log(util.formatTime(sjc,'Y/M/D h:m:s'));
   // console.log(util.formatTime(sjc, 'h:m'));

   
  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },
  upper:function(e){
    console.log(e);
   
    this.getList()
  },
  /**
   * 上滑加载更多
   */
  scrollToUpper: function(e) {
    console.info('scrollToLower', e);
    var hidden = this.data.hidden,
      loadingData = this.data.loadingData,
      that = this;
    if (hidden) {
      this.setData({
        hidden: false
      });
      console.info(this.data.hidden);
    }
    if (loadingData) {
      return;
    }
    this.setData({
      loadingData: true
    });
    // 加载数据,模拟耗时操作
 
    wx.showLoading({
      title: '数据加载中...',
    });
 
    setTimeout(function() {
      that.getList( () => {
        that.setData({
          hidden: true,
          loadingData: false
        });
        wx.hideLoading();
      });
      console.info('上拉数据加载完成.');
    }, 2000);
  },
  scrollToLower: function(e) {
    wx.showToast({
      title: '触顶了...',
    })
  },
  bindscroll: function (e) {
    //console.log(e)
    let self = this;
    self.setData({
      isTop: false
    })
  },
    // 触摸开始事件
    touchStart: function (e) {
    
    let self = this;
    self.setData({
      touchStartY: e.changedTouches[0].pageY,
      isTop: true
    });
    touchDot = e.touches[0].pageX; // 获取触摸时的原点
      // 使用js计时器记录时间  
   /*   interval = setInterval(function () {
        time++;
      }, 100);*/
      //console.log(e)
    },
    // 触摸移动事件
    touchMove: function (e) {
      var that=this;
      let touchStartY = that.data.touchStartY;
      let touchMoveY = e.changedTouches[0].pageY;
      let touchMoveHeight=touchMoveY - touchStartY;
   
      that.setData({
        touchMoveHeight: touchMoveY - touchStartY
      })
      if ((touchMoveHeight>20)&& that.data.isTop&&(!that.data.Isdraged)){
        that.anniu();
        that.setData({
          show:true,
        })
      }
      if(touchMoveHeight<that.data.maxtouchMoveHeight){
        that.setData({
          Isvibrate:false
        })
      }
      if ((touchMoveHeight>=that.data.maxtouchMoveHeight)&& that.data.isTop&&(!that.data.Isvibrate)) {
wx.vibrateShort({
  complete: (res) => {
    that.setData({
      Isvibrate:true,
    })
  },
})
      }
      var touchMove = e.touches[0].pageX;
     // console.log("touchMove:" + touchMove + " touchDot:" + touchDot + " diff:" + (touchMove - touchDot));
      // 向左滑动  
      if (((touchMove - touchDot) <= -80) &&(!that.data.switchtab)) {
that.setData({
  switchtab:true,
});
        var tabIndex=that.data.tabIndex;
       if(tabIndex<4){
         tabIndex++;
         that.setData({
           tabIndex:tabIndex
         })
       }
       wx.showLoading({
        title: '加载中'
      });
      that.getList(() => {
        that.setData({
          scrolltoupper: false,
          scrolltolower: false,
          touchMoveHeight: 0,
        })
        wx.hideLoading();});
      }
      // 向右滑动
      if (((touchMove - touchDot )>= 80)&& (!that.data.switchtab)) {
        console.log('向右滑动');
        that.setData({
          switchtab:true
        })
       var tabIndex=that.data.tabIndex;
       if(tabIndex>1){
         tabIndex--;
         that.setData({
           tabIndex:tabIndex
         })
       }
       wx.showLoading({
        title: '加载中'
      });
      that.getList(() => {
        that.setData({
          scrolltoupper: false,
          scrolltolower: false,
          touchMoveHeight: 0,
        })
        wx.hideLoading();});

      }
    },
    // 触摸结束事件
    touchEnd: function (e) {
    
      let self = this;
      self.setData({
        show:false,
        Isdraged:false,
        Isvibrate:false,
      })
      clearInterval(self.data.timer);
      let isTop = self.data.isTop;
      let touchStartY = self.data.touchStartY;
      let touchEndY = e.changedTouches[0].pageY;
      //console.log(isTop)
      //console.log(touchStartY)
      //console.log(touchEndY)
      if (touchEndY > touchStartY && isTop&&(self.data.touchMoveHeight>=self.data.maxtouchMoveHeight)) {
        self.setData({
          scrolltoupper: true,
          scrolltolower: true,
          touchMoveHeight: 120
        })
        self.myPullDownRefresh();
      }else{
        self.setData({
          touchMoveHeight:0
        })
      }
     // clearInterval(interval); // 清除setInterval
      time = 0;
      self.setData(
        {
          switchtab:false,
        }
      )
    },
    myPullDownRefresh: function () {
      let self = this;
      //console.log("begin")
      
      var scrolltoupper = self.data.scrolltoupper;
      if (scrolltoupper){
        
        
        wx.showLoading({
          title: '加载中'
        });
        self.getList(() => {
          self.setData({
            scrolltoupper: false,
            scrolltolower: false,
            touchMoveHeight: 0,
            

          })
          wx.hideLoading();
         
          /*wx.showToast({
            title: '刷新成功',
            icon:'success',
            duration:2000
          })*/
        });
        
        //定时器为了模仿实际开发中请求数据过程  使加载效果看起来好一些,
  
      }
    },
    anniu: function (e) {
      var self = this;
      var _index = 0;
      var _alpha = self.data.alpha;
      var _speed = 500;
      self.setData({
        timer:setInterval(function () {
          var an_show = wx.createAnimation({});
          var an_hide = wx.createAnimation({});
          an_show.opacity(1).step({ duration: _speed });
          an_hide.opacity(0).step({ duration: _speed });
          _alpha[_index] = an_show;
          _alpha[_index == 0 ? 4 : _index - 1] = an_hide;
          self.setData({
            alpha: _alpha
          })
          _index = _index == 4 ? 0 : _index + 1;
        }, _speed)
      })
      /*var timer = setInterval(function () {
        var an_show = wx.createAnimation({});
        var an_hide = wx.createAnimation({});
        an_show.opacity(1).step({ duration: _speed });
        an_hide.opacity(0).step({ duration: _speed });
        _alpha[_index] = an_show;
        _alpha[_index == 0 ? 4 : _index - 1] = an_hide;
        self.setData({
          alpha: _alpha
        })
        _index = _index == 4 ? 0 : _index + 1;
      }, _speed);*/
    },
})

4.index.json

{
  "navigationBarTitleText": "直播间"
  
}

5.在utils文件夹中的util.js(用于直播间获取时间戳,在自己的项目中不用的话可以在index.js中删掉这句var util = require("…/…/utils/util.js");不引用即可)

//数据转化
function formatNumber(n) {
  n = n.toString()
  return n[1] ? n : '0' + n
}
 
/**
 * 时间戳转化为年 月 日 时 分 秒
 * number: 传入时间戳
 * format:返回格式,支持自定义,但参数必须与formateArr里保持一致
*/
function formatTime(number,format) {
 
  var formateArr  = ['Y','M','D','h','m','s'];
  var returnArr   = [];
 
  var date = new Date(number * 1000);
  returnArr.push(date.getFullYear());
  returnArr.push(parseInt(formatNumber(date.getMonth() + 1)));
  returnArr.push(formatNumber(date.getDate()));
 
  returnArr.push(formatNumber(date.getHours()));
  returnArr.push(formatNumber(date.getMinutes()));
  returnArr.push(formatNumber(date.getSeconds()));
 
  for (var i in returnArr)
  {
    format = format.replace(formateArr[i], returnArr[i]);
  }
  return format;
}
module.exports = {
  formatTime: formatTime
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值