微信小程连串表渲染功效之列表下拉刷新及上拉加载的落到实处况势分析,上拉加载

微信小程序

下拉刷新 上拉加载,轻巧方便,易于上手。
1.首先上list.wxml代码

<!--pages/list/list.wxml-->
<view class="list-container">
  <view class="header">

  </view>
  <view class="doc-item"  wx:for="{{dataSource}}" wx:for-item="item" wx:key="{{item.id}}"  bindtap='bindViewTap' data-url="{{item.url}}" data-name="{{item.name}}">
    <text >{{item.title}}</text>
    <view class='item-info'>
      <text>{{item.author}}</text>
      <text style='float: right'>{{item.time}}</text>
    </view>
  </view>
  <view class="footer" wx:if="{{!hasMoreData}}">
    没有更多了
  </view>
  <view class="footer" wx:if="{{hasMoreData}}">
    加载中...
  </view>
</view>

2.再上js代码

// pages/list/list.js

Page({

  /**
   * 页面的初始数据
   */
  data: {
    id: "",
    dataSource: [],
    hasMoreData: true,
    pageIndex: 1,
    pageSize: 15,
    isLoading: false
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.setData({
      id: options.id//从url上获取id
    })
    wx.setNavigationBarTitle({title: options.nav})
    this.getList(1)
  },
  getList: function(index){
    wx.request({
      url: 'your server url',
      data: {
        method: 'your method',
        pageSize: this.data.pageSize,
        pageIndex: index,
      },
      header: {
        'content-type': 'application/json' // 默认值
      },
      success: (res) => {
        if(this.data.pageIndex == 1){
          wx.stopPullDownRefresh({
            complete: this.updateDom(res)
          })
        }else{
          this.updateDom(res)
        }

      }
    })
  },
  updateDom: function(res){
    this.setData({ dataSource: this.data.dataSource.concat(res.data.Data.List), isLoading: false })
    if (this.data.pageSize > res.data.Data.Length) {
      this.setData({ hasMoreData: false })
    }
  },

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

  },

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

  },

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

  },

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

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    if(!this.data.isLoading){
      this.setData({ hasMoreData: true, pageIndex: 1, dataSource: [], isLoading: true})
      this.getList(1)
    }

  },
  //事件处理函数
  bindViewTap: function (e) {
    //To do somethiing
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    if(this.data.hasMoreData && !this.data.isLoading){
      this.setData({ pageIndex: this.data.pageIndex + 1, isLoading: true})
      this.getList(this.data.pageIndex)
    }

  },

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


  }
})

3.简单的list.wxss

/* pages/list/list.wxss */
page{
  background-color: #E6E6E6;
}
.header{
  text-align: center;
  font-size: 14px;
  color: #aaa;
}
.footer{
  text-align: center;
  padding-top: 36rpx;
  padding-bottom: 48rpx;
  font-size: 14px;
  color: #aaa;
}
.doc-item{
  padding: 24rpx 36rpx;
  margin: 12rpx 0;
  display: flex;
  background: white;
  flex-direction: column;
  border-bottom: 1px solid #e3e3e3;
}
.item-info{
  padding-top: 24rpx;
  font-size: 14px;
  color: #aaa;
}

肆.list.json配备文件

{
  "enablePullDownRefresh": true,
  "backgroundTextStyle": "dark"
}

时现今天,一个简约的下拉刷新上拉加载基本解决了。巧用微信的各个Api,就很舒心。
接轨增添的话:
1.updateDom这里下拉刷新是归纳的清空重新加载,其实能够开始展览数组比较插入最新记录;
2.失误提示没加;
三.足以利用腾讯开源框架Wepy那种今世化的类Vue框架实行组件化开垦。

何以要动用组合的不二等秘书籍

