3

我正在一个带有部分列表组件的本机应用程序中构建一个视图,它上面还有一个标题,它将显示有关列表的聚合数据。滚动时,标题视图应该随着动画缩小。我的所有动画都可以正常工作,但是在使用onEndreached道具添加无限滚动时会出现问题。当添加新数据或状态/道具发生变化时,它会跳到列表的顶部。

为了使 SectionList 具有动画效果,我使用它来包装它Animated.createAnimatedComponent来创建一个<AnimatedSectionList />组件。当它被 Animated 包裹时,问题就出现了。

在下面链接的 gif 中,您可以看到当我向下滚动时它会跳到列表的顶部。这是状态发生变化并且我们开始获取更多数据的时候。 https://monosnap.com/file/2aH5iPF2XcygEz381bpHW9QGPGHA2Z

我尝试使用getItemLayout来计算列表大小,希望因为我读到当 react 不知道列表的高度时,它可能会很跳跃。

我也试过在加载新数据后滚动到一个部分,scrollTo但这也不起作用。我正在使用componentDidUpdate生命周期方法执行此操作,但是componentDidUpdate当新数据进来时并没有被一致地调用。

这是我的代码。


const DataItem = [
  { name: "test name", value: "testvalue" },
  { name: "test name", value: "testvalue" },
  { name: "test name", value: "testvalue" },
  { name: "test name", value: "testvalue" },
  { name: "test name", value: "testvalue" }
];

const initialSections = [
  { title: "MY DETAILS", data: DataItem },
  { title: "MY COMMUNITY", data: DataItem },
  { title: "MY FAMILY", data: DataItem }
];

const styles = {
  item: {
    flex: 1,
    height: 50,
    marginTop: 1,
    backgroundColor: "#dddddd"
  },
  sectionHeader: {
    flex: 1,
    height: 20,
    marginTop: 1,
    backgroundColor: "#00ff00"
  }
};



class Edit extends Component {
  constructor(props) {
    super(props);

    this.state = {
      scrollEnabled: true,
      scrollY: new Animated.Value(0),
      sections: initialSections,
      refreshing: false
    };


  _renderSectionHeader(section) {
    return (
      <View style={styles.sectionHeader}>
        <Text> {section.title} </Text>
      </View>
    );
  }

  _renderItem(item) {
    return (
      <View style={styles.item}>
        <Text>{item.name}</Text>
      </View>
    );
  }


  handleStateButton() {
    this.setState({ refreshing: true });
  }

  fetchMoreData() {
    this.setState({ refreshing: true });

    const newData = [...this.state.sections, ...initialSections];

    setTimeout(
      function() {
        this.setState({ sections: newData, refreshing: false });       }.bind(this),
      2000
    );
  }

  render() {
    const backgroundScrollY = this.state.scrollY.interpolate({
      inputRange: [0, 224],
      outputRange: [0, -50],
      extrapolate: "clamp"
    });

    const backgroundScrollHeight = this.state.scrollY.interpolate({
      inputRange: [0, 224],
      outputRange: [1, 0.75],
      extrapolate: "clamp"
    });

    const listScrollY = this.state.scrollY.interpolate({
      inputRange: [0, 224],
      outputRange: [0, -10],
      extrapolate: "clamp"
    });

    const infoOpacity = this.state.scrollY.interpolate({
      inputRange: [0, 0.5, 150],
      outputRange: [1, 1, 0],
      extrapolate: "clamp"
    });

    const AnimatedSectionList = Animated.createAnimatedComponent(SectionList);

    return (
      <View
        style={{
          flex: 1,
          //   alignItems: "flex-start",
          flexDirection: "column"
        }}
      >
        <Animated.View
          style={[
            {
              position: "relative",
              // flex: 1,
              // alignSelf: "flex-start",
              top: 0,
              minHeight: 200,
              height: 300,
              backgroundColor: "#ddee99",
              border: "1px solid #0000FF",
              justifyContent: "center",
              alignItems: "center"
            },
            { transform: [{ scaleY: backgroundScrollHeight }] }
          ]}
        >
          <Animated.Image
            source={{
              uri:
                "https://images.unsplash.com/photo-1558901591-3a5f333830dd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80"
            }}
            style={[
              { position: "absolute", backgroundColor: "#cccccc" },
              { transform: [{ translateY: backgroundScrollY }] }
            ]}
            blurRadius={1.5}
          />

          <Text>{this.state.refreshing && `Fetching data`}</Text>

          <Button onPress={this.fetchMoreData} title="Get More Data" />
          <Button onPress={this.handleStateButton} title="Changing State" />
        </Animated.View>

        <AnimatedSectionList
          ref={ref => (this.sectionListRef = ref)}
          bounces={false}
          scrollEnabled={this.state.scrollEnabled}
          style={[
            { position: "relative" },
            { transform: [{ translateY: listScrollY }] }
          ]}
          onScroll={Animated.event(
            [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
            { listener: this._onScroll.bind(this) }
          )}
          sections={this.state.sections}
          renderSectionHeader={({ section }) =>
            this._renderSectionHeader(section)
          }
          ListHeaderComponent={() => (
            <View
              style={{
                flex: 1,
                flexDirection: "row",
                alignItems: "center",
                height: 40,
                backgroundColor: "#ff00ff"
              }}
            >
              <Text>List Header</Text>
            </View>
          )}
          ListFooterComponent={() => (
            <View
              style={{
                flex: 1,
                flexDirection: "row",
                alignItems: "center",
                height: 80,
                backgroundColor: "#FF0"
              }}
            >
              <Text>List Footer</Text>
            </View>
          )}
          getItemLayout={this.getItemLayout}
          renderItem={({ item }) => this._renderItem(item)}
          keyExtractor={(item, index) => index}
          stickySectionHeadersEnabled={true}
          onEndReachedThreshold={0.75}
          onEndReached={d => {
            this.fetchMoreData();
          }}
        />
      </View>
    );
  }
}


我希望当状态或道具发生变化时,列表将保持在当前滚动位置,而是跳到顶部,违背了无限滚动的目的。

对于解决此问题的最佳方法的任何想法,我们将不胜感激。

4

1 回答 1

0

我把

const AnimatedSectionList = Animated.createAnimatedComponent(SectionList);

退出班级并停止跳到顶部

于 2020-10-28T22:13:43.183 回答