Hindre at omvendt flatlist blar til bunn når nye elementer legges til

stemmer
45

Jeg bygger en chat-app, bruker en omvendt Flatlist . Jeg legger til nye elementer øverst på listen når onEndReached heter og alt fungerer fint.

Problemet er at hvis du legger elementer til bunnen, ruller det øyeblikkelig til bunnen av listen. Det betyr at brukeren må bla tilbake for å lese meldingene som nettopp ble lagt til (noe som er forferdelig).

Jeg prøvde å ringe scrollToOffset i onContentSizeChange , men dette har en sekunders forsinkelse der rullen hopper frem og tilbake.

Hvordan kan jeg få listen til å oppføre seg på samme måte når jeg legger til elementer øverst OG til bunnen ved å holde de samme meldingene på skjermen i stedet for å vise de nye?

Publisert på 26/05/2020 klokken 14:44
kilden bruker
På andre språk...                            


3 svar

stemmer
0

Har du prøvd å bruke keyExtractor? Det kan hjelpe å reagere på å unngå gjengivelse, så prøv å bruke unike taster for hvert element. du kan lese mer om det her: https://reactnative.dev/docs/flatlist#keyextractor

Svarte 26/05/2020 kl. 18:35
kilden bruker

stemmer
0

her er demo: https://snack.expo.io/@nomi9995/flatlisttest

Løsning 1:

bruk maintenanceVisibleContentPosition- rekvisitter for å forhindre autoscroll i IOS, men dessverre fungerer det ikke på Android.

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

Løsning 2:

Jeg fant en annen løsning ved å holde siste y forskjøvet med onScroll og også lagre innholdshøyde før og etter å ha lagt til nye elementer med onContentSizeRendre og beregne forskjellen på innholdshøyde, og sett ny y forskyvning til den siste y forskyvningen av innholdshøydeforskjellen!

Svarte 28/05/2020 kl. 15:36
kilden bruker

stemmer
0

Her legger jeg til et nytt element på toppen og bunnen i en omvendt Flatlist .

legg inn bildebeskrivelse her

Jeg håper du kan sammenligne dine krav med den oppgitte eksempelskoden :)

Full kode:

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,
  },
});
Svarte 30/05/2020 kl. 14:55
kilden bruker

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