Voorkomen dat omgekeerde Flatlist naar beneden scrollt als er nieuwe items worden toegevoegd

stemmen
1

Ik ben een chat app aan het bouwen, met behulp van een omgekeerde Flatlist. Ik voeg nieuwe items toe aan de top van de lijst wanneer onEndReacheddeze wordt opgeroepen en alles werkt prima.

Het probleem is dat als er items aan de onderkant worden toegevoegd, deze direct naar de onderkant van de lijst rollen. Dat betekent dat de gebruiker terug naar boven moet scrollen om de zojuist toegevoegde berichten te lezen (wat vreselijk is).

Ik heb geprobeerd om te bellenscrollToOffsetonContentSizeChange, maar dit heeft een vertraging van een seconde waarbij het scrollen heen en weer springt.

Hoe kan ik de lijst op dezelfde manier laten werken als ik items aan de bovenkant EN aan de onderkant toevoeg, door dezelfde berichten op het scherm te houden in plaats van de nieuwe te laten zien?

De vraag is gesteld op 26/05/2020 om 14:44
bron van user
In andere talen...                            


3 antwoorden

stemmen
0

Heb je het geprobeerd met keyExtractor? Het kan helpen om te reageren om herhalingen te voorkomen, dus probeer unieke sleutels te gebruiken voor elk item. u kunt er hier meer over lezen: https://reactnative.dev/docs/flatlist#keyextractor

antwoordde op 26/05/2020 om 18:35
bron van user

stemmen
0

hier is demo: https://snack.expo.io/@nomi9995/flatlisttest

Oplossing 1:

gebruik maintainVisibleContentPosition props om het automatisch scrollen in IOS te voorkomen, maar helaas werkt het niet op android.

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

Oplossing 2:

Ik heb een andere workaround gevonden door de laatste y offset te bewaren met onScroll en ook de hoogte van de inhoud op te slaan voor en na het toevoegen van nieuwe items met onContentSizeChange en het verschil van de hoogte van de inhoud te berekenen, en nieuwe y offset in te stellen op de laatste y offset hoogte van de inhoud!

antwoordde op 28/05/2020 om 15:36
bron van user

stemmen
0

Hier voeg ik een nieuw item toe aan de boven- en onderkant in een omgekeerde Flatlist.

enter image description here

Ik hoop dat u uw wensen kunt vergelijken met de meegeleverde voorbeeldcode :)

Volledige 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,
  },
});
antwoordde op 30/05/2020 om 14:55
bron van user

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