2017-07-07 81 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