Verhindern, dass die invertierte flache Liste nach unten scrollt, wenn neue Elemente hinzugefügt werden

stimmen
45

Ich baue eine Chat-Anwendung mit einer umgekehrten Flatlist. Ich füge neue Elemente an den Anfang der Liste hinzu, wenn onEndReachedsie aufgerufen wird, und alles funktioniert einwandfrei.

Das Problem besteht darin, dass beim Hinzufügen von Elementen am Ende der Liste sofort an das Ende der Liste gescrollt wird. Das bedeutet, dass der Benutzer zurück nach oben scrollen muss, um die gerade hinzugefügten Nachrichten zu lesen (was schrecklich ist).

Ich habe versucht, anzurufenscrollToOffsetonContentSizeChange, aber das hat eine Verzögerung von einer Sekunde, wo die Schriftrolle hin und her springt.

Wie kann ich erreichen, dass sich die Liste genauso verhält, wenn ich Elemente oben UND unten hinzufüge, indem ich dieselben Nachrichten auf dem Bildschirm lasse, anstatt die neuen anzuzeigen?

Veröffentlicht am 26/05/2020 um 14:44
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
0

Haben Sie versucht, keyExtractor zu verwenden? Es kann helfen zu reagieren, um eine erneute Darstellung zu vermeiden, also versuchen Sie, für jedes Element eindeutige Schlüssel zu verwenden. sie können hier mehr darüber lesen: https://reactnative.dev/docs/flatlist#keyextractor

Beantwortet am 26/05/2020 um 18:35
quelle vom benutzer

stimmen
0

hier ist die Demo: https://snack.expo.io/@nomi9995/flatlisttest

Lösung 1:

verwenden Sie die maintainVisibleContentPosition-Requisiten zur Verhinderung des automatischen Scrollens in IOS, aber leider funktioniert das nicht auf Android.

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

Lösung 2:

Ich fand eine weitere Abhilfe, indem ich mit onScroll den neuesten y-Offset beibehalte und auch die Inhaltshöhe vor und nach dem Hinzufügen neuer Elemente mit onContentSizeChange speichere und die Differenz der Inhaltshöhe berechne und den neuen y-Offset auf die neueste y-Offset-Inhaltshöhendifferenz setze!

Beantwortet am 28/05/2020 um 15:36
quelle vom benutzer

stimmen
0

Hier füge ich oben und unten in einer umgekehrten Flatlist ein neues Element hinzu.

enter image description here

Ich hoffe, Sie können Ihre Anforderungen mit dem mitgelieferten Beispielcode vergleichen :)

Vollständiger Code:

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,
  },
});
Beantwortet am 30/05/2020 um 14:55
quelle vom benutzer

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