An open API service indexing awesome lists of open source software.

https://github.com/itenl/react-native-scrollable-tabview

Based on pure JS scripts, without relying on native, no need for react-native link, Title / Header / Tabs / Sticky / Screen components can be flexibly configured, among which Tabs / Sticky can slide When it reaches the top, it will be topped.
https://github.com/itenl/react-native-scrollable-tabview

react react-native scrollable sticky tabbar tabview tiktok

Last synced: 10 months ago
JSON representation

Based on pure JS scripts, without relying on native, no need for react-native link, Title / Header / Tabs / Sticky / Screen components can be flexibly configured, among which Tabs / Sticky can slide When it reaches the top, it will be topped.

Awesome Lists containing this project

README

          

# react-native-scrollable-tabview

[![NPM Version](http://img.shields.io/npm/v/@itenl/react-native-scrollable-tabview.svg?style=flat)](https://www.npmjs.com/package/@itenl/react-native-scrollable-tabview)

[English](./README.md) | 简体中文

基于纯 `JS` 脚本,不依赖原生,无需 `react-native link`,`Title` / `Header` / `Tabs` / `Sticky` / `Screen` 组件可灵活配置,其中 `Tabs` / `Sticky` 可在滑动到顶部时会进行吸顶;我们所支持的是以栈的形式独立管理自身的 `Sticky` / `Screen` / `Badge` / `tabLabel` 各项配置,并且为 `Screen` 注入[生命周期](#InjectionLifecycle) `onRefresh` / `onEndReached`它们将在下拉刷新与滚动条触底时触发,最后还为 `Screen` / `Sticky` 注入了更多 [props](#InjectionScreenProps)

##### Table of Contents
* [Example-API](https://github.com/itenl/react-native-scrollable-tabview-example-app)
* [Example-TikTok](https://github.com/itenl/react-native-scrollable-tabview-example-tiktok)
* [Features](#features)
* [Installation](#installation)
* [Usage](#usage)
* [Props](#props)
* [Method](#method)
* [Stack Property](#StackProperty)
* [Badge Property](#BadgeProperty)
* [Injection lifecycle to Screen](#InjectionLifecycle)
* [Injection props to Screen](#InjectionScreenProps)
* [Injection props to Sticky](#InjectionStickyProps)
* [Known Issues](#KnownIssues)
* [Snapshot](#Snapshot)

## Features
* 支持为每个 `Screen` 设置下拉刷新与上滑加载更多(生命周期注入或属性注入)
* Tabs 支持固定自适应与水平滚动两种配置方式
* 允许为每个 `Screen` 独立配置 `Sticky` 组件
* 允许为每个 `Tab` 独立配置自定义的徽章
* 支持下拉刷新与上滑加载更多前置函数 `onBeforeRefresh` / `onBeforeEndReached`
* 支持动画标题,可支持动画为 `interpolate.opacity` 与 `interpolate.height`

## Installation

```shell
npm i @itenl/react-native-scrollable-tabview
```
or
```shell
yarn add @itenl/react-native-scrollable-tabview
```

## Usage

```jsx
import React from 'react';
import ScrollableTabView from '@itenl/react-native-scrollable-tabview';

function App() {
return (
(this.scrollableTabView = rf)}
mappingProps={{
fromRootEst: this.state.est,
}}
badges={[
null,
[

new
,

Three Tips
,
],
]}
stacks={[
{
screen: One,
sticky: Sticky,
tabLabel: 'OneTab',
tabLabelRender: tabLabel => {
return `--- ${tabLabel} ---`;
},
badge: [one, two],
toProps: {
xx: 123,
},
}, {
screen: ({
layoutHeight,
refresh,
scrollTo,
toTabView,
initScreen,
onRefresh,
onEndReached,
}) => {
// The code is required
initScreen();
const [datetime, setDatetime] = useState(Date.now());
useEffect(() => {
setInterval(() => {
setDatetime(Date.now());
}, 1000);
}, []);
onRefresh((toggled) => {
toggled(true);
alert("onRefresh start");
setTimeout(() => {
toggled(false);
alert("onRefresh stop");
}, 3000);
});
onEndReached(() => {
alert("onEndReached");
});
return (


Test function component {datetime}


);
},
tabLabel: "TestFunctionComponent",
}
]}
tabsStyle={{}}
tabWrapStyle={{}}
tabInnerStyle={{}}
tabActiveOpacity={0.6}
tabStyle={{}}
textStyle={{}}
textActiveStyle={{}}
tabUnderlineStyle={{}}
firstIndex={0}
syncToSticky={true}
onEndReachedThreshold={0.1}
onBeforeRefresh={(next, toggled) => {
toggled();
next();
}}
onBeforeEndReached={next => {
next();
}}
onTabviewChanged={(index, tabLabel, isFirst) => {
alert(index);
}}
header={() => {
return ;
}}
oneTabHidden={true}
enableCachePage={true}
carouselProps={{}}
sectionListProps={{}}
toHeaderOnTab={true}
toTabsOnTab={true}
tabsShown={false}
fixedTabs={false}
fixedHeader={false}
useScroll={false}
fillScreen={true}
>
);
}
```

## Props

All props are optional

Prop | Type | Default | Description
----------------- | -------- | ----------- | -----------
**`stacks`** | Array | [] | 页面栈 < [阅读 Stack Property](#StackProperty) >
**`mappingProps`** | Object | {} | 关联映射数据到 Stack / Sticky
**`badges`** | Array | [] | 针对每个Tab的徽章 < [阅读 Badge Property](#BadgeProperty) >
**`tabsStyle`** | Object | {} | 整个Tabs样式
**`tabWrapStyle`** | Object / Function | {} | 单个Tab外包装样式 (函数参数提供了item, index, 需要返回样式对象,eg. **`return index == 1 && { zIndex : 10}`**)
**`tabInnerStyle`** | Object | {} | 单个Tab内包装样式
**`tabActiveOpacity`** | Number | 0.6 | Tab按钮点击后透明度
**`tabStyle`** | Object | {} | 单个Tab样式
**`textStyle`** | Object | {} | Tab内文本样式
**`textActiveStyle`** | Object | {} | 选中激活的text样式
**`tabUnderlineStyle`** | Object | {} | 选中激活的下划线样式
**`firstIndex`** | Number / Null | null | 设置 **`firstIndex`** 的栈为活动状态 (请在设定 **`firstIndex`** 值的时候确保 **`stacks`** 的个数大于 **`firstIndex`** )
**`syncToSticky`** | Boolean | true | 是否同步(Screen中发生 **`render`** 触发 **`componentDidUpdate`** 将更新Sticky)
**`onEndReachedThreshold`** | Number | 0.2 | 触底回调阈值
**`onBeforeRefresh`** | Function | null | 下拉刷新前置函数, 执行 **`next`** 将执行Screen中 **`onRefresh`** 函数,执行 **`toggled`** 将切换系统loading,可传 true / false 进行指定 (回调含有 **`next`** , **`toggled`** 两个形参)
**`onBeforeEndReached`** | Function | null | 上滑加载更多前置函数, 执行next将执行Screen中 **`onEndReached`** 函数 (回调含有 **`next`** 形参)
**`onTabviewChanged`** | Function | null | Tab切换完成回调 (回调含有 **`index`**, **`tabLabel`**, **`isFirst`** 形参)
**`screenScrollThrottle`** | Number | 60 | **`Screen`** 横向滑动时节流参数,单位 (毫秒)
**`header`** | Function / JSX Element / Class Component | null | 顶部组件 (若是函数需要返回 Element)
**`stickyHeader`** | Function / JSX Element / Class Component | null | 顶部带吸顶效果组件 (若是函数需要返回 Element)
**`oneTabHidden`** | Boolean | false | 仅一个Tab时将隐藏自身
**`enableCachePage`** | Boolean | true | 是否持久化页面切换后不销毁
**`carouselProps`** | Object | {} | 传递给 Carousel 的剩余属性 < [阅读 Carousel](https://github.com/meliorence/react-native-snap-carousel/blob/master/doc/PROPS_METHODS_AND_GETTERS.md) >
**`sectionListProps`** | Object | {} | 传递给 SectionList 的剩余属性 < [阅读 SectionList](https://reactnative.dev/docs/sectionlist) >
**`toHeaderOnTab`** | Boolean | false | 点击触发已激活的Tab将回到Header(高优先级)
**`toTabsOnTab`** | Boolean | false | 点击触发已激活的Tab将回到Tabs
**`tabsShown`** | Boolean | true | 配置 Tabs 显示隐藏
**`fixedTabs`** | Boolean | false | 在 **`enableCachePage`** 为true的情况下滑动切换Screen设置最小高度保障Header与Tabs不会弹跳
**`fixedHeader`** | Boolean | false | 与Tabs一同渲染,固定顶部Header,不跟随滚动
**`useScroll`** | Boolean | false | Tabs是否支持横向滚动(存在多个类目Tab的情况需要启用,建议 **`tabStyle`** 传入固定宽度)
**`useScrollStyle`** | Object | {} | 为滚动的 **`Tabs`** 设置 **`contentContainerStyle`**,常见为左右两侧添加边距 **`paddingLeft`** **`paddingHorizontal`**
**`fillScreen`** | Boolean | true | 填充整个 Screen
**`title`** | Function / JSX Element / Class Component | null | 动画标题
**`titleArgs`** | Object | **`{ style: {}, interpolateOpacity: {}, interpolateHeight: {} }`** | 标题配置 < [阅读 interpolate](https://reactnative.dev/docs/animations#interpolation) >
**`onScroll`** | Function | null | 滚动事件监听
**`onScroll2Horizontal`** | Function | null | 滚动事件监听(横向)
**`tabsEnableAnimated`** | Boolean | false | 为Tabs启用滑动效果,需要为 **`tabStyle`** 指定 **`width`**
**`tabsEnableAnimatedUnderlineWidth`** | Number | 0 | 为Tabs Underline设定固定宽度并添加弹跳动画,需要启用 **`tabsEnableAnimated=true`**.( 建议传入 **`tabStyle.width`** 的三分之一或固定 30px )
**`errorToThrow`** | Boolean | false | **`console.error`** 将会抛出错误 **`throw new Error()`**

## Method

``` javascript
(this.scrollableTabView = rf)}
>

this.scrollableTabView.getCurrentRef();
this.scrollableTabView.toTabView(1);
this.scrollableTabView.scrollTo(0);
this.scrollableTabView.clearStacks(()=>alert('done'));

```

Name | Type | Description
----------------- | -------- | -----------
**`getCurrentRef(index: number.optional)`** | Function | 获取当前活动的视图的实例,可传 **`index`** 获取指定实例
**`toTabView(index: number.required / label: string.required)`** | Function | 跳到指定 Screen
**`scrollTo(index: number.required)`** | Function | 上下滑动至指定位置 (传入 0 默认定位至 tabs / 传入负数则置顶)
**`clearStacks(callback: function.optional)`** | Function | 清空栈以及相关状态 (Tabs / Badge / Stacks))

## Stack Property

Name | Type | Description
----------------- | -------- | -----------
**`screen`** | Class Component | Screen 类组件
**`sticky`** | Class Component | 吸顶类组件, 实例内将返回该类组件的上下文
**`tabLabel`** | String | Tab 昵称
**`tabLabelRender`** | Function | 自定义 Tab渲染函数,优先级高于 **`tabLabel`**
**`badge`** | Array | 针对当前 Tab 的徽章,与 **`badges`** 属性互斥,优先级高于最外层属性 **`badges`** < [阅读 Badge Property](#BadgeProperty) >
**`toProps`** | Object | **`toProps`** 仅传递给 Screen,不作数据关联

## Badge Property

Type | Description
-------- | -----------
JSX Element | 基于当前Tab进行渲染的 徽章 / 悬浮 Tips 等

## Injection lifecycle to Screen(仅在类组件)

Name | Type | Description
----------------- | -------- | -----------
**`onRefresh`** | Function | 下拉刷新时触发,形参 **`toggled`** 函数用于切换原生 loading 状态的显隐,若在 loading 中用户切换 tab 将会强制隐藏并重置状态
**`onEndReached`** | Function | 上滑加载更多触发

## Injection props to Screen

Name | Type | Description
----------------- | -------- | -----------
**`refresh()`** | Function | 手动触发刷新、同步Screen状态至Sticky
**`scrollTo(index: number.required)`** | Function | 上下滑动至指定位置 (传入 0 默认定位至 tabs / 传入负数则置顶)
**`toTabView(index: number.required / label: string.required)`** | Function | 跳到指定 Screen
**`layoutHeight.container`** | Number | Container 容器总高度
**`layoutHeight.header`** | Number | Header 高度
**`layoutHeight.tabs`** | Number | Tabs 高度
**`layoutHeight.screen`** | Number | 视图 高度
**`initScreen`** | Function | (仅在函数组件) 如果是函数组件则必须调用
**`onRefresh`** | Function | (仅在函数组件) < [阅读 onRefresh 描述](#InjectionLifecycle) >
**`onEndReached`** | Function | (仅在函数组件) < [阅读 onEndReached 描述](#InjectionLifecycle) >

## Injection props to Sticky

Name | Type | Description
----------------- | -------- | -----------
**`screenContext`** | Object | 获取 Screen 上下文

## Known Issues
- 如果你仅仅是新增 `Stack` 可以 `Push` 即可,但如果需要更新或者删除 `Stack` 请使用 [clearStacks](#Method) 后在添加你所需要的 `Stacks`

## Snapshot

### Android (Sliding Tabs)

### iOS (Bounce Tabs)

### API Example


---

**MIT Licensed**