2017-07-07 79 views
2

我拼凑了一个Microsoft Excel的工作版本,如“冻结疼痛”视图。列标题水平滚动内容,行标题与内容垂直滚动,但当滚动另一个时,每个“卡住”位置。React Native粘性行和标题滚动性能?

You can try the working version here.
这不是最佳的,因为它停止了一个轻弹的滚动或只是轻扫许多口吃。

该方法使用了一些技巧,但导致问题的方法是同步滚动视图。

As outlined here,我试过设置useNativeDriver: true,这需要改变
ScrollViewAnimated.ScrollView
ref={ref => (this.instance = ref)}ref={ref => (this.instance = ref._component)} 但随后同步进入完全失控。

我喜欢更理想的方法。这怎么能改进?

import React from 'react'; 
import { ScrollView, Animated, Text, View } from 'react-native'; 

export default class SyncScrollTest extends React.Component { 
    constructor() { 
    super(); 
    this.scrollPosition = new Animated.Value(0); 
    this.scrollEvent = Animated.event(
     [{ nativeEvent: { contentOffset: { y: this.scrollPosition } } }], 
     { useNativeDriver: false }, 
    ); 
    } 

    render() { 
    return (
     <View style={{ flex: 1 }}> 
     <View style={{ flexDirection: 'row' }}> 
      <ScrollViewVerticallySynced 
      style={{ width: 50, marginTop: 60 }} 
      name="C1" 
      color="#F2AFAD" 
      onScroll={this.scrollEvent} 
      scrollPosition={this.scrollPosition} 
      /> 
      <ScrollView horizontal bounces={false}> 
      <View style={{ width: 600 }}> 
       <View style={{ height: 60, justifyContent: 'center', backgroundColor: '#B8D2EC' }}> 
       <Text> 
        I am Column Header!! I am Column Header!! I am Column Header!! I am Column 
        Header!! I am Column Header!! I am Column Header!! I am Column Header!! 
       </Text> 
       </View> 
       <ScrollViewVerticallySynced 
       style={{ width: 600 }} 
       name="C2" 
       color="#D9E4AA" 
       onScroll={this.scrollEvent} 
       scrollPosition={this.scrollPosition} 
       /> 
      </View> 
      </ScrollView> 
     </View> 
     </View> 
    ); 
    } 
} 

class ScrollViewVerticallySynced extends React.Component { 
    componentDidMount() { 
    this.listener = this.props.scrollPosition.addListener((position) => { 
     this.instance.scrollTo({ 
     y: position.value, 
     animated: false, 
     }); 
    }); 
    } 

    render() { 
    const { name, color, style, onScroll } = this.props; 
    return (
     <ScrollView 
     key={name} 
     ref={ref => (this.instance = ref)} 
     style={style} 
     scrollEventThrottle={1} 
     onScroll={onScroll} 
     bounces={false} 
     showsVerticalScrollIndicator={false} 
     > 
     {someRows(name, 25, color)} 
     </ScrollView> 
    ); 
    } 
} 

const someRows = (name, rowCount, color) => 
    Array.from(Array(rowCount).keys()).map(index => 
    (<View 
     key={`${name}-${index}`} 
     style={{ 
     height: 50, 
     backgroundColor: index % 2 === 0 ? color : 'white', 
     flex: 1, 
     alignItems: 'center', 
     justifyContent: 'center', 
     }} 
    > 
     <Text> 
     {name} R{index + 1} 
     </Text> 
    </View>), 
); 

```

+1

你的代码运行平稳的设备,但不是在模拟器。你碰巧搞清楚了吗?我试图完成同样的事情,没有运气。 – teggy

回答

1

我已经改变了,而不是使用监听器和动画事件我使用ScrollViewscrollTo方法来滚动同步您的例子。我认为听众是滚动时行间滞后的原因。

您可以测试更改here

import React from 'react'; 
import { ScrollView, Text, View } from 'react-native'; 
import { Constants } from 'expo' 

export default class SyncScrollTest extends React.Component { 
    constructor() { 
    super(); 
    this.c1IsScrolling = false; 
    this.c2IsScrolling = false; 

    } 

    render() { 
    return (
     <View style={{ flex: 1, marginTop: Constants.statusBarHeight }}> 
     <View style={{ flexDirection: 'row' }}> 
      <ScrollViewVerticallySynced 
      style={{ width: 50, marginTop: 60 }} 
      refe= {ref => (this.c2View = ref)} 
      name="C1" 
      color="#F2AFAD" 
      onScroll={e => { 
       if (!this.c1IsScrolling) { 
        this.c2IsScrolling = true; 
        var scrollY = e.nativeEvent.contentOffset.y; 
        this.c1View.scrollTo({ y: scrollY }); 
       } 
       this.c1IsScrolling = false; 
       }} 

      /> 
      <ScrollView horizontal bounces={false}> 
      <View style={{ width: 400 }}> 
       <View style={{ height: 60, justifyContent: 'center', backgroundColor: '#B8D2EC' }}> 
       <Text> 
        I am Column Header!! I am Column Header!! I am Column Header!! I am Column 
        Header!! I am Column Header!! I am Column Header!! I am Column Header!! 
       </Text> 
       </View> 
       <ScrollViewVerticallySynced 
       style={{ width: 400 }} 
       refe= {ref => (this.c1View = ref)} 
       name="C2" 
       color="#D9E4AA" 
       onScroll= {e => { 
        if (!this.c2IsScrolling) { 
        this.c1IsScrolling = true; 
        var scrollY = e.nativeEvent.contentOffset.y; 
        this.c2View.scrollTo({ y: scrollY }); 
        } 
        this.c2IsScrolling = false; 
       }} 

       /> 
      </View> 
      </ScrollView> 
     </View> 
     </View> 
    ); 
    } 
} 

class ScrollViewVerticallySynced extends React.Component { 
    render() { 
    const { name, color, style, onScroll, refe } = this.props; 
    return (
     <ScrollView 
     key={name} 
     ref={refe} 
     style={style} 
     scrollEventThrottle={1} 
     onScroll={onScroll} 
     bounces={false} 
     showsVerticalScrollIndicator={false} 
     > 
     {someRows(name, 25, color)} 
     </ScrollView> 
    ); 
    } 
} 


const someRows = (name, rowCount, color) => 
    Array.from(Array(rowCount).keys()).map(index => 
    (<View 
     key={`${name}-${index}`} 
     style={{ 
     height: 50, 
     backgroundColor: index % 2 === 0 ? color : 'white', 
     flex: 1, 
     alignItems: 'center', 
     justifyContent: 'center', 
     }} 
    > 
     <Text> 
     {name} R{index + 1} 
     </Text> 
    </View>), 
); 

你可以找到另一个例子here

+0

出于某种原因,这给了我更糟的滚动行为比OP的原始版本。有什么我做错了吗?我已经做了两个零食,并在模拟器和真实设备上进行测试。 – MC10