Android下拉刷新和上拉加载的框架网上1度尤其多了,不过大多都供给继续自定义的下拉SwiperefreshLayout,只怕自定义recyclerview,
恐怕自定的adapter。首要有以下二种:

  1. 微信小程连串表渲染功效之列表下拉刷新及上拉加载的落到实处况势分析,上拉加载。无法不要持续自定义的xxRefreshLayout
    将下拉刷新控件及listview成套封装到1个控件里。
  2. 必须一而再自定义的xxListView。将上拉加载成效封装到自定义的listview或者RecyclerView里。
  3. 无法不继续小编自定义的Adapter

无论是哪一种本身都不甘于利用。作者或然有自身的下拉控件,也或者从来利用原生的的SwipeRefreshLayout(会有一部分定制修改)。列表部分固然半数以上场所下采用RecyclerView,可是有的地方也利用了ListView。至于Adapter,小编越发不会去继续了。相信我们都有协调的BaseAdapter,尽管盘锦小异,不过也有自作者作古和分化的地方,为了LoadMore去承接修改自身的BaseAdapter很倒霉。
比如小编的BaseAdapter封装了click事件,并基于DataBinding,连ViewHolder都省了。

从代码设计上思念,承接并不是很好的采纳,代码侵袭性太强。仍有趣的事先选用基础控件,除非是谷歌等老牌第3方库。那里自个儿更赞成于采用组合包装的诀要贯彻LoadMoreHelper。下拉控件恐怕是PtrFrameLayout也说不定是SwiperefreshLayout,
列表控件大概是ListView
也大概是RecyclerView,使用本人的BaseAdapater即可。LoadMoreHelper并不是自定义控件,而是通过数量Loader,对壹1零部件实行设置。而对此种种零部件来讲不须要依靠LoadMoreHelper

澳门葡京 1

load_more.png

</br>

正文实例讲述了微信小程连串表渲染功用之列表下拉刷新及上拉加载的兑现方式。分享给大家供大家参考,具体如下:

Weex
SDK中提供了下拉刷新和上拉加载的零部件,可是意义相比较单纯,不能够完毕跟手滑动操作,还会招致weex刷新和原生刷新不统1的难点,所以最佳的操作是扩充艺谋出原生的刷新组件。

下拉刷新与上拉加载进程分析

即使双方看起来很1般,可是依然有分别。①些控件将三种行为阴毒整合到一齐是不正好的。所以1般下拉刷新控件都不会提供上拉加载功效,需求用户本人去落到实处

下拉刷新和上拉加载是二种不一致的控件成效,不要混淆在协同。

当下最佳用的是谷歌的SwipeRefreshLayout,有的工程还用到了仿ios的PtrFrameLayout,就算该控件不再维护更新了,可是是或不是接纳是在乎开采者,LoadMoreHelper不做限定。下拉体制及处理滑动事件都以由下拉控件承担定制和处理,LoadMoreHelper不用关爱那个。

先看一下数目加载的大概流程:

澳门葡京 2

Pull_and_loadmore.png

固然下拉刷新和上拉加载在UI体验上分歧,可是其装载数据的长河却大都

下拉刷新load第2页数据,并替换当前全部list数据

上拉加载load大于第二页的多寡,并将加载的数据补充到当前list里

调用者必须完结数量加载接口,获取数据结果,并透过数量装载器公告UI变化。

  • 数量加载接口
    能够是1道,能够是异步。
    一齐数据加载接口SyncDataLoader直接再次来到数据结果,LoadMoreHelper会在后台线程调用该接口;
    异步数据加载接口AsyncDataLoader,在数据加载成功后的回调用LoadMoreHelper.onLoadEnd,文告数据结果

      /**
       * Load data sync. LoadHelper will call it on work thread
      */
       @WorkerThread
      public interface SyncDataLoader<VM> {
           PageData<VM> startLoadData(int page, PageData<VM> lastPageData);
      }
    
      /**
       * Load data int async thread
       */
      public interface AsyncDataLoader<VM> {
          void startLoadData(int page, PageData<VM> lastPageData);
      }
    

