我如何在React Native ListView中将项目居中? [英] How do I center an item within a React Native ListView?
问题描述
我正在尝试在选定水平居中的情况下将其居中放置在水平listView中.我当前的策略是首先测量项目,然后滚动到视图中引用项目的x坐标.
I'm trying to center an item within a horizontal listView when selected. My current strategy is to first measure the item and scroll to the x coordinates of the referenced item within the view.
当前,每当我按下项目ListView
时,滚动到最底端的x: 538
Currently, any time I press an item ListView
scrolls to the very end x: 538
在保持代码无状态/正常运行的情况下,是否有更简单的方法来实现此目的?
Is there an easier way to implement this while keeping the code stateless / functional?
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
Update
With @Ludovic suggestions I have now switch to FlatList, I am not sure how trigger scrollToIndex with a functional component. Below is my new 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})} />
);
};
推荐答案
我认为您应该使用FlatList
FlatList具有方法scrollToIndex
,该方法可以直接转到您的数据项.它与ScrollView几乎相同,但更智能.遗憾的是,该文档非常差.
FlatList have a method scrollToIndex
that allows to directly go to an item of your datas. It's almost the same as a ScrollView but smarter. Sadly the documentation is very poor.
这是我做过的FlatList的示例
Here is an example of a FlatList I did
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/docs/flatlist #__ docusaurus
More about FlatList : https://facebook.github.io/react-native/docs/flatlist#__docusaurus
这篇关于我如何在React Native ListView中将项目居中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!