js局部
interface IProps { text: string, style?: object,}interface IState { transformX: any, viewWidth: number, textWidth: number,}const FlexItem = Flex.Item;const Speed = 10000export default class Notice extends React.PureComponent<IProps, IState> { state: IState = { transformX: new Animated.Value(0), viewWidth: 0, textWidth: 0, } constructor (props: IProps) { super(props) } onTextLayout = (event: any) => { const { width } = event.nativeEvent.layout; this.setState({ textWidth: width }) } onViewLayout = (event: any) => { const { width } = event.nativeEvent.layout; this.setState({ viewWidth: width }) } move () { const { viewWidth, textWidth, transformX } = this.state; if (textWidth > viewWidth) { let duration = Speed duration += ((textWidth - viewWidth) / viewWidth) * Speed; transformX.setValue(viewWidth) Animated.timing(transformX, { toValue: -textWidth, duration: duration, easing: Easing.linear, useNativeDriver: false }).start(({finished}) => { if (finished) { this.move() } }) } } componentDidUpdate () { this.move() } renderContent(text: string) { const { transformX, textWidth } = this.state; return <Animated.View style={[styles.animatedView, { width: textWidth, transform: [{ translateX: transformX }] }]}> <Text numberOfLines={1}> {text} </Text> </Animated.View> } render() { const { text, style = {} } = this.props; return <View onLayout={this.onViewLayout} style={[styles.view, style]}> <Flex direction="row"> <FlexItem style={{ flexDirection: 'row' }}> {this.renderContent(text)} </FlexItem> </Flex> <View style={styles.hide}> <Text onLayout={this.onTextLayout} numberOfLines={1} style={[styles.hide]}> {text} </Text> </View> </View> }}
css局部
const styles = StyleSheet.create({ view: { paddingVertical: 24, overflow: 'hidden' }, normalView: { paddingLeft: 24, }, animatedView: { flexDirection: 'row', }, hide: { flexDirection: 'row', opacity: 0, zIndex: -1, position: 'absolute', top: 0, },});