Для приложения, подобного чату, я хочу, чтобы компонент ScrollView
прокручивался снизу, потому что самые новые сообщения появляются под более старыми. Можем ли мы отрегулировать положение прокрутки ScrollView
?
Можно ли прокручивать ScrollView до конца?
Ответ 1
Для React Native 0.41 и более поздних scrollToEnd
вы можете сделать это со встроенным методом scrollToEnd
:
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollToEnd({animated: true});
}}>
</ScrollView>
Ответ 2
Используйте onContentSizeChange, чтобы отслеживать нижний Y прокрутки (высота)
https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
var _scrollToBottomY
<ScrollView
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollToBottomY = contentHeight;
}}>
</ScrollView>
затем используйте имя ссылки вида прокрутки, как
this.refs.scrollView.scrollTo(_scrollToBottomY);
Ответ 3
Вот самое простое решение, которое я мог бы собрать:
<ListView
ref={ref => (this.listView = ref)}
onLayout={event => {
this.listViewHeight = event.nativeEvent.layout.height;
}}
onContentSizeChange={() => {
this.listView.scrollTo({
y: this.listView.getMetrics().contentLength - this.listViewHeight
});
}}
/>;
Ответ 4
попробуйте это решение
xcode 10.0
RN: 56,0,0
<ScrollView ref="scrollView"
onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}> </ScrollView> // OR height - width
Ответ 5
Вы можете инвертировать представление прокрутки/списка с помощью модуля react-native-invertible-scroll-view
, а затем просто вызвать ref.scrollTo(0)
для прокрутки вниз.
Установите модуль:
npm install --save react-native-invertible-scroll-view
Затем импортируйте компонент:
import InvertibleScrollView from 'react-native-invertible-scroll-view';
Затем используйте следующий JSX вместо ScrollView
:
<InvertibleScrollView inverted
ref={ref => { this.scrollView = ref; }}
onContentSizeChange={() => {
this.scrollView.scrollTo({y: 0, animated: true});
}}
>
{ /* content */ }
</InvertibleScrollView>
Это работает, потому что react-native-invertible-scroll-view
обратной связью с обратной связью с обратной связью переворачивает весь контент представления. Обратите внимание, что дети с представлением также будут отображаться в обратном порядке к нормальному виду - первый ребенок появится внизу.
Ответ 6
Этот метод немного взломан, но я не смог найти лучший способ
- Сначала добавьте ссылку на свой ScrollView.
- Второе добавьте фиктивный вид перед закрытием тега ScrollView
- Получить позицию y этого макета.
- Всякий раз, когда вы хотите прокрутить вниз, прокрутите до положения макета.
var footerY; //Y position of the dummy view
render() {
return (
<View>
<ScrollView
ref='_scrollView'>
// This is where all the things that you want to display in the scroll view goes
// Below is the dummy View
<View onLayout={(e)=> {
footerY = e.nativeEvent.layout.y;
}}/>
</ScrollView>
//Below is the button to scroll to the bottom
<TouchableHighlight
onPress={() => { this.refs._scrollView.scrollTo(footerY); }}>
<Text>Scroll to Bottom</Text>
</TouchableHighlight>
</View>
);
}
Ответ 7
Это отвечает на ваш вопрос: fooobar.com/questions/133894/...
Вам нужно постоянно прокручивать нижнюю часть страницы, вычисляя высоту содержимого за вычетом высоты его scrollView.
Ответ 8
Возможно, это поможет кому-то с подобными проблемами при работе с элементами в списке.
Это позволит прокрутить до предыдущего элемента в списке. Я использую его в приложении для обмена сообщениями.
<FlatList
data={data.messages}
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollToIndex({index: data.messages.length - 2});
}}
renderItem={({item}) => this.renderItem(item)}
/>
Ответ 9
Некоторое время я боролся с этим и, наконец, придумал что-то, что сработало очень хорошо и гладко для меня. Как и многие, я пытался .scrollToEnd
безрезультатно. Решение, которое сработало для меня, заключалось в комбинации onContentSizeChange
, onLayout
реквизита и немного большего визуального осмысления того, "что в действительности означает прокрутка до дна". Последняя часть кажется мне тривиальной, но мне потребовалось вечно, чтобы понять.
Учитывая, что ScrollView
имеет фиксированную высоту, когда высота содержимого превышает высоту контейнера, я рассчитал смещение, вычтя prevHeight
(фиксированная высота ScrollView
) для currHeight
(высота содержимого), Если вы можете визуально представить это, прокрутив эту разницу по оси Y, сдвиньте высоту содержимого над своим контейнером на это смещение. Я увеличил свое смещение и сделал текущую высоту содержимого моей предыдущей высотой и продолжал вычислять новое смещение.
Вот код Надеюсь, это кому-нибудь поможет.
class ChatRoomCorrespondence extends PureComponent {
currHeight = 0;
prevHeight = 0;
scrollHeight = 0;
scrollToBottom = () => {
this.refs.scrollView.getScrollResponder().scrollResponderScrollTo({
x: 0,
y: this.scrollHeight,
animated: true
});
};
render() {
return (
<ScrollView
style={Styles.container}
ref="scrollView"
onContentSizeChange={(w, h) => {
this.currHeight = h;
if (
this.prevHeight > 0 &&
this.currHeight - this.scrollHeight > this.prevHeight
) {
this.scrollHeight += this.currHeight - this.prevHeight;
console.log("--------------------------------------------");
console.log("Curr: ", this.currHeight);
console.log("Prev: ", this.prevHeight);
console.log("Scroll: ", this.scrollHeight);
this.prevHeight = this.currHeight;
console.log("PREV: ", this.prevHeight);
console.log("--------------------------------------------");
this.scrollToBottom();
}
}}
onLayout={ev => {
// Fires once
const fixedContentHeight = ev.nativeEvent.layout.height;
this.prevHeight = fixedContentHeight;
}}
>
<FlatList
data={this.props.messages}
renderItem={({ item }) => (
<ChatMessage
text={item.text}
sender={item.sender}
time={item.time}
username={this.props.username}
/>
)}
keyExtractor={(item, index) => index.toString()}
/>
</ScrollView>
);
}
}
Ответ 10
Я думаю, что уже слишком поздно, чтобы ответить, но я получил один взлом! Если вы используете FlatList
, вы можете активировать свойство inverted
, которое возвращается к установке transform scale
на -1
(что приемлемо для других компонентов списка, таких как ScrollView
...). Когда вы визуализируете свой FlatList
с данными, он всегда будет внизу!
Ответ 11
Попробуйте установить свойство contentOffset прокрутки в соответствии с текущей высотой содержимого.
Чтобы выполнить то, что вам нужно, вы можете сделать это как часть события onScroll. Однако это может привести к плохому пользовательскому опыту, поэтому может оказаться более удобным для пользователя, если это произойдет только при добавлении нового сообщения.
Ответ 12
У меня была аналогичная проблема, но после прочтения этой страницы (которая дает мне головную боль!) я нахожу этот очень приятный пакет npm, который просто инвертируйте ListView и упростите приложение чата!
Ответ 13
Немного поздно... но посмотри на этот вопрос. Прокрутите вверх страницы ScrollView
ScrollView имеет метод "scrollTo".