在 React Native 中滚动到 ScrollView 的底部
Scroll to bottom of ScrollView in React Native
我想找到一种以编程方式滚动到 scrollView 底部的方法。在查看 ScrollView 的源代码后,我知道了 scrollTo 方法,但是我似乎无法找到一种方法来测量 scrollView 的内容大小。
环顾四周后,我遇到了 this github 提到查看如何 "UIManager.measureX methods are used" 测量内容大小的问题。但是在源码中翻了好几遍,似乎都没有找到这些方法的用处。
有人能给我指出正确的方向吗?
它非常隐蔽,我 运行 进入了源代码。
你可以这样试试:
要求:
var RCTUIManager = require('NativeModules').UIManager;
渲染:
<ScrollView ref = {component=>{this._scrollView=component;}}>
</ScrollView>
事件:
someEvent: function() {
RCTUIManager.measure(this._scrollView.getInnerViewNode(), (...data)=>{console.log(data)});
}
从数据中可以得到高度为data
第四个元素的scrollview的contentsize。当然你可以从中获取内容偏移量。 运行 进入 RCTUIMananger.m
的源代码以获得更多详细信息。
当您使用getInnerViewNode
时,您可以获得ScrollView 内部视图的框架。如果要获取ScrollView的frame,应该使用React.findNodeHandle(this._scrollView)
,ScrollView的frame并不总是等于其内部视图的frame。
(更新)
如果你想用callback
替换(...data)=>{console.log(data)}
,你应该这样使用:
RCTUIManager.measure(this._scrollView.getInnerViewNode(), callback.bind(this));
有更好的方法来做到这一点。概括地说:
使用 ListView 呈现聊天。
<ListView
ref="list"
...
使用 renderFooter that uses onLayout 向列表添加页脚以保存其 y
位置。页脚不必渲染任何可见的东西,只是一个空的 View
。您要查找的只是列表底部所在的位置。
renderFooter={() => {
return <View onLayout={(e)=> {
this.footerY = e.nativeEvent.layout.y;
}}/>
}},
将 onLayout
处理程序添加到保存列表 height
的 ListView
本身。
onLayout={(e)=>{
this.listHeight = e.nativeEvent.layout.height;
}}
有了这两位信息,您可以滚动到列表底部,如下所示:
if (this.listHeight && this.footerY && this.footerY > this.listHeight) {
var scrollDistance = this.listHeight - this.footerY;
var scrollResponder = this.refs.list.getScrollResponder();
scrollResponder.scrollWithoutAnimationTo(-scrollDistance);
}
滚动到底部的频率由您决定,取决于您想要的行为。
一个实际的例子是 GiftedMessenger。
虽然 RCTUIManager.measure()
通过引用提取数据数组的第 4 个元素来工作,但在使用 ScrollViews 时使用以下内容更合适(也更容易):
回复:https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
onContentSizeChange={( contentWidth, contentHeight ) => {
this._contentHeight = contentHeight
}}
一旦内部子组件完成布局并发生更改,就会触发此事件。这对我有用,我在确定内容范围时推荐这种受支持的方法。
你可以使用 ScrollView 的 scrollToEnd() 方法:
https://facebook.github.io/react-native/docs/scrollview.html#scrolltoend
根据文档:
如果这是一个垂直的ScrollView滚动到底部。如果这是一个水平滚动视图向右滚动。
<ScrollView ref={scrollView => this.scrollView = scrollView}
onContentSizeChange={( contentWidth, contentHeight ) => {
this._contentHeight = contentHeight;
console.log('Height: ' + this._contentHeight);
this.scrollView.scrollTo({ y: this._contentHeight , animated: true})
}}>
我想找到一种以编程方式滚动到 scrollView 底部的方法。在查看 ScrollView 的源代码后,我知道了 scrollTo 方法,但是我似乎无法找到一种方法来测量 scrollView 的内容大小。
环顾四周后,我遇到了 this github 提到查看如何 "UIManager.measureX methods are used" 测量内容大小的问题。但是在源码中翻了好几遍,似乎都没有找到这些方法的用处。
有人能给我指出正确的方向吗?
它非常隐蔽,我 运行 进入了源代码。
你可以这样试试:
要求:
var RCTUIManager = require('NativeModules').UIManager;
渲染:
<ScrollView ref = {component=>{this._scrollView=component;}}>
</ScrollView>
事件:
someEvent: function() {
RCTUIManager.measure(this._scrollView.getInnerViewNode(), (...data)=>{console.log(data)});
}
从数据中可以得到高度为data
第四个元素的scrollview的contentsize。当然你可以从中获取内容偏移量。 运行 进入 RCTUIMananger.m
的源代码以获得更多详细信息。
当您使用getInnerViewNode
时,您可以获得ScrollView 内部视图的框架。如果要获取ScrollView的frame,应该使用React.findNodeHandle(this._scrollView)
,ScrollView的frame并不总是等于其内部视图的frame。
(更新)
如果你想用callback
替换(...data)=>{console.log(data)}
,你应该这样使用:
RCTUIManager.measure(this._scrollView.getInnerViewNode(), callback.bind(this));
有更好的方法来做到这一点。概括地说:
使用 ListView 呈现聊天。
<ListView
ref="list"
...
使用 renderFooter that uses onLayout 向列表添加页脚以保存其 y
位置。页脚不必渲染任何可见的东西,只是一个空的 View
。您要查找的只是列表底部所在的位置。
renderFooter={() => {
return <View onLayout={(e)=> {
this.footerY = e.nativeEvent.layout.y;
}}/>
}},
将 onLayout
处理程序添加到保存列表 height
的 ListView
本身。
onLayout={(e)=>{
this.listHeight = e.nativeEvent.layout.height;
}}
有了这两位信息,您可以滚动到列表底部,如下所示:
if (this.listHeight && this.footerY && this.footerY > this.listHeight) {
var scrollDistance = this.listHeight - this.footerY;
var scrollResponder = this.refs.list.getScrollResponder();
scrollResponder.scrollWithoutAnimationTo(-scrollDistance);
}
滚动到底部的频率由您决定,取决于您想要的行为。
一个实际的例子是 GiftedMessenger。
虽然 RCTUIManager.measure()
通过引用提取数据数组的第 4 个元素来工作,但在使用 ScrollViews 时使用以下内容更合适(也更容易):
回复:https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
onContentSizeChange={( contentWidth, contentHeight ) => {
this._contentHeight = contentHeight
}}
一旦内部子组件完成布局并发生更改,就会触发此事件。这对我有用,我在确定内容范围时推荐这种受支持的方法。
你可以使用 ScrollView 的 scrollToEnd() 方法:
https://facebook.github.io/react-native/docs/scrollview.html#scrolltoend
根据文档: 如果这是一个垂直的ScrollView滚动到底部。如果这是一个水平滚动视图向右滚动。
<ScrollView ref={scrollView => this.scrollView = scrollView}
onContentSizeChange={( contentWidth, contentHeight ) => {
this._contentHeight = contentHeight;
console.log('Height: ' + this._contentHeight);
this.scrollView.scrollTo({ y: this._contentHeight , animated: true})
}}>