我正在构建一个应用程序,其中有一个名为<SearchBar />
的可实现标头,其具有支持isCollaped
(值可以为true或false),用于打开和关闭容器,以及{{1 (下面的截图,抱歉没有英文文本)。
应用的屏幕截图:
我想在开始滚动<ScrollView />
时展开<SearchBar />
,因此我将<ScrollView />
的值设置为true,并且它有效,但由于isCollaped
每隔200毫秒调用<ScrollView />
,并且在释放手指后滚动动画不停止,当我尝试通过按下它再次打开onScroll
时,如果滚动动画仍处于活动状态,我会得到一个非常错误的动画,再次折叠<SearchBar />
。
这部分代码在按下时会调整SearchBar的大小:
<SearchBar />
这是collapseSearchBar = () => {
this.setState({
searchBarCollapsed: !this.state.searchBarCollapsed,
});
};
:
<SearchBar/>
这是<SearchBar
isCollapsed={this.state.searchBarCollapsed}
onCollapse={this.collapseSearchBar}
onSearch={this.search}
/>
的代码:
<ScrollView />
我的问题是:当用户滑动时,我怎样才能进行一次<ListView
ref='mainScrollView'
dataSource={this.state.dataSource}
renderRow={(rowData) => {
return this._renderRow(rowData, this.props.navigation);
}}
onScroll={() => {
if (!this.state.searchBarCollapsed) {
this.setState({
searchBarCollapsed: true
});
}
}}
/>
调用<ScrollView />
,而不是所有时间(每200毫秒,动画开始后约3秒),动画处于活动状态。
答案 0 :(得分:0)
您可以使用scrollEventThrottle
道具来设置scroll
事件的触发频率。
<强> scrollEventThrottle 强>
它控制滚动时触发滚动事件的频率 (以ms为单位的时间间隔)。数字越小,精度越高 跟踪滚动位置的代码,但可以导致滚动 由于发送的信息量导致的性能问题 这座桥。您不会注意到设置值之间的差异 当JS运行循环同步到屏幕刷新率时,在1到16之间。 如果您不需要精确滚动位置跟踪,请设置此值 更高以限制通过网桥发送的信息。该 默认值为零,这会导致发送滚动事件 每次滚动视图时只会执行一次。
但我认为这不会解决你的问题。您可以做些什么来设置第二个状态值(类似isAnimating
),并在设置标题动画之前检查它。动画结束后,您可以将其设置为false。
示例强>
<ListView
ref='mainScrollView'
dataSource={this.state.dataSource}
renderRow={(rowData) => {
return this._renderRow(rowData, this.props.navigation);
}}
onScroll={() => {
if (!this.state.searchBarCollapsed) {
this.setState({
searchBarCollapsed: true,
isAnimating: true
});
}
}}
/>
collapseSearchBar = () => {
this.interval = setInterval(() => {
if (this.state.isAnimating === false) {
this.setState({
searchBarCollapsed: !this.state.searchBarCollapsed,
isAnimating: true
});
clearInterval(this.interval);
this.interval = null;
}
}, 100)
};
答案 1 :(得分:0)
就我而言,我必须在向上滚动一次和向下滚动一次时为视图设置动画。基本上,它就像在向下滚动时显示视图并在向上滚动时隐藏它一样。由于在滚动时多次调用函数,因此在视图中会产生闪烁效果。所以我创建了一个状态'scrollDown)。
const [scrollDown, setScrollDown] = useState(true)
在我的情况下,最初 scrollDown 将为真,表明用户将首先向下滚动。动画会执行,因为它是真,它也会更新自己为假,所以下次动画不会执行。当然,!scrollDown 会给出 true 但那些代码不会执行,因为它们是向上滚动的。因此,一旦用户向上滚动,scrollDown 值将更新并遵循相同的逻辑。
const _toogleNavigationBtn = (event) => {
const currentOffset = event.nativeEvent.contentOffset.y;
if(scrollDown)
if(currentOffset > offset && offset > 0 ){
setScrollDown(prevState => !prevState)
Animated.timing(navigationBtnY,{
toValue: 50,
duration: 700,
easing: Easing.out(Easing.exp)
}).start();
}
const contentSize = parseInt(event.nativeEvent.contentSize.height)
const scrolledSize = parseInt(currentOffset + event.nativeEvent.layoutMeasurement.height)
if(!scrollDown)
if(offset === 0 || currentOffset < offset || contentSize == scrolledSize){
setScrollDown(prevState => !prevState)
Animated.timing(navigationBtnY,{
toValue: 0,
duration: 700,
easing: Easing.out(Easing.exp)
}).start();
}
setOffset(prevState => currentOffset)
}