GroupList 3.0.0

分组列表组件,继承了List的大部分特性。

为列表数据提供分组展示形式,每个组有一个标题,在滚动时当前组的标题有吸顶效果。

同样支持无穷模式(指定高度和未知高度)。

提供分组导航(参考常见的字母导航),但是不定高的无穷列表模式无法使用。

使用说明

引用方式

import { GroupList } from '$yo-component';

// 如果你的项目中未使用最新的 ykit-config-yo 插件,可能无法使用上面这个语法糖
// 你仍然可以通过下面这种方式来引用
import GroupList from 'yo3/component/grouplist';

基础使用

GroupList是一个定制化的 List,它会把 ListdataSource 中的元素进行分组展示,并且给每一组添加一个组标题。 因此它的 dataSourceList 中的稍有不同,你需要给每一个元素指定一个 groupKey,这是一个必须添加的属性:

let guid = -1;
// ...

<GroupList
  dataSource={[
    {text: '北京', key:++guid, groupKey:'B'},
    {text: '上海', key:++guid, groupKey:'S'},
    // ...
  ]}
  sort={(a,b) => { //return a positive or negative number... }}
  // ...
/>

如果设置 groupKeynotGrouped ,那么这些元素组成的组没有标题,并且会放置在所有分组的上方。使用 sort 属性可以给分组排序,它的使用方式与数组的 sort 完全一致。

除了必须给 dataSource 中的元素添加 groupKey 之外,和 List 不同的一点是 GroupListrenderItem 属性现在被分成了两个属性: renderGroupItemrenderGroupTitle

<GroupList
  renderGroupItem={(item,i) => { /* return a JSX ,array of element or string... */ }}
  renderGroupTitle={groupKey => { /* the same to renderGroupItem... */ }}
  // ...
/>

你可以分别指定普通的列表项和分组标题的渲染方式,renderGroupItem的使用与 ListrenderItem 完全一致;renderGroupTitle可以指定分组标题的渲染方式,它可以接收一个参数 groupKey,即你在 dataSource 中为每个元素添加的 groupKey。

对于一些其它 List 中的属性,GroupList也与之有细微的差别: itemTouchClassGroupList 里只能够指定普通列表项的触摸反馈效果,对于分组标题无效,onItemTap也是一样; 而 itemExtraClass 现在也分成了两个属性 itemExtraClassgroupTitleExtraClass 。可以参考 GroupList 的文档使用。

GroupList继承了 List 的全部特性,无穷模式,下拉刷新和加载更多等功能都可以使用。

Static Section

List#Static Section

配置分组导航侧边栏

设置 showIndexNavBar 属性为 true 可以开启一个分组导航栏(默认是开启的),你可以通过 renderIndexNavBar 指定渲染导航项的方式。它有一个事件 onIndexNavBarItemHover,在手指划过某个导航项时触发。

需要注意的是,在不指定高度的无穷模式下,分组导航栏无法使用,因为在所有列表项完成定位之前无法获取每一个分组的位置。

一个完整的例子

下面的代码就是右侧 Demo 的源码:

class GroupListDemo extends Component {

  static guid = -1;

  constructor() {
    super();
    this.state = {
      dataSource: this.renderDataSource(getRandomDataSource(100))
    };
  }

  renderDataSource(dataSource) {
    return dataSource.map((item, index)=> {
      return {
        groupKey: index < 5 ? 'notGrouped' : parseInt(item.text / 10, 10),
        text: index < 5 ? ('没有被分组的元素' + item.text) : item.text,
        key: ++GroupListDemo.guid
      };
    });
  }

  loadMore() {
    this.setState({
      dataSource: this.state.dataSource.concat(this.renderDataSource(getRandomDataSource(10)))
    });
  }

  render() {
    return (
      <Page title='GroupList Demo' onLeftPress={()=>location.href = '../index/index.html'}>
        <GroupList
          ref='grouplist'
          dataSource={this.state.dataSource}
          offsetY={-220}
          infinite={true}
          itemHeight={44}
          showIndexNavBar={true /* 注意:没有指定高度的无穷分组列表无法使用indexNavBar,这个属性设置为true也不会生效 */}
          renderIndexNavBarItem={(groupKey) => DIGIT_TO_CHN[groupKey] /* 同上 */}
          onIndexNavBarItemHover={(groupKey) => {
            ToolTip.show(DIGIT_TO_CHN[groupKey], 2000);
          }}
          renderGroupItem={(item, index)=><div>{index + ':' + item.text}</div>}
          renderGroupTitle={(groupKey)=>DIGIT_TO_CHN[groupKey]}
          groupTitleExtraClass={title=>'label demo-group-title'}
          onItemTap={(item, index)=>ToolTip.show('tapping:' + item.text, 2000)}
          sort={(a, b) => { return a - b; }}
          usePullRefresh={true}
          onRefresh={()=> {
            setTimeout(()=> {
              this.setState({ dataSource: this.renderDataSource(getRandomDataSource(500)) })
              this.refs.grouplist.stopRefreshing(true);
            }, 500);
          }}
          useLoadMore={true}
          onLoad={()=> {
            setTimeout(()=> {
              this.loadMore();
              this.refs.grouplist.stopLoading(true);
            }, 500);
          }}
        />
      </Page>
    );
  }
}
属性

dataSource { Array/Immutable List } #

组件的数据源,每个元素必须有groupKey属性(String),如果是不需要分组的元素,groupKey属性为'notGrouped'。

示例:

  • [
     {
       text: String //如果传入了这个属性并且没有配置renderItem,会以text文本作为列表项的内容
       groupKey: String //列表项的groupKey,将根据这个属性对元素进行分组,如果是不需要分组的元素,应设置为'notGrouped'。
     },
     ...
    ]
    

默认值: null

sort { Function } #

组的排序规则,使用方式与array.sort相同,能够接受两个参数a和b,返回一个数字。 负数表示a在b前,正数表示a在b后。

默认值: null

方法参数:

参数名 类型 描述 支持版本
a String 两个title之中在前面的那个
b String 两个title之中在后面的那个

renderGroupTitle { Function } #

根据groupKey渲染group title。

默认值: (groupKey)=>groupKey

方法参数:

参数名 类型 描述 支持版本
groupKey {String} title对应的groupKey

renderGroupItem { Function } #

根据列表项数据渲染列表项,返回JSX或者字符串,默认会返回数据对象的text(如果定义了的话)。

默认值: item=>item.text

方法参数:

参数名 类型 描述 支持版本
item Object 列表项数据
index Number 在数据源中的index

staticSection { Element } 3.0.3 #

在所有列表项之上渲染的一块静态区域,在开启Infinite模式时,这块区域不会参与列表项的回收复用。 注意:在设置staticSection以后,你还必须设置staticSectionHeight属性指定它的高度。

默认值: null

staticSectionHeight { Number } 3.0.3 #

静态区域的高度,在设置了staticSection以后必须为它指定一个高度。

默认值: 0

showIndexNavBar { Bool } #

是否显示分组导航。

默认值: false

infinite { Bool } #

是否使用无穷列表模式(参考List的无穷列表模式)。

默认值: false

infiniteSize { Number } #

无穷列表模式中,保留在容器中列表项的数量。 由于grouplist中列表项的高度一般较小,因此默认值为30。

默认值: 30

itemHeight { Number } #

无穷列表模式下列表项的高度。

默认值: null

titleHeight { Number } #

group title的高度,使用infinite模式时通过这个属性设置title项的高度,参见List的无穷列表模式。

默认值: 25

titleOffset { Number } 3.0.6 #

group title吸顶容器距离默认位置(top:0)的偏移。当你不希望吸顶容器处在GroupList的顶部时,可以设置这个属性。

默认值: 0,

itemExtraClass { String/Function } #

grouplist列表项的extraClass,使用方式参考List的itemExtraClass属性。

注意:这个属性的值/结果会完全覆盖掉默认的className。

默认值: null

方法参数:

参数名 类型 描述 支持版本
item Object 列表项数据对象
index Number 在数据源中的偏移

groupTitleExtraClass { String } #

grouptitle的extraClass,可以是字符串或者函数,如果传入函数,可以接收一个参数,为当前元素的groupKey。

注意:这个属性的值/返回的结果会完全覆盖掉默认的className而不是追加。

默认值: null

方法参数:

参数名 类型 描述 支持版本
groupKey String 分组名

offsetY { Number } #

列表的初始位置。

默认值: 0

contentInset { Number } 3.0.13 #

内容区域周围的留白,目前仅支持 bottom。主要用于适配 iPhoneX,在下方留出一定间隙。有『加载更多』时,显示在『加载更多』的下方。可以通过设置背景色来改变留白的颜色。

默认值: {bottom:0}

onItemTap { Function } #

点击列表项时触发的事件回调,接受的参数和使用方式与List相同。

默认值: ()=>{}

方法参数:

参数名 类型 描述 支持版本
item Object 列表项数据对象
index Number 在数据源中的偏移
target element 当前event对象的target

itemTouchClass { String/Function } #

列表项被点击时附加的className,参见List同名属性。

默认值: item-light

方法参数:

参数名 类型 描述 支持版本
item Object 列表项数据对象
index Number 在数据源中的偏移

usePullRefresh { Bool } #

是否使用下拉刷新。

pullRefreshHeight { Number } #

触发下拉刷新状态的高度(一般即为下拉刷新提示区域的高度)。

默认值: 40

renderPullRefresh { Function } #

() => JSX

自定义的下拉刷新渲染函数。

返回值: JSX 用来渲染

onRefresh { Function } #

下拉刷新回调。

方法参数:

参数名 类型 描述 支持版本
dataSource Array 当前数据源

useLoadMore { Bool } #

是否开启加载更多功能。

onLoad { Function } #

加载更多触发时的回调函数。

loadMoreHeight { Number } #

触发加载更多状态的高度(一般即为加载更多提示区域的高度)。

默认值: 40

renderLoadMore { Function } #

自定义加载更多区域的渲染方式,用返回的JSX节点取代原节点。

返回值: JSX

onScroll { Function } #

Scroller滚动时触发的回调。

方法参数:

参数名 类型 描述 支持版本
offsetY Number 当前 Scroller 的 y 轴偏移量

onScrollEnd { Function } 3.1.4 #

滚动结束之后的回调

默认值: null

方法参数:

参数名 类型 描述 支持版本
offsetY Number 当前 Scroller 的 y 轴偏移量

extraClass { String } #

附加给组件根节点的额外className。

style { Object } 3.0.2 #

给GroupList容器节点绑定的额外样式。

默认值: null

onIndexNavBarItemHover { Function } #

在手指扫过分组导航的某一项时触发的回调

方法参数:

参数名 类型 描述 支持版本
groupKey {String} 当前手指盖住的navBarItem对应的groupKey

renderIndexNavBarItem { Function } #

定制grouplist分组导航中每一项的render函数,接收groupkey为参数,返回字符串或者jsx

默认值: groupKey=>groupKey

方法参数:

参数名 类型 描述 支持版本
groupKey String/Number

disabled { Bool } 3.0.2 #

是否禁止滚动,参见Scroller的同名属性

默认值: false

directionLockThreshold { Number } 3.0.2 #

只允许单向滚动的时候,会根据这个阀值来判定响应哪个方向上的位移:某一方向位移减去另一个方向位移超过阀值,就会判定为这个方向的滚动。

默认值: 5

deceleration { Number } 3.0.6 #

滚动视图开始惯性滚动时减速的加速度,默认为0.010。

scrollWithoutTouchStart { Bool } 3.0.2 #

实验中的属性 在默认情况下一次用户触发(非调用scrollTo方法)scroller的滚动需要由touchstart事件来启动,在某些情况下,例如scroller从disable状态切换到enable状态时, 可能不能接收到这一瞬间的touchstart事件,这可能导致用户期待的滚动过程没有发生。 开启这个属性为true以后将允许scroller用touchmove启动滚动过程,这可以解决上述场景的问题。

默认值: false

stickyOffset { Number } 3.0.6 #

给staticSection内部吸顶容器设置的y轴偏移。

默认值: 0

方法

refresh 3.0.6 #

在GroupList容器尺寸发生变化时调用,刷新内部的Scroller组件。

resetLoadStatus 3.0.7 #

重置加载更多功能。

方法参数:

参数名 类型 描述 必选 支持版本
hasLoadMore Bool 是否能够加载更多,如果传入false,加载更多区域的文字将会变成 没有更多了,并且继续向下滚动时不会触发onLoadMore。

scrollTo #

调用List同名方法,滚动到某个位置y。

方法参数:

参数名 类型 描述 必选 支持版本
y Number y坐标
time Number 动画持续时间

stopAnimate #

调用List同名方法,中止正在执行的滚动。

stopRefreshing #

调用 Scroller 同名方法,中止下拉刷新过程。在列表发生下拉刷新之后你应该调用这个方法去中止它(比如服务器响应已经返回的时候),否则刷新不会自动终止。

方法参数:

参数名 类型 描述 必选 支持版本
success Bool 下拉刷新是否成功,默认为 false。
config Object 停止刷新的动画配置。
config.duration number 回到顶部的动画时间,默认是 300ms。
callback Function 回到顶部的动画执行完毕的回调。

startRefreshing #

调用List同名方法,模拟下拉刷新过程。

stopLoading #

调用List同名方法,中止加载更多过程。

方法参数:

参数名 类型 描述 必选 支持版本
success Bool 加载更多是否成功