</br>

  • 数量结果PageData的定义,
    第3含有,一.pageIndex,当前页码,二. list,数据,3.
    pageMore,是还是不是还有下一页数据,四. result,是还是不是加载成功

      public final class PageData<DT> {
          private int pageIndex;
          private List<DT> data;
          private boolean pageMore;
          private boolean success = true;
      }
    
  • 数据装载接口
    数码装载的接口定义,IDataSwapper,在下拉刷新时调用swapData,
    在上拉加载时调用appendData。建议使用Adapter一而再该接口,当然也得以单独实现。

      public interface IDataSwapper<VM> {
          /**
          * Swap all datas
          */
          void swapData(List<? extends VM> list);
          /**
          * Append data to the end of current list
          */
          void appendData(List<? extends VM> list);
      }
    

微信小程序为二零一七年四月二十三日攻占了三个差别平时的竹签,神速刷爆了互联网和情侣圈,近年来自作者也写了三个demo程序体验壹把。微信小程序和vuejs有些像,都以数额驱动视图&单向数据绑定,而其体验要比H5页面好广大,那得益于微信环境的协助以及第1回运营时还要加载全体页面包车型大巴拍卖。本文将分享微信小程系列表的下拉刷新和上划加载的实行。

refresh零件是WeexSDK官方提供的,可是不佳在那一个组件内开始展览扩充,为了便利前端的应用和客户端的增添,最后在list组件的根底上进展扩张,因为差不多具备的基础代谢和加载都以基于list组件的。

行使装饰格局加上加载更多view

由于RecyclerView不能像ListView那样直接增多headerview可能footerview,要求团结在Adapter里福衢寿车。而那边大家又并不想一连该Adapter,使用装饰格局将调用者的Adapter包裹起来。那样对调用者来讲,只供给关怀自个儿的Adapter就可以,不须要关爱包装者。

大家先看一下Android原生的ListView是怎么着贯彻header和footer
在添加footer后,会将原adapter包装成HeaderViewListAdapter

    public void addFooterView(View v, Object data, boolean isSelectable) {
    ...
    // Wrap the adapter if it wasn't already wrapped.
    if (mAdapter != null) {
        if (!(mAdapter instanceof HeaderViewListAdapter)) {
            wrapHeaderListAdapterInternal();
        }
        ...
    }
}

public class HeaderViewListAdapter implements WrapperListAdapter, Filterable {
private final ListAdapter mAdapter;
...
}

参考该设计,类似的大家在增进RecyclerView的footerView时,也足以打包一个FooterAdapter

//包装origin adapter
RecyclerView.Adapter<VH> originAdapter = recyclerView.getAdapter();
footerAdapter = new FooterViewAdapter<>(originAdapter);
        recyclerView.setAdapter(footerAdapter);

FooterAdapter 会将原先的Adapter包装起来,并在尾巴部分增加 加载越多的view

    //FooterAdapter 继承于BaseWrapperAdapter
    public class FooterViewAdapter<VH extends RecyclerView.ViewHolder> extends BaseWrapperAdapter

    public class BaseWrapperAdapter<VH extends RecyclerView.ViewHolder>
    extends RecyclerView.Adapter<VH> {
     private RecyclerView.Adapter<VH> mWrappedAdapter;
     ...
     }

如此,便足以不需求用户继承LoadMoreHelperAdapter,又能在RecyclerView的末尾增添footerView。对于调用者来讲,那壹层完全是透明的,只必要根据在此之前的习惯调用原AdapternotifyDataSetChanged就能够,不要求关切包装者的存在。

效果图

iOS端

为了便利扩大,笔者采纳继续官方的WXListComponent类,先全体驾驭一下全套类中的代码

@interface MWSListComponent () 

