React-Native прокрутите вверх с помощью Flatlist
У меня много проблем с прокруткой до верхней части моего Flatlist, поэтому любая помощь будет принята с благодарностью!
По сути, он выбирает первые 5 элементов из firebase, затем, когда вызывается onEndReached, мы добавляем следующие 5 элементов в список:
data: [...this.state.data, ...results]
На данный момент у меня есть кнопка обновления в верхней части моего просмотра, которая выполняет следующие действия:
this.flatListRef.scrollToOffset({ animated: true, y: 0 });
Если я щелкну по нему, когда будут отображены первые 5 элементов, он прокручивается в верхнюю часть списка, как и ожидалось. Проблема возникает только после того, как список был добавлен (я полагаю, что элементы не видны?).
Я также пробовал "ScrollToItem", однако, полагаю, это не работает из-за следующего из документов React Native:
Примечание. Невозможно прокрутить до мест за пределами окна рендеринга, не указав реквизит getItemLayout.
Может кто-нибудь объяснить, что происходит, или знать, что я делаю не так?
Заранее спасибо!
getItemLayout: (не совсем уверен, что это делает или как определить длину, смещение и т. д.)
getItemLayout = (data, index) => (
{ length: 50, offset: 50 * index, index }
)
return (
<View>
<FlatList
ref={(ref) => { this.flatListRef = ref; }}
onScroll={this.handleScroll}
data={this.state.data}
keyExtractor={item => item.key}
ListFooterComponent={this.renderFooter()}
onRefresh={this.handleRefresh}
refreshing={this.state.newRefresh}
onEndReached={this.handleEndRefresh}
onEndReachedThreshold={0.05}
getItemLayout={this.getItemLayout}
renderItem={this.renderItem}
/>
{this.state.refreshAvailable ? this.renderRefreshButton() : null}
</View>
);
5 ответов
Правильный синтаксис
this.flatListRef.scrollToOffset({ animated: true, offset: 0 });
и вы также можете использовать
На всякий случай, если кто-то не понимает, как это сделать с помощью хуков, вот пример
function MyComponent() {
const flatListRef = React.useRef()
const toTop = () => {
// use current
flatListRef.current.scrollToOffset({ animated: true, offset: 0 })
}
return (
<FlatList
ref={flatListRef}
data={...}
...
/>
)
}
Основное отличие состоит в том, что вы получаете к нему доступ через .current
Если кому интересно, как использовать хуки для React:
-
import React, {useRef} from 'react'
- объявить ->
const flatListRef = useRef()
- установить это как
ref={flatListRef}
- назови это как
flatListRef.current.scrollToOffset({animated: false, offset: yourOffset})
Метод ниже решил мою проблему. Проверьте это:
const flatList = useRef();
const moveToTop = () => flatList.current.scrollToIndex({ index: 0 });
return (
<View>
<FlatList
ref={flatList}
onScroll={this.handleScroll}
data={this.state.data}
keyExtractor={item => item.key}
ListFooterComponent={this.renderFooter()}
onRefresh={this.handleRefresh}
refreshing={this.state.newRefresh}
onEndReached={this.handleEndRefresh}
onEndReachedThreshold={0.05}
getItemLayout={this.getItemLayout}
renderItem={this.renderItem}
/>
{this.state.refreshAvailable ? this.renderRefreshButton() : null}
</View>
);
Как добавить прокрутку вверх в FlatList в приложении ReactNative
В этом ответе я упомянул очень простой фрагмент кода, в котором есть две кнопки для прокрутки списка вправо или влево. Вы можете использовать этот код для достижения других вариантов использования программной прокрутки плоского списка.
//import
import React, { useEffect, useState, useRef, useCallback } from 'react';
//React class declaration.
const DocumentsInfo = ({ route, navigation }) => {
//state variable
const [documentsArray, setDocumentsArray] = useState({}); // array being shown in flatlist.
const [maxVisibleIndex, setMaxVisibleIndex] = useState(0); // highest visible index currently visible.
const [minVisibleIndex, setMinVisibleIndex] = useState(0); // lowest visible index currently visible.
const flatListRef = useRef() // reference of flatlist.
// callback for whenever flatlist scrolls
const _onViewableItemsChanged = useCallback(({ viewableItems, changed }) => {
setMaxVisibleIndex(viewableItems[viewableItems.length - 1].index);
setMinVisibleIndex(viewableItems[0].index);
}, []);
// function for scrolling to top
const scrollToTop = () => {
setMinVisibleIndex(0);
setMaxVisibleIndex(0);
flatListRef.current.scrollToIndex({ index: 0, animated: true });
};
// function for scrolling to bottom
const scrollToBottom = () => {
let temp = documentsArray.length - 1;
setMinVisibleIndex(temp);
setMaxVisibleIndex(temp);
flatListRef.current.scrollToIndex({ index: temp, animated: true });
};
// function for moving flatlist left and right by 1 index
const moveNextPreviousHorizontalFlatlist = (isNext) => {
if (isNext) {
let maxVisible = maxVisibleIndex + 1;
if (maxVisible < documentsArray.length) {
let minVisible = minVisibleIndex + 1;
setMinVisibleIndex(minVisible);
setMaxVisibleIndex(maxVisible);
flatListRef.current.scrollToIndex({ index: maxVisible, animated: true });
}
}
else {
let minVisible = minVisibleIndex - 1;
if (minVisible >= 0) {
let maxVisible = maxVisibleIndex - 1;
setMinVisibleIndex(minVisible);
setMaxVisibleIndex(maxVisible);
flatListRef.current.scrollToIndex({ index: minVisible, animated: true });
}
}
};
// UI
return (
<View>
{ maxVisibleIndex != documentsArray.length - 1 &&
<View style={styles.Refresh}>
<TouchableOpacity onPress={() =>
moveNextPreviousHorizontalFlatlist(true)
}>
<Image style={styles.Refresh} source={Refresh} />
</TouchableOpacity>
</View>
}
<FlatList
ref={flatListRef}
onViewableItemsChanged={_onViewableItemsChanged}
showsHorizontalScrollIndicator={false}
horizontal
keyExtractor={(item, index) => item.fileName + index}
data={documentsArray}
renderItem={({ item, index }) => {
return ( <DocumentListItem /> )
}}
/>
{ minVisibleIndex != 0 &&
<View style={styles.Refresh}>
<TouchableOpacity onPress={() =>
moveNextPreviousHorizontalFlatlist(false)
}>
<Image style={styles.Refresh} source={Refresh} />
</TouchableOpacity>
</View>
}
</View>
);