Для програми, подібної до чату, я хочу залишити ScrollView
компонент прокрученим донизу, оскільки найновіші повідомлення з’являються під старими. Чи можемо ми відрегулювати положення прокрутки a ScrollView
?
Для програми, подібної до чату, я хочу залишити ScrollView
компонент прокрученим донизу, оскільки найновіші повідомлення з’являються під старими. Чи можемо ми відрегулювати положення прокрутки a ScrollView
?
Відповіді:
Для React Native 0.41 і пізніших версій ви можете зробити це за допомогою вбудованого scrollToEnd
методу:
<ScrollView
ref={ref => {this.scrollView = ref}}
onContentSizeChange={() => this.scrollView.scrollToEnd({animated: true})}>
</ScrollView>
root
інакше, scrollToEnd не визначено. тобтоthis.scrollView.root.scrollToEnd
root
фактично видає невизначену помилку.
ref={ref => {this.scrollView = ref}}
оскільки ви не хочете повертати завдання
Використовуйте 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);
Ось найпростіше рішення, яке я міг зібрати:
<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
});
}}
/>;
Для тих, хто пише компонент функції, який може використовувати хук,
import React, { useRef } from 'react';
import { ScrollView } from 'react-native';
const ScreenComponent = (props) => {
const scrollViewRef = useRef();
return (
<ScrollView
ref={scrollViewRef}
onContentSizeChange={() => scrollViewRef.current.scrollToEnd({ animated: true })}
/>
);
};
спробуйте це рішення
xcode 10.0
RN: 56.0.0
<ScrollView ref="scrollView"
onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}> </ScrollView> // OR height - width
ref=
? здається реліквією веб-розробника
Якщо хтось у 2020 році чи пізніше задається питанням, як цього досягти за допомогою функціональних компонентів. Ось як я зробив:
ref={ref => scrollView = ref }
onContentSizeChange={() => scrollView.scrollToEnd({ animated: true })}>
Ви можете інвертувати вид прокрутки / списку за допомогою 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
перевертає весь вміст подання. Зверніть увагу, що діти представлення також відображатимуться у порядку, зворотному до звичайного вигляду - перша дитина з’явиться внизу .
Насправді відповідь @Aniruddha у мене не спрацювала, тому що я використовую, "react-native": "0.59.8"
а this.scrollView.root.scrollToEnd
також невизначена
але я зрозумів це, і це працює this.scrollView.scrollResponderScrollToEnd({animated: true});
Якщо ви використовуєте, 0.59.8
це буде працювати АБО якщо ви використовуєте пізнішу версію, і це працює для вас. будь ласка, додайте версії у цій відповіді, щоб інші не отримували проблем.
Повний код тут
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollResponderScrollToEnd({animated: true});
}}>
</ScrollView>
Цей метод трохи хакі, але кращого способу я не знайшов
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>
);
}
scrollToBottom
робить такі підходи застарілими в нових версіях React Native.
Це відповідає на ваше запитання: https://stackoverflow.com/a/39563100/1917250
Вам потрібно постійно прокручувати сторінку внизу, обчислюючи висоту вмісту мінус висоту його scrollView.
Якщо ви використовуєте TypeScript, вам потрібно це зробити
interface Props extends TextInputProps {
scrollRef?: any;
}
export class Input extends React.Component<Props, any> {
scrollRef;
constructor(props) {
this.scrollRef = React.createRef();
}
<ScrollView
ref={ref => (this.scrollRef = ref)}
onContentSizeChange={() => {
this.scrollRef.scrollToEnd();
}}
>
</ScrollView>
Я боровся з цим деякий час і нарешті придумав щось, що для мене працювало дуже добре та гладко. Як і багато, я намагався .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>
);
}
}
Я думаю, що пізно відповідати, але я отримав один хак! Якщо ви використовуєте, FlatList
ви можете ввімкнути inverted
властивість, яка повертається до transform scale
значення -1
(що прийнятно для інших компонентів списку, таких як ScrollView
...). Коли ви надаєте свої FlatList
дані, вони завжди будуть внизу!
Спробуйте встановити властивість contentOffset для подання прокрутки на поточну висоту вмісту.
Щоб досягти того, що вам потрібно, ви можете зробити це як частину події onScroll. Однак це може спричинити погану взаємодію з користувачем, тому може виявитись більш зручним для користувача, якщо робити це лише тоді, коли додається нове повідомлення.
ScrollView
вниз до нижче все його зміст, а не просто прокрутка вниз.
У мене була подібна проблема, але після прочитання цієї сторінки (від якої мені болить голова!) Я знайшов цей дуже приємний пакет npm, який просто інвертує ListView і полегшує все для програми чату !!
ScrollView
, а не `ListView`).
Трохи пізно ... але подивіться на це питання. Прокрутіть до початку ScrollView
ScrollView має метод "scrollTo".