@property (nonatomic, strong) MJRefreshGifHeader *refreshHeader;
@property (nonatomic, strong) MJRefreshAutoFooter *refreshFooter;
@property (nonatomic, assign) BOOL refresh;             /**< 是否开启下拉刷新 */
@property (nonatomic, assign) BOOL loading;             /**< 是否开启上拉加载 */
@property (nonatomic, assign) BOOL showLoading;         /**< 控制loading是否显示 */
@property (nonatomic, assign) BOOL refreshEvent;
@property (nonatomic, assign) BOOL loadingEvent;

@end

@implementation MWSListComponent

WX_EXPORT_METHOD(@selector(endRefreshing));
WX_EXPORT_METHOD(@selector(endLoading));
WX_EXPORT_METHOD(@selector(noticeNoMoreData));

- (void)dealloc
{
    _refreshFooter = nil;
    _refreshHeader = nil;
}

- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
{
    self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
    if (self) {
        _refresh = [WXConvert BOOL:attributes[@"refresh"]];
        _loading = [WXConvert BOOL:attributes[@"loading"]];
        _showLoading = [attributes.allKeys containsObject:@"showLoading"] ? [WXConvert BOOL:attributes[@"showLoading"]] : YES;
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self _updateRefreshHeader];
    [self _updateRefreshFooter];
    [self _updateLoadingState];
}


- (void)addEvent:(NSString *)eventName
{
    [super addEvent:eventName];
    if ([eventName isEqualToString:@"refresh"]) {
        _refreshEvent = YES;
    }
    if ([eventName isEqualToString:@"loading"]) {
        _loadingEvent = YES;
    }
}

- (void)removeEvent:(NSString *)eventName
{
    [super removeEvent:eventName];
    if ([eventName isEqualToString:@"refresh"]) {
        _refreshEvent = NO;
    }
    if ([eventName isEqualToString:@"loading"]) {
        _loadingEvent = NO;
    }
}

- (void)updateAttributes:(NSDictionary *)attributes
{
    [super updateAttributes:attributes];
    if ([attributes.allKeys containsObject:@"refresh"]) {
        _refresh = [WXConvert BOOL:attributes[@"refresh"]];
        [self _updateRefreshHeader];
    }
    if ([attributes.allKeys containsObject:@"loading"]) {
        _loading = [WXConvert BOOL:attributes[@"loading"]];
        [self _updateRefreshFooter];
    }
    if ([attributes.allKeys containsObject:@"showLoading"]) {
        _showLoading = [WXConvert BOOL:attributes[@"showLoading"]];
        [self _updateLoadingState];
    }
}

#pragma mark - Private Method
- (void)_addRefreshHeader
{
    if (!_refreshHeader) {
        __weak typeof(self) weakSelf = self;
        _refreshHeader = [MJRefreshGifHeader headerWithRefreshingBlock:^{
            [weakSelf refreshData];
        }];
        UIScrollView *scrollView = (UIScrollView *)self.view;
        scrollView.header = _refreshHeader;
    }
}

- (void)refreshData
{
    if (_refreshEvent) {
        [self fireEvent:@"refresh" params:nil];
    }
}

- (void)_removeRefreshHeader
{
    if (_refreshHeader) {
        UIScrollView *scrollView = (UIScrollView *)self.view;
        scrollView.header = nil;
        _refreshHeader = nil;
    }
}

- (void)_addRefreshFooter
{
    if (!_refreshFooter) {
        __weak typeof(self) weakSelf = self;
        _refreshFooter = [MDRefreshAutoFooter footerWithRefreshingBlock:^{
            [weakSelf loadingData];
        }];
        UIScrollView *scrollView = (UIScrollView *)self.view;
        scrollView.footer = _refreshFooter;
        [self _updateLoadingState];
    }
}

- (void)loadingData
{
    if (_loadingEvent) {
        [self fireEvent:@"loading" params:nil];
    }
}

- (void)_removeRefreshFooter
{
    if (_refreshFooter) {
        UIScrollView *scrollView = (UIScrollView *)self.view;
        scrollView.footer = nil;
        _refreshFooter = nil;
    }
}

