Реагирует на собственный список анимированных разделов, когда меняется состояние / реквизит - PullRequest
0 голосов
/ 28 мая 2019

Я создаю представление в собственном приложении с компонентом списка разделов, а также имеет заголовок, который будет отображать совокупные данные о списке.При прокрутке вид заголовка должен уменьшаться с анимацией.У меня все анимация работает нормально, но возникают проблемы при добавлении бесконечной прокрутки с помощью onEndreached prop.При добавлении новых данных или изменении состояния / реквизита, они переходят наверх списка.

Чтобы анимировать SectionList, я обернул его, используя Animated.createAnimatedComponent, чтобы создать <AnimatedSectionList /> компонент.Именно тогда, когда это обернуто с Анимированным, возникают проблемы.

В приведенном ниже gif вы можете увидеть, что он переходит в начало списка, когда я прокручиваю вниз.Это когда состояние меняется, и мы начинаем получать больше данных.https://monosnap.com/file/2aH5iPF2XcygEz381bpHW9QGPGHA2Z

Я пытался использовать getItemLayout для вычисления размера списка, надеясь, потому что я прочитал, что когда реакция не знает высоту списка, это может быть нервным.

Я также пытался прокрутить раздел после загрузки новых данных, используя 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>
    );
  }
}


Я ожидаю, что список останется в текущей прокручиваемой позиции, когда состояние или реквизит изменятся, но вместо этого он прыгнет на вершину, победив цель бесконечной прокрутки.

Буду признателен за любые мысли о том, как лучше подойти к этому вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...