2017-04-20 71 views
0

我试图在选中时在水平listView中放置一个项目。我目前的策略是首先测量项目并滚动到视图内引用项目的x坐标。如何在React Native ListView中将项目居中?

enter image description here

目前,任何时候我按项目ListView滚动到最后x: 538

是否有实现这个同时保持代码的无国籍/功能更简单的方法?

const ItemScroll = (props) => { 

    const createItem = (obj, rowID) => { 

    const isCurrentlySelected = obj.id === props.currentSelectedID 

    function scrollToItem(_scrollViewItem, _scrollView) { 
     // measures the item coordinates 
     _scrollViewItem.measure((fx) => { 
     console.log('measured fx: ', fx) 
     const itemFX = fx; 
     // scrolls to coordinates 
     return _scrollView.scrollTo({ x: itemFX }); 
     }); 
    } 
    return (
     <TouchableHighlight 
     ref={(scrollViewItem) => { _scrollViewItem = scrollViewItem; }} 
     isCurrentlySelected={isCurrentlySelected} 
     style={isCurrentlySelected ? styles.selectedItemContainerStyle : styles.itemContainerStyle} 
     key={rowID} 
     onPress={() => { scrollToItem(_scrollViewItem, _scrollView); props.onEventFilterPress(obj.id, rowID) }}> 
     <Text style={isCurrentlySelected ? styles.selectedItemStyle : styles.itemStyle} > 
      {obj.title} 
     </Text> 
     </TouchableHighlight> 
    ) 
    }; 
    return (
    <View> 
     <ScrollView 
     ref={(scrollView) => { _scrollView = scrollView; }} 
     horizontal> 
     {props.itemList.map(createItem)} 
     {props.onItemPress} 
     </ScrollView> 
    </View> 
); 
}; 

更新

随着@Ludovic建议,我现在已经切换到FlatList,我不知道如何与功能组件触发scrollToIndex。下面是我的新ItemScroll

const ItemScroll = (props) => { 

    const { 
     itemList, 
     currentSelectedItem 
     onItemPress } = props 

    const renderItem = ({item, data}) => { 
    const isCurrentlySelected = item.id === currentSelectedItem 

    const _scrollToIndex =() => { return { viewPosition: 0.5, index: data.indexOf({item}) } } 

    return (
     <TouchableHighlight 
     // Below is where i need to run onItemPress in the parent 
     // and scrollToIndex in this child. 
     onPress={[() => onItemFilterPress(item.id), scrollToIndex(_scrollToIndex)]} > 
     <Text style={isCurrentlySelected ? { color: 'red' } : { color: 'blue' }} > 
      {item.title} 
     </Text> 
     </TouchableHighlight> 
    ) 
    } 
    return (
    <FlatList 
     showsHorizontalScrollIndicator={false} 
     data={itemList} 
     keyExtractor={(item) => item.id} 
     getItemLayout={(data, index) => (
      // Max 5 items visibles at once 
      { length: Dimensions.get('window').width/5, offset: Dimensions.get('window').width/5 * index, index } 
    )} 
     horizontal   
     // Here is the magic : snap to the center of an item 
     snapToAlignment={'center'} 
     // Defines here the interval between to item (basically the width of an item with margins) 
     snapToInterval={Dimensions.get('window').width/5} 
     renderItem={({item, data}) => renderItem({item, data})} /> 
); 
}; 

回答

1

在我看来,你应该使用FlatList

FlatList有一个方法scrollToIndex,允许直接进入您的DATAS的项目。它几乎与ScrollView相同但更智能。可悲的是,文件非常差。

这里是一个FlatList我做

let datas = [{key: 0, text: "Hello"}, key: 1, text: "World"}] 

<FlatList 
    // Do something when animation ended 
    onMomentumScrollEnd={(e) => this.onScrollEnd(e)} 
    ref="flatlist" 
    showsHorizontalScrollIndicator={false} 
    data={this.state.datas} 
    keyExtractor={(item) => item.key} 
    getItemLayout={(data, index) => (
     // Max 5 items visibles at once 
     {length: Dimensions.get('window').width/5, offset: Dimensions.get('window').width/5 * index, index} 
    )} 
    horizontal={true} 
    // Here is the magic : snap to the center of an item 
    snapToAlignment={'center'} 
    // Defines here the interval between to item (basically the width of an item with margins) 
    snapToInterval={Dimensions.get('window').width/5}  
    style={styles.scroll} 
    renderItem={ ({item}) => 
     <TouchableOpacity 
      onPress={() => this.scrollToIndex(/* scroll to that item */)} 
      style={styles.cell}> 
      <Text>{item.text}</Text> 
     </TouchableOpacity> 
    } 
/> 

更多FlatList的例子:https://facebook.github.io/react-native/releases/next/docs/flatlist.html

+0

我怎么会指定'scrollToIndex'指数?它是关键,可见项目数组中的索引还是整个数组中的索引? – Chris

+0

数组中的索引 – Ludovic

+0

'onPress = {()=> scrollToIndex({viewPosition:0.5,index:data.indexOf({item})})}'是一个解决方案吗? – Chris