Hippy-react框架中的WaterfallView组件

2021SC@SDUSC

Hippy-react中WaterfallView组件分析

  • 组件分析
    • WaterfallView:瀑布流组件
  • 小结:

组件分析

在上一篇blog中我们对Hippy-react中的image和list-view组件进行了分析,本次我们继续进行WaterfallView组件的分析。

WaterfallView:瀑布流组件

瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。

一、首先我们来看该组件中的参数和方法列表;

参数 作用
numberOfColumns 瀑布流中列的数量
numberOfItems 瀑布流中的item数量
contentInset 内容缩进
columnSpacing 列之间的距离
interItemSpacing item之间的垂直距离
preloadItemNumber 到达list末尾时要预先加载的item数量
containPullHeader 判断是否包含PullHeader组件
containPullFooter 判断是否包含Pullfooter组件
containBannerView 判断是否存在Banner视图
renderItem 传递数据并返回行组件。方法入参是当前 item 的 index,在这里可以凭借 index 获取到瀑布流一个具体单元格的数据,从而决定如何渲染这个单元格
renderBanner?() banner的渲染方式
renderPullHeader?() pullHeader的渲染方式
renderPullFooter?() pullFooter的渲染方式
getItemType?(index: number) 指定一个函数,在其中返回对应条目的类型,List 将对同类型条目进行复用,合理的类型拆分可以很好地提升list 性能
getItemStyle?(index: number) 设置WaterfallItem容器样式
getItemKey?(index: number) 指定一个函数,在其中返回对应条目的 Key 值
onEndReached?() 在所有的数据都已经渲染过,并且列表被滚动到最后一条时被调用
onItemLayout?(evt: LayoutEvent, index: number): void 在第一次布局或者布局改变时被调用
onScroll 在触发waterFall的滑动事件时被调用
onHeaderPulling? (): void; 当用户下拉 ListView 时调用
onHeaderReleased? (): void; 当用户释放拉取 WaterfallView 时调用
onFooterPulling? (): void; 当用户向上滑动 WaterfallView 以获取更多数据时调用
onFooterReleased? (): void; 当用户释放获取更多数据时调用
onInitialListReady? (): void; 在waterFall准备好时被调用

以上就是WaterFallView组件中的参数及函数情况,我们在进行开发时可以对照以上作用描述以便使用。

二、WaterfallView类的实现

1.其中关于滚动方法的实现:其中onScroll在触发滑动时被调用,scrollToIndex决定Waterfall滑动到第几个item,scrollToContentOffset控制的是具体滑动的坐标,二者都需要调用callUIFunction进行操作。
关于onScroll,我们先来看其声明代码:

  onScroll?(evt: {
    startEdgePos: number,
    endEdgePos: number,
    firstVisibleRowIndex: number,
    lastVisibleRowIndex: number,
    visibleRowFrames: Object
  }): void;

其中
startEdgePos表示距离 List 顶部边缘滚动偏移量;
endEdgePos表示距离 List 底部边缘滚动偏移量;
firstVisibleRowIndex表示当前可见区域内第一个元素的索引;
lastVisibleRowIndex表示当前可见区域内最后一个元素的索引;
visibleRowFrames表示当前可见区域内所有 item 的信息(x,y,width,height)

关于scrollToIndex以及scrollToContentOffset的代码如下:

public scrollToIndex({ index = 0, animated = true }) {
    callUIFunction(this.instance as Fiber, 'scrollToIndex', [index, index, animated]);
  }
public scrollToContentOffset({
    xOffset = 0,
    yOffset  = 0,
    animated = true,
  }) {
    callUIFunction(this.instance as Fiber, 'scrollToContentOffset', [xOffset, yOffset, animated]);
  }

2.WaterfallView类中通过一个方法实现了item和banner的渲染,以下为其代码:

public render() {
    const {
      style = {},
      renderBanner,
      numberOfColumns = 2,
      columnSpacing = 0,
      interItemSpacing = 0,
      numberOfItems = 0,
      preloadItemNumber = 0,
      renderItem,
      renderPullHeader,
      renderPullFooter,
      getItemType,
      getItemKey,
      getItemStyle,
      contentInset = { top: 0, left: 0, bottom: 0, right: 0 },
      onItemLayout,
      onHeaderPulling,
      onHeaderReleased,
      onFooterPulling,
      onFooterReleased,
      containPullHeader = false,
      containPullFooter = false,
      containBannerView = false,
      ...otherNativeProps
    } = this.props as WaterfallViewProps;

    const nativeProps = {
      ...otherNativeProps,
      style,
      numberOfColumns,
      columnSpacing,
      interItemSpacing,
      preloadItemNumber,
      contentInset,
      containPullHeader,
      containPullFooter,
      containBannerView,
    };
    const itemList = [];

    if (typeof renderBanner === 'function') {
      const banner = renderBanner();
      if (banner) {
        itemList.push((
          <View key="bannerView">
            {React.cloneElement(banner)}
          </View>
        ));
        nativeProps.containBannerView = true;
      }
    }

    if (typeof renderItem === 'function') {
      const pullHeader = this.getPullHeader(renderPullHeader, onHeaderPulling, onHeaderReleased);
      const pullFooter = this.getPullFooter(renderPullFooter, onFooterPulling, onFooterReleased);
      for (let index = 0; index < numberOfItems; index += 1) {
        const itemProps: WaterfallViewItemProps = {} as WaterfallViewItemProps;
        const rowChildren = renderItem(index) || null;
        this.handleRowProps(itemProps, index, { getItemKey, getItemStyle, getItemType, onItemLayout });
        if (rowChildren) {
          itemList.push((
            // @ts-ignore
            <WaterfallViewItem {...itemProps}>
              { rowChildren }
            </WaterfallViewItem>
          ));
        }
      }

      if (pullHeader) {
        itemList.unshift(pullHeader);
        nativeProps.containPullHeader = true;
      }

      if (pullFooter) {
        itemList.push(pullFooter);
        nativeProps.containPullFooter = true;
      }
      (nativeProps as WaterfallViewProps).style = {
        ...style,
      };
    } else {
      warn('Waterfall attribute [renderItem] is not Function');
    }

    return (
      // @ts-ignore
      <ul
        nativeName={'WaterfallView'}
        ref={ref => this.instance = ref}
        initialListReady={this.handleInitialListReady.bind(this)}
        {...nativeProps}
      >
        { itemList }
      </ul>
    );
  }

小结:

瀑布流是现在流行的一种布局方式,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。hippy-react中也通过WaterfallView类来实现这种布局方式,并且提供了各种方法调用来方便代码编写,为网页布局的实现提供了很大的便利。

你可能感兴趣的:(react.js)