Empêcher que la Flatlist inversée ne défile vers le bas lorsque de nouveaux éléments sont ajoutés

voix
45

Je suis en train de créer une application de chat, en utilisant un Flatlist. J'ajoute de nouveaux éléments en haut de la liste lorsquonEndReached'on m'appelle et tout fonctionne bien.

Le problème est que si j'ajoute des éléments en bas de la liste, elle se déplace instantanément vers le bas de la liste. Cela signifie que l'utilisateur doit remonter pour lire les messages qui viennent d'être ajoutés (ce qui est terrible).

J'ai essayé d'appelerscrollToOffsetonContentSizeChange, mais il y a un délai d'une seconde où le défilement va et vient.

Comment faire pour 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 ?

Créé 26/05/2020 à 14:44
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
0

Avez-vous essayé d'utiliser keyExtractor ? Il peut vous aider à réagir en évitant de vous rendre à nouveau, alors essayez d'utiliser des clés uniques pour chaque objet. vous pouvez en savoir plus à ce sujet ici : https://reactnative.dev/docs/flatlist#keyextractor

Créé 26/05/2020 à 18:35
source utilisateur

voix
0

voici la démo : https://snack.expo.io/@nomi9995/flatlisttest

Solution 1 :

utiliser les accessoires maintainVisibleContentPosition pour empêcher le défilement automatique dans IOS mais malheureusement, cela ne fonctionne pas sur android.

<FlatList
  ref={(ref) => { this.chatFlatList = ref; }}
  style={styles.flatList}
  data={this.state.items}
  renderItem={this._renderItem}
  maintainVisibleContentPosition={{
     minIndexForVisible: 0,
  }}
/>

Solution 2 :

J'ai trouvé une autre solution en conservant le dernier décalage y avec onScroll et en enregistrant également la hauteur du contenu avant et après l'ajout de nouveaux éléments avec onContentSizeChange et en calculant la différence de hauteur du contenu, et en définissant un nouveau décalage y correspondant à la dernière différence de hauteur du contenu !

Créé 28/05/2020 à 15:36
source utilisateur

voix
0

Ici, j'ajoute un nouvel élément en haut et en bas d'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, {useState, createRef} from 'react';
import {
  SafeAreaView,
  View,
  FlatList,
  StyleSheet,
  Text,
  Button,
  Platform,
  UIManager,
} 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(),
];

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

let scrollValue = 0;
let itemHeight = 100;

export default function App() {
  const [data, setData] = useState(DATA);
  let flatList = createRef();

  const addItem = (top) => {
    let newData;
    if (top) {
      newData = [...data, getRandomColor()];
      setData(newData);
    } else {
      newData = [getRandomColor(), ...data];
      setData(newData);
      if (scrollValue > itemHeight) {
        flatList.current.scrollToOffset({
          offset: scrollValue + itemHeight,
          animated: false,
        });
      }
    }
  };

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

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  item: {
    backgroundColor: '#f9c2ff',
    padding: 20,
    height: itemHeight,
  },
  title: {
    fontSize: 32,
  },
});
Créé 30/05/2020 à 14:55
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more