Đối với một ứng dụng giống như trò chuyện, tôi muốn giữ một ScrollView
thành phần được cuộn xuống dưới cùng, vì các tin nhắn mới nhất xuất hiện bên dưới các tin nhắn cũ hơn. Chúng ta có thể điều chỉnh vị trí cuộn của a ScrollView
không?
Đối với một ứng dụng giống như trò chuyện, tôi muốn giữ một ScrollView
thành phần được cuộn xuống dưới cùng, vì các tin nhắn mới nhất xuất hiện bên dưới các tin nhắn cũ hơn. Chúng ta có thể điều chỉnh vị trí cuộn của a ScrollView
không?
Câu trả lời:
Đối với React Native 0.41 trở lên , bạn có thể thực hiện việc này bằng scrollToEnd
phương pháp tích hợp:
<ScrollView
ref={ref => {this.scrollView = ref}}
onContentSizeChange={() => this.scrollView.scrollToEnd({animated: true})}>
</ScrollView>
root
cách khác, scrollToEnd là không xác định. tức làthis.scrollView.root.scrollToEnd
root
thực sự tạo ra một lỗi không xác định.
ref={ref => {this.scrollView = ref}}
vì bạn không muốn trả lại bài tập
Sử dụng onContentSizeChange để theo dõi phần Y dưới cùng của chế độ xem cuộn (chiều cao)
https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
var _scrollToBottomY
<ScrollView
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollToBottomY = contentHeight;
}}>
</ScrollView>
sau đó sử dụng tên tham chiếu của chế độ xem cuộn như
this.refs.scrollView.scrollTo(_scrollToBottomY);
Đây là giải pháp đơn giản nhất mà tôi có thể tập hợp:
<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
});
}}
/>;
Đối với bất kỳ ai viết thành phần hàm có thể sử dụng hook,
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 })}
/>
);
};
thử giải pháp này
xcode 10.0
RN: 56.0.0
<ScrollView ref="scrollView"
onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}> </ScrollView> // OR height - width
ref=
? có vẻ giống như một di tích của nhà phát triển web
Trong trường hợp bất kỳ ai trong năm 2020 hoặc sau đó đang tự hỏi làm thế nào để đạt được điều này với các thành phần chức năng. Đây là cách tôi đã làm:
ref={ref => scrollView = ref }
onContentSizeChange={() => scrollView.scrollToEnd({ animated: true })}>
Bạn có thể đảo ngược chế độ xem cuộn / danh sách bằng cách sử dụng react-native-invertible-scroll-view
mô-đun , sau đó chỉ cần gọi ref.scrollTo(0)
để cuộn xuống dưới cùng.
Cài đặt mô-đun:
npm install --save react-native-invertible-scroll-view
Sau đó nhập thành phần:
import InvertibleScrollView from 'react-native-invertible-scroll-view';
Sau đó, sử dụng JSX sau thay vì ScrollView
:
<InvertibleScrollView inverted
ref={ref => { this.scrollView = ref; }}
onContentSizeChange={() => {
this.scrollView.scrollTo({y: 0, animated: true});
}}
>
{ /* content */ }
</InvertibleScrollView>
Điều này hoạt động vì react-native-invertible-scroll-view
lật toàn bộ nội dung của chế độ xem. Lưu ý rằng con của chế độ xem cũng sẽ hiển thị theo thứ tự ngược lại với chế độ xem bình thường - con đầu tiên sẽ xuất hiện ở dưới cùng .
Trên thực tế, câu trả lời @Aniruddha không phù hợp với tôi vì tôi đang sử dụng "react-native": "0.59.8"
và this.scrollView.root.scrollToEnd
cũng không được xác định
nhưng tôi đã tìm ra và điều này hoạt động this.scrollView.scrollResponderScrollToEnd({animated: true});
Nếu bạn đang sử dụng, 0.59.8
điều này sẽ hoạt động HOẶC nếu bạn đang sử dụng phiên bản mới hơn và điều này phù hợp với bạn. vui lòng thêm các phiên bản trong câu trả lời này để những người khác không gặp rắc rối.
Mã đầy đủ tại đây
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollResponderScrollToEnd({animated: true});
}}>
</ScrollView>
Phương pháp này hơi hack một chút nhưng tôi không thể tìm ra cách tốt hơn
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
cách tiếp cận như thế này đã trở nên lỗi thời trong các phiên bản React Native mới hơn.
Điều này trả lời câu hỏi của bạn: https://stackoverflow.com/a/39563100/1917250
Bạn cần phải liên tục cuộn đến cuối trang bằng cách tính chiều cao của nội dung trừ đi chiều cao của scrollView.
Nếu bạn sử dụng TypeScript Bạn cần thực hiện việc này
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>
Tôi đã đấu tranh với điều này trong một thời gian và cuối cùng đã tìm ra thứ gì đó hoạt động thực sự hiệu quả và suôn sẻ cho tôi. Giống như nhiều người, tôi đã cố gắng .scrollToEnd
nhưng không có kết quả. Các giải pháp mà làm việc cho tôi là sự kết hợp của onContentSizeChange
, onLayout
đạo cụ và hơn một chút suy nghĩ trực quan về "những gì di chuyển xuống đáy" thực sự có nghĩa. Phần cuối cùng có vẻ tầm thường đối với tôi bây giờ, nhưng tôi đã mất mãi mãi để tìm ra.
Giả sử rằng ScrollView
có chiều cao cố định, khi chiều cao nội dung vượt quá chiều cao của vùng chứa, tôi đã tính toán phần bù bằng cách trừ prevHeight
(chiều cao cố định của ScrollView
) cho currHeight
(chiều cao nội dung). Nếu bạn có thể hình dung trực quan nó, hãy cuộn đến sự khác biệt đó trong trục y, trượt chiều cao nội dung trên vùng chứa của nó bằng khoảng chênh lệch đó. Tôi đã tăng độ lệch của mình và đặt chiều cao nội dung hiện tại của tôi bằng chiều cao trước đó của tôi và tiếp tục tính toán bù mới.
Đây là mã. Hy vọng nó sẽ giúp một ai đó.
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>
);
}
}
Tôi đoán là đã quá muộn để trả lời nhưng tôi đã nhận được một lần hack! Nếu bạn sử dụng FlatList
bạn có thể bật inverted
bất động sản rơi trở lại thiết lập transform scale
để -1
(đó là chấp nhận được cho các thành phần khác như danh sách ScrollView
...). Khi bạn kết xuất FlatList
dữ liệu của mình, nó sẽ luôn ở dưới cùng!
Hãy thử đặt thuộc tính contentOffset của dạng xem cuộn thành chiều cao hiện tại của nội dung.
Để hoàn thành những gì bạn cần, bạn có thể thực hiện việc này như một phần của sự kiện onScroll. Tuy nhiên, điều này có thể gây ra trải nghiệm người dùng không tốt vì vậy việc chỉ làm điều này có thể thân thiện hơn với người dùng khi có thêm thư mới.
ScrollView
xuống bên dưới tất cả nội dung của nó, thay vì chỉ cuộn xuống cuối.
Tôi đã gặp vấn đề tương tự, nhưng sau khi đọc trang này (khiến tôi đau đầu!) Tôi thấy gói npm rất đẹp này chỉ đảo ngược ListView và làm cho mọi thứ trở nên dễ dàng cho một ứng dụng trò chuyện !!
ScrollView
, không phải về `ListView`).
Hơi muộn ... nhưng hãy xem câu hỏi này. Cuộn lên đầu ScrollView
ScrollView có phương thức "scrollTo".