- (void)_updateRefreshHeader
{
    if (_refresh) {
        [self _addRefreshHeader];
    }
    else {
        [self _removeRefreshHeader];
    }
}

- (void)_updateRefreshFooter
{
    if (_loading) {
        [self _addRefreshFooter];
    }
    else {
        [self _removeRefreshFooter];
    }
}

- (void)_updateLoadingState
{
    self.refreshFooter.hidden = !_showLoading;
}

#pragma mark - JS call method
- (void)endRefreshing
{
    if (_refreshHeader) {
        UIScrollView *scrollView = (UIScrollView *)self.view;
        [scrollView.header endRefreshing];
        [UIView animateWithDuration:0.4 animations:^{ [(UIScrollView *)self.view setContentOffset:CGPointZero]; }];
    }
}

- (void)endLoading
{
    if (_refreshFooter) {
        UIScrollView *scrollView = (UIScrollView *)self.view;
        [scrollView.footer endRefreshing];
        scrollView.footer.hidden = YES;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            scrollView.footer.hidden = NO;
        });
    }
}

- (void)noticeNoMoreData
{
    if (_refreshFooter) {
        UIScrollView *scrollView = (UIScrollView *)self.view;
        [scrollView.footer noticeNoMoreData];
    }
}

@end

refresh {boolean}: 可选值为true/false,默认是false。此值决定 list
是还是不是展开下拉刷新功效。

loading {boolean}:可选值为true/false,默认是false。此值决定 list
是或不是打开上拉加载成效。

下拉刷新的时候,会接触list组件的refresh艺术,上拉加载的时候,会触发list组件的loading主意。当数码重回的时候,我们须要手动去关闭刷新也许加载,因为数量几时回来只有weex端才领悟,所以扩张了一下多少个情势:

WX_EXPORT_METHOD(@selector(endRefreshing));    // 停止刷新

- (void)endRefreshing
{
   if (_refreshHeader) {
       UIScrollView *scrollView = (UIScrollView *)self.view;
       [scrollView.header endRefreshing];
       // weex在调用停止刷新后,scroll并不会回到顶部,需要我们手动进行设置一下。
       [UIView animateWithDuration:0.4 animations:^{ [(UIScrollView *)self.view setContentOffset:CGPointZero]; }];
   }
}

WX_EXPORT_METHOD(@selector(endLoading));    // 停止上拉加载

- (void)endLoading
{
    if (_refreshFooter) {
        UIScrollView *scrollView = (UIScrollView *)self.view;
        [scrollView.footer endRefreshing];
        scrollView.footer.hidden = YES;
        // 此处的处理因为数据返回时候,weex的render需要一定的时间,所有绝大部分时候,是先看到footer,然后cell才会一个一个进行渲染,所以此处先隐藏footer,0.25s之后再显示
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            scrollView.footer.hidden = NO;
        });
    }
}

当未有越来越多多少的时候,大家得以调用这么些格局开展设置

WX_EXPORT_METHOD(@selector(noticeNoMoreData));  // 提示没有更多数据了

- (void)noticeNoMoreData
{
    if (_refreshFooter) {
        UIScrollView *scrollView = (UIScrollView *)self.view;
        [scrollView.footer noticeNoMoreData];
    }
}

LoadMoreHelper调用情势

布局文件使用原生的控件就可以。个中SwipeRefreshLayout可替换来PtrFrameLayout,RecyclerView可替换来ListView.

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>

Api选取链式调用。推荐应用lambda表明式使代码更简短。

  1. 先是设置swipeRefreshLayout,会活动要求包涵的RecyclerView
    固然不需求下拉刷新只用上拉加载的话,能够直接设置RecyclerView。在LoadMoreHelper当中,会基于传入的view举办设置,设置RecyclerView的滑行监听,包装Adapter等。

         loadHelper = LoadMoreHelper.create(swipeRefreshLayout)
             .setDataSwapper(adapter)
             .setAsyncDataLoader((page, lastPageData) -> doLoadData(page))
             .startPullData(true);
    
  2. 设置IDataSwapper澳门葡京 ,。这里Adapter实现了IDataSwapper接口。当然能够不行使Adapter承袭而独自完结该接口,具体可参见工程里的例证。

    private class MyAdapter2 extends
    RecyclerView.Adapter<ViewHolder2> implements
    IDataSwapper<Item> {

    @Override
    public void swapData(List<? extends Item> list) {
    datas.clear();
    datas.addAll(list);
    notifyDataSetChanged();
    }

     @Override
     public void appendData(List<? extends Item> list) {
         if (list == null || list.isEmpty()) {
             return;
         }
         int start = datas.size();
         datas.addAll(list);
         notifyItemRangeInserted(start, list.size());
     }
    

    }

  3. 设置AsyncDataLoader
    采取异步数据加载,那里的loadData使用了Rxjava做例子。LoadMoreHelper会在下拉刷新只怕上拉加载时调用
    startLoadData。文告当前所需数据的页码,调用者只需填充加载方法,并将数据加载结果通过onLoadEnd传入。

         new LoadMoreHelper.AsyncDataLoader<Item>(){
         @Override
         public void startLoadData(int page, PageData lastPageData) {
             DataLoader.loadData(pageIndex, null)
                     .subscribeOn(Schedulers.io())
                     .observeOn(AndroidSchedulers.mainThread())
                     .subscribe(result -> {
                         PageData<Item> pageData = PageData.createSuccess(pageIndex, result.getData(), result.isPageMore());
                         loadHelper.onLoadEnd(pageData);
                     }, e -> {
                         PageData<Item> pageData = PageData.createFailed(pageIndex);
                         loadHelper.onLoadEnd(pageData);
                     });
         }
     };
    

LoadMoreHelper也提供了1部分其它接口能够安装加载更加多viewsetLoadMoreViewCreator,加载战败viewsetLoadFailedViewCreator,加载完结viewsetLoadCompleteViewCreator。页面数据加载战败后方可点击重试。

代码见
https://github.com/liyuanhust/LoadMoreHelper

先是来探望程序效果图,以下肆张图从左至右依次是:下来刷新动画、下拉刷新结果、上划加载动画以及上划加载结果,程序中的数据均为模拟数据,不分包网络请求,所以能够直接运转。

前端

在设置样式的模块代码如下

<template>
    <div>
        <list 
          ref="list"
          refresh="true"
          @refresh="_refreshData"
          loading="true"
          @loading="_loadingData"
        >
        </list>
    </div>
</template>

ref为了获得list组件,上述代码开启了上拉加载和下拉刷新的效应,下边是script模块的代码

<script>
export default {
    methods: {
        _refreshData() {
            this._fetchData(true)
        },
        _loadingData() {
            this._fetchData(false)
        },
        _fetchData(isRefresh) {
            // 请求数据,结束后
            if (_platform==='iOS') {
                let list = this.$refs.list;
                if (list) {
                    if (isRefresh) {
                        list.endRefreshing();
                    }
                    if (this.noMoreData) {
                        list.noticeNoMoreData();
                    } else {
                        list.endLoading();  
                    }
                }
            }
        }
    }
}
</script>

透过上述操作,就可以将原生的代码桥接到weex中选拔啊。

澳门葡京 3

措施一:用scroll-view组件落成

鉴于最终未有接纳那种达成格局(下拉刷新有bug),由此只做简要介绍,当然要是没有下拉刷新的必要,scroll-view组件完毕列表的渲染很便宜,从合法文书档案可以看到,scroll-view组件集成了以下办法为编制程序提供极大方便。

scroll-into-view String
值应为某子成分id,则滚动到该因素,成分顶部对齐滚动区域顶部
bindscrolltoupper 伊芙ntHandle
滚动到顶部/左侧,会触发 scrolltoupper
事件
bindscrolltolower 伊夫ntHandle
滚动到底层/左侧,会触发 scrolltolower
事件
bindscroll 伊芙ntHandle 滚动时触发
event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY}

格局2:用page页面自带的效应

Page() 函数用来注册二个页面。接受1个 object
参数,其钦点页面的发端数据、生命周期函数、事件处理函数等。

1、在app.json页设置窗口前景象为dark & 允许下拉

"window":{
  "backgroundTextStyle":"dark",
  "navigationBarBackgroundColor": "#000",
  "navigationBarTitleText": "wechat",
  "navigationBarTextStyle":"white",
  "enablePullDownRefresh": true
}

二、在list.json页设置允许下拉

{
  "enablePullDownRefresh": true
}

三、利用onPullDownRefresh监听用户下拉动作

注:在滚动 scroll-view 时会阻止页面回弹,所以在 scroll-view
中滚动不可能触发onPullDownRefresh,因此在运用 scroll-view
组件时不知所可利用page的该性子。

onPullDownRefresh: function() {
 wx.showNavigationBarLoading() //在标题栏中显示加载
 let newwords = [{message: '从天而降',viewid:'-1',time:util.formatTime(new Date),greeting:'hello'}].concat(this.data.words);
 setTimeout( ()=> {
   this.setData({
     words: newwords
   })
   wx.hideNavigationBarLoading() //完成停止加载
   wx.stopPullDownRefresh() //停止下拉刷新
  }, 2000)
}

4、利用onReachBottom页面上拉触底事件

注:,第三遍进入页面,如若页面不满一屏时会触发 onReachBottom
,应为唯有用户主动上拉才触发;手指上拉,会接触多次onReachBottom,应为一次上拉,只触发二遍;所以在编程时要求将那两点思虑在内。

onReachBottom:function(){
  console.log('hi')
  if (this.data.loading) return;
  this.setData({ loading: true });
  updateRefreshIcon.call(this);
  var words = this.data.words.concat([{message: '土生土长',viewid:'0',time:util.formatTime(new Date),greeting:'hello'}]);
  setTimeout( () =>{
    this.setData({
     loading: false,
     words: words
    })
  }, 2000)
 }
})

五、上划加载Logo动画

/**
 * 旋转刷新图标
 */
function updateRefreshIcon() {
 var deg = 0;
 console.log('旋转开始了.....')
 var animation = wx.createAnimation({
  duration: 1000
 });
 var timer = setInterval( ()=> {
  if (!this.data.loading)
   clearInterval(timer);
  animation.rotateZ(deg).step();//在Z轴旋转一个deg角度
  deg += 360;
  this.setData({
   refreshAnimation: animation.export()
  })
 }, 2000);
}

最终附上布局代码:

<view wx:for="{{words}}" class="item-container">
  <view class="items">
    <view class="left">
       <view class="msg">{{item.message}}</view>
       <view class="time">{{item.time}}</view>
    </view>
    <view class="right">{{item.greeting}}</view>
  </view>
</view>
<view class="refresh-block" wx:if="{{loading}}">
 <image animation="{{refreshAnimation}}" src="../../resources/refresh.png"></image>
</view>

期待本文所述对大家微信小程序设计具有扶助。

你大概感兴趣的作品:

  • 微信小程序实现下拉刷新和轮播图效果
  • 微信小程序
    刷新上拉下拉不会断详细介绍
  • 微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(二)
  • 微信小程序上海好笑剧团加载下拉刷新(onscrollLower)分批加载数据(一)
  • 微信小程序列表的上拉加载和下拉刷新的落到实处
  • 微信小程序
    scroll-view实现上拉加载与下拉刷新的实例
  • 微信小程序
    详解下拉加载与上拉刷新达成格局
  • 微信小程序(6):列表上拉加载下拉刷新示例
  • 详解微信小程序开荒之下拉刷新
    上拉加载
  • 微信小程序完结列表下拉刷新上拉加载

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website