สำหรับแอปที่คล้ายการแชทฉันต้องการให้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
});
}}
/>;
สำหรับใครก็ตามที่เขียนส่วนประกอบของฟังก์ชันที่สามารถใช้ 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 })}
/>
);
};
ในกรณีที่ทุกคนในปี 2020 หรือใหม่กว่านั้นสงสัยว่าจะทำสิ่งนี้ได้อย่างไรด้วยส่วนประกอบที่ใช้งานได้ นี่คือวิธีที่ฉันทำ:
ref={ref => scrollView = ref }
onContentSizeChange={() => scrollView.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=
อะไร? ดูเหมือนของที่ระลึกนักพัฒนาเว็บ
คุณสามารถพลิกกลับมุมมองเลื่อน / รายการโดยใช้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 ต่อไปนี้แทน a 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"