diff --git a/packages/taro-components-rn/TCRNExample/App.flatlist.js b/packages/taro-components-rn/TCRNExample/App.flatlist.js
new file mode 100644
index 000000000000..681c89eaa639
--- /dev/null
+++ b/packages/taro-components-rn/TCRNExample/App.flatlist.js
@@ -0,0 +1,157 @@
+import React, { Component } from 'react'
+import { StyleSheet } from 'react-native'
+import {
+ Provider,
+ Block,
+ ScrollView,
+ View,
+ Text,
+ Button,
+ Image
+} from '../dist'
+// import EXAudio from './example/EXAudio'
+import EXButton from './example/EXButton'
+import EXCheckbox from './example/EXCheckbox'
+import EXForm from './example/EXForm'
+import EXIcon from './example/EXIcon'
+import EXImage from './example/EXImage'
+import EXInput from './example/EXInput'
+// import EXMap from './example/EXMap'
+import EXPicker from './example/EXPicker'
+import EXProgress from './example/EXProgress'
+import EXRadio from './example/EXRadio'
+import EXRichText from './example/EXRichText'
+import EXSlider from './example/EXSlider'
+import EXSwiper from './example/EXSwiper'
+import EXSwitch from './example/EXSwitch'
+// import EXVideo from './example/EXVideo'
+import EXWebView from './example/EXWebView'
+
+export default class App extends Component {
+ state = {
+ // 更改 scrollTop 可滚动
+ scrollTop: 0
+ }
+
+ onViewTouchstart = () => {
+ console.log('view toucstart')
+ }
+
+ onViewTouchmove = () => {
+ console.log('view touchmove')
+ }
+
+ onViewTouchend = () => {
+ console.log('view touchend')
+ }
+
+ componentDidMount () {
+ // setTimeout(() => {
+ // this.setState({ scrollTop: 2200 })
+ // }, 0)
+ }
+
+ renderItem = ({ item }) => {
+ switch (item.name) {
+ case 'welcome':
+ return Welcome to React Native!
+ case 'Block':
+ return (
+
+
+ Block
+
+
+
+ )
+ case 'Button':
+ return (
+
+
+ Button
+
+
+
+ )
+ case 'Checkbox':
+ return (
+
+
+ Checkbox
+
+
+
+ )
+ case 'Form':
+ return (
+
+
+ Form
+
+
+
+ )
+ }
+ }
+
+ render () {
+ return (
+
+ {
+ console.log('to upper')
+ }}
+ onScrollToLower={() => {
+ console.log('to lower')
+ }}
+ onScroll={(e) => {
+ console.log('onScroll', e)
+ }}
+ bounces={false}
+ data={[
+ { name: 'welcome' },
+ { name: 'Block' },
+ { name: 'Button' },
+ { name: 'Checkbox' },
+ { name: 'Form' },
+ ]}
+ renderItem={this.renderItem}
+ />
+
+ )
+ }
+}
+
+const styles = StyleSheet.create({
+ section: {
+ alignItems: 'center',
+ width: '100%',
+ paddingBottom: 10,
+ marginBottom: 10,
+ borderBottomWidth: 1,
+ borderBottomColor: 'gold'
+ },
+ sectionTit: {
+ marginBottom: 10,
+ paddingVertical: 4,
+ paddingHorizontal: 8,
+ backgroundColor: 'tomato',
+ borderRadius: 4,
+ borderLeftWidth: 3,
+ borderLeftColor: '#666',
+ borderRightWidth: 3,
+ borderRightColor: '#666'
+ },
+ sectionTitTxt: {
+ fontSize: 18,
+ color: 'white'
+ }
+})
diff --git a/packages/taro-components-rn/src/components/ScrollView/PropsType.tsx b/packages/taro-components-rn/src/components/ScrollView/PropsType.tsx
index fc38857cf139..465ea9c60f01 100644
--- a/packages/taro-components-rn/src/components/ScrollView/PropsType.tsx
+++ b/packages/taro-components-rn/src/components/ScrollView/PropsType.tsx
@@ -1,5 +1,5 @@
import * as React from 'react'
-import { StyleProp, ViewStyle } from 'react-native'
+import { StyleProp, ViewStyle, ListRenderItem } from 'react-native'
export type ScrollMetrics = {
contentLength: number;
@@ -37,7 +37,7 @@ export interface ScrollViewState {
snapScrollLeft: number;
}
-export interface ScrollViewProps {
+export interface ScrollViewProps {
children?: React.ReactNode;
style?: StyleProp;
scrollX?: boolean;
@@ -52,4 +52,6 @@ export interface ScrollViewProps {
onScroll?: (evt: EventOnScroll) => void;
// RN 属性
contentContainerStyle?: StyleProp;
+ data?: ReadonlyArray | null;
+ renderItem?: ListRenderItem;
}
diff --git a/packages/taro-components-rn/src/components/ScrollView/index.tsx b/packages/taro-components-rn/src/components/ScrollView/index.tsx
index 4a5e0fb3e38c..9ee100aa7615 100644
--- a/packages/taro-components-rn/src/components/ScrollView/index.tsx
+++ b/packages/taro-components-rn/src/components/ScrollView/index.tsx
@@ -22,6 +22,7 @@
import * as React from 'react'
import {
ScrollView,
+ FlatList,
NativeSyntheticEvent,
NativeScrollEvent,
LayoutChangeEvent,
@@ -38,7 +39,7 @@ import { ScrollViewProps, ScrollViewState, ScrollMetrics } from './PropsType'
// // Other
// ]
-class _ScrollView extends React.Component {
+class _ScrollView extends React.Component, ScrollViewState> {
static defaultProps = {
upperThreshold: 50,
lowerThreshold: 50,
@@ -47,7 +48,7 @@ class _ScrollView extends React.Component {
enableBackToTop: false,
}
- static getDerivedStateFromProps (props: ScrollViewProps, state: ScrollViewState) {
+ static getDerivedStateFromProps (props: ScrollViewProps, state: ScrollViewState) {
return state.snapScrollTop !== props.scrollTop || state.snapScrollLeft !== props.scrollLeft ? {
snapScrollTop: props.scrollTop,
snapScrollLeft: props.scrollLeft
@@ -70,7 +71,7 @@ class _ScrollView extends React.Component {
velocity: 0,
visibleLength: 0,
}
- $scrollView = React.createRef()
+ $scrollView = React.createRef()
_hasDataChangedSinceEndReached: boolean
_sentEndForContentLength: number = 0
_scrollEventThrottle: number = 50
@@ -180,8 +181,15 @@ class _ScrollView extends React.Component {
}
scrollToOffset = (x: number = 0, y: number = 0): void => {
+ const { scrollX, data, renderItem } = this.props
const node = this.$scrollView.current
- node && node.scrollTo({ x, y, animated: !!this.props.scrollWithAnimation })
+ if (node) {
+ if (data && renderItem) {
+ (node as FlatList).scrollToOffset({ offset: scrollX ? x : y, animated: !!this.props.scrollWithAnimation })
+ } else {
+ (node as ScrollView).scrollTo({ x, y, animated: !!this.props.scrollWithAnimation })
+ }
+ }
}
componentDidMount () {
@@ -192,11 +200,11 @@ class _ScrollView extends React.Component {
}
}
- getSnapshotBeforeUpdate (prevProps: ScrollViewProps, prevState: ScrollViewState) {
+ getSnapshotBeforeUpdate (prevProps: ScrollViewProps, prevState: ScrollViewState) {
return prevState.snapScrollTop !== this.state.snapScrollTop || prevState.snapScrollLeft !== this.state.snapScrollLeft
}
- componentDidUpdate (prevProps: ScrollViewProps, prevState: ScrollViewState, snapshot: boolean) {
+ componentDidUpdate (prevProps: ScrollViewProps, prevState: ScrollViewState, snapshot: boolean) {
if (snapshot) {
this.scrollToOffset(this.state.snapScrollLeft, this.state.snapScrollTop)
}
@@ -213,6 +221,8 @@ class _ScrollView extends React.Component {
scrollX,
enableBackToTop,
contentContainerStyle,
+ data,
+ renderItem,
} = this.props
const flattenStyle: ViewStyle & { [key: string]: any } = StyleSheet.flatten(style)
@@ -226,45 +236,59 @@ class _ScrollView extends React.Component {
flattenStyle.justifyContent && (_contentContainerStyle.justifyContent = flattenStyle.justifyContent)
}
- return (
+ const scrollElementProps = {
+ horizontal: scrollX,
+ onContentSizeChange: this._onContentSizeChange,
+ onLayout: this._onLayout,
+ onScroll: this._onScroll,
+ onScrollEndDrag: this._onScrollEndDrag,
+ onMomentumScrollEnd: this._onMomentumScrollEnd,
+ scrollEventThrottle: this._scrollEventThrottle,
+ scrollsToTop: !!enableBackToTop,
+ style: wrapperStyle,
+ contentContainerStyle: [_contentContainerStyle, contentContainerStyle],
+ ...omit(this.props, [
+ // props
+ 'style',
+ 'scrollX',
+ 'upperThreshold',
+ 'lowerThreshold',
+ 'scrollTop',
+ 'scrollLeft',
+ 'scrollWithAnimation',
+ 'enableBackToTop',
+ 'onScrollToUpper',
+ 'onScrollToLower',
+ 'onScroll',
+ 'contentContainerStyle',
+ // SProps
+ 'horizontal',
+ 'onContentSizeChange',
+ 'onLayout',
+ 'onScroll',
+ 'onScrollEndDrag',
+ 'onMomentumScrollEnd',
+ 'scrollEventThrottle',
+ 'scrollsToTop',
+ 'style',
+ 'contentContainerStyle',
+ 'data',
+ 'renderItem',
+ 'keyExtractor',
+ ]),
+ ref: this.$scrollView
+ }
+
+ return data && renderItem ? (
+ index + ''}
+ />
+ ) : (
{children}