带有 ScrollView 的 RefreshControl 每次刷新都会向下移动屏幕内容

问题描述 投票:0回答:2

我有一个带有 ScrollView 的屏幕,该屏幕具有刷新控件属性。 事实证明,当我刷新屏幕时,屏幕的整个内容会向下移动几个位置。如果我再次刷新,它就会继续下降,依此类推。

enter image description here enter image description here

此屏幕截图是在刷新之前和刷新之后拍摄的。正如您所看到的,刷新后屏幕顶部添加了一些空间。为什么?

这是我的渲染函数中的内容:

render() {
  if(this.state.isLoading || this.state.user === null) {
   // IF I PUT RETURN NULL HERE IT WORKS FINE,AND THE CONTENT DOESNT GO DOWN
    return(<ScrollView contentContainerStyle={{alignItems: "center", flex: 1, justifyContent: 'center'}}>
      <Spinner isVisible={true} size={100} type={'Pulse'} color={'#013773'}/>
      <DropdownAlert ref={ref => this.dropDownAlertRef = ref} /> 
    </ScrollView>);
  }
  else {
    return (
      <ScrollView
      refreshControl={
        <RefreshControl
          refreshing={this.state.isLoading}
          onRefresh={this._onRefresh.bind(this)}
        />
      }>
        <View style={styles.whiteContainer}>
          <View style={{backgroundColor: colors.white,paddingVertical: 10, borderStyle: 'solid', borderColor: colors.black}}>
              <Text style={{fontStyle: 'italic', fontWeight: 'bold', fontSize:20, marginLeft:20, color: colors.grey}}>
                Mis donaciones
              </Text>
          </View>
          {this.state.myDonations.length > 0 ? 
          <Carousel
            ref={(c) => { this._carousel = c; }}
            data={this.state.myDonations}
            renderItem={this._renderDonation}
            sliderWidth={SLIDER_WIDTH}
            itemWidth={ITEM_WIDTH2}
            inactiveSlideShift={0}
            onSnapToItem={(index) => this.setState({ index })}
            scrollInterpolator={scrollInterpolator}
            slideInterpolatedStyle={animatedStyles}
            useScrollView={true}
            />: 
            <Text style={{fontStyle: 'italic', alignSelf: 'center', fontWeight: 'bold', fontSize:20, marginTop:20, marginBottom: 40, color: colors.grey}}>
            ¡Nada para mostrar!
          </Text>}
        </View>
        {this.state.user.category === "Voluntario" ? 
        <View style={styles.whiteContainer2}>
        <View style={{backgroundColor: colors.white,paddingVertical:10, borderStyle: 'solid', borderColor: colors.black}}>
            <Text style={{fontStyle: 'italic', fontWeight: 'bold', fontSize:20, marginLeft:20, color: colors.grey}}>
              Mis entregas
            </Text>
        </View>
        {this.state.myDeliveries.length > 0 ? 
        <Carousel
        ref={(c) => { this._carousel = c; }}
        data={this.state.myDeliveries}
        renderItem={this._renderDelivery}
        sliderWidth={SLIDER_WIDTH}
        itemWidth={ITEM_WIDTH2}
        inactiveSlideShift={0}
        onSnapToItem={(index) => this.setState({ index })}
        scrollInterpolator={scrollInterpolator}
        slideInterpolatedStyle={animatedStyles}
        useScrollView={true}
      /> : <Text style={{fontStyle: 'italic', alignSelf: 'center', fontWeight: 'bold', fontSize:20, marginTop:20, marginBottom: 40, color: colors.grey}}>
      ¡Nada para mostrar!
    </Text>}
      </View>
        : null}
        <View style={styles.whiteContainer2}>
          <View style={{backgroundColor: colors.white, paddingVertical:10, borderStyle: 'solid', borderColor: colors.black}}>
              <Text style={{fontStyle: 'italic', fontWeight: 'bold', fontSize:20, marginLeft:20, color: colors.grey}}>
                Pedidos
              </Text>
          </View>
          {this.state.requests.length > 0 ? 
          <Carousel
              ref={(c) => { this._carousel = c; }}
              data={this.state.requests}
              renderItem={this._renderRequest}
              sliderWidth={SLIDER_WIDTH}
              itemWidth={ITEM_WIDTH}
              inactiveSlideShift={0}
              onSnapToItem={(index) => this.setState({ index })}
              scrollInterpolator={scrollInterpolator}
              slideInterpolatedStyle={animatedStyles}
              useScrollView={true}
            /> : <Text style={{fontStyle: 'italic', alignSelf: 'center', fontWeight: 'bold', fontSize:20, marginTop:20, marginBottom: 40, color: colors.grey}}>
            ¡Nada para mostrar!
          </Text>}
        </View>
        <DropdownAlert ref={ref => this.dropDownAlertRef = ref} /> 
      </ScrollView>
    );
  }
}

_onRefresh 看起来像这样:

_onRefresh = () => {   
  this.setState({
    user: null,
    isLoading: true
  });
}
当 componentDidUpdate 内的方法完成加载时,

isLoading 随后被设置为 false。

我正在从“react-native”导入 RefreshControl 和 ScrollView:“~0.61.4”。

更新:正如您在我的渲染方法中看到的,我得到了一个 if-else 语句。事实证明,如果我将 return null 而不是我的微调器放在第一个块内,问题就解决了。为什么?

javascript react-native
2个回答
2
投票

好的,我发现了问题。 如您所见,我的渲染方法中有一个条件 if-else 语句。 结果我还必须将 RefreshControl 添加到语句第一个块的 ScrollView 中。

render() {
  if(this.state.isLoading || this.state.user === null) {
    return(
    <ScrollView contentContainerStyle={{alignItems: "center", flex: 1, justifyContent: 'center'}}
    refreshControl={
      <RefreshControl
        refreshing={false}
        onRefresh={this._onRefresh.bind(this)}
      />
    }>
      ...
    </ScrollView>);
  }
  else {
    return (
      <ScrollView
      refreshControl={
        <RefreshControl
          refreshing={this.state.isLoading}
          onRefresh={this._onRefresh.bind(this)}
        />
      }>
        ...
      </ScrollView>
    );
  }
}

0
投票

不需要双重渲染条件,只需添加

key
。当按键更改其触发器以重新安装 ui 时,只需修复

render() {
    return(
       <ScrollView
       key={`${this.state.isRefreshing}`}
       refreshControl={
         <RefreshControl
           refreshing={this.state.isRefreshing}
           onRefresh={this._onRefresh.bind(this)}
         />
       }>
         ...
       </ScrollView>
    );
}
© www.soinside.com 2019 - 2024. All rights reserved.