web-dev-qa-db-fra.com

Empêcher Flatlist inversée de défiler vers le bas lorsque de nouveaux éléments sont ajoutés

Je construis une application de chat, en utilisant un Flatlist inversé. J'ajoute de nouveaux éléments en haut de la liste lorsque onEndReached est appelé et que tout fonctionne bien.

Le problème est que si vous ajoutez des éléments en bas, il défile instantanément vers le bas de la liste. Cela signifie que l'utilisateur doit faire défiler vers le haut pour lire les messages qui viennent d'être ajoutés (ce qui est terrible).

J'ai essayé d'appeler scrollToOffset dans onContentSizeChange, mais cela a un délai d'une seconde où le défilement saute d'avant en arrière.

Comment puis-je faire en sorte que la liste se comporte de la même manière lorsque j'ajoute des éléments en haut ET en bas, en gardant les mêmes messages à l'écran au lieu d'afficher les nouveaux?

5
Ryan Pergent

Avez-vous essayé d'utiliser keyExtractor? Cela peut aider à réagir pour éviter le rendu, essayez donc d'utiliser des clés uniques pour chaque élément. vous pouvez en savoir plus ici: https://reactnative.dev/docs/flatlist#keyextractor

0
Al Ped

Ici, j'ajoute un nouvel élément en haut et en bas dans une Flatlist inversée .

enter image description here

J'espère que vous pourrez comparer vos besoins avec l'exemple de code fourni :)

Code complet:


import React, {Component} from 'react';
import {
  SafeAreaView,
  View,
  FlatList,
  StyleSheet,
  Text,
  Button,
  Platform,
  UIManager,
  LayoutAnimation,
} from 'react-native';

if (Platform.OS === 'Android') {
  if (UIManager.setLayoutAnimationEnabledExperimental) {
    UIManager.setLayoutAnimationEnabledExperimental(true);
  }
}

const getRandomColor = () => {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
};

const DATA = [
  getRandomColor(),
  getRandomColor(),
  getRandomColor(),
  getRandomColor(),
  getRandomColor(),
];

export default class App extends Component {
  scrollValue = 0;
  append = true;

  state = {
    data: DATA,
  };

  addItem = (top) => {
    const {data} = this.state;
    let newData;
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    if (top) {
      newData = [...data, getRandomColor()];
      this.setState({data: newData});
    } else {
      newData = [getRandomColor(), ...data];
      this.setState({data: newData});
    }
  };

  shouldComponentUpdate() {
    return this.scrollValue === 0 || this.append;
  }

  onScrollBeginDrag = () => {
    this.append = true;
    LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
    this.setState({});
  };

  render() {
    const {data} = this.state;
    return (
      <SafeAreaView style={styles.container}>
        <Button title="ADD ON TOP" onPress={() => this.addItem(true)} />
        <FlatList
          data={data}
          onScrollBeginDrag={this.onScrollBeginDrag}
          renderItem={({item}) => <Item item={item} />}
          keyExtractor={(item) => item}
          inverted
          onScroll={(e) => {
            this.append = false;
            this.scrollValue = e.nativeEvent.contentOffset.y;
          }}
        />
        <Button title="ADD ON BOTTOM" onPress={() => this.addItem(false)} />
      </SafeAreaView>
    );
  }
}

function Item({item}) {
  return (
    <View style={[styles.item, {backgroundColor: item}]}>
      <Text style={styles.title}>{item}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    height: 100,
  },
  title: {
    fontSize: 32,
  },
});

0
Aswin C