对于类似聊天的应用程序,我希望将ScrollView
组件滚动到底部,因为最新消息显示在较旧的消息下方。我们可以调整a的滚动位置ScrollView
吗?
对于类似聊天的应用程序,我希望将ScrollView
组件滚动到底部,因为最新消息显示在较旧的消息下方。我们可以调整a的滚动位置ScrollView
吗?
Answers:
对于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 })}
/>
);
};
如果有人在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”方法。