Evitar que el Flatlist invertido se desplace hacia abajo cuando se añaden nuevos elementos

votos
41

Estoy construyendo una aplicación de chat, usando una aplicación invertidaFlatlist. Añado nuevos elementos a la parte superior de la lista cuando onEndReachedse llama y todo funciona bien.

El problema es que si añades elementos al final, instantáneamente se desplaza al final de la lista. Eso significa que el usuario tiene que desplazarse hacia arriba para leer los mensajes que acaban de ser añadidos (lo cual es terrible).

Intenté llamarscrollToOffsetonContentSizeChange, pero esto tiene un retraso de un segundo en el que el pergamino salta de un lado a otro.

¿Cómo puedo hacer que la lista se comporte de la misma manera cuando agrego elementos en la parte superior Y en la parte inferior, manteniendo los mismos mensajes en la pantalla en lugar de mostrar los nuevos?

Publicado el 26/05/2020 a las 14:44
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
0

¿Has probado a usar KeyExtractor? Puede ayudar a reaccionar y evitar la repetición de la operación, así que intenta usar claves únicas para cada artículo. puedes leer más sobre ello aquí: https://reactnative.dev/docs/flatlist#keyextractor

Respondida el 26/05/2020 a las 18:35
fuente por usuario

votos
0

aquí está la demostración: https://snack.expo.io/@nomi9995/flatlisttest

Solución 1:

usar los accesorios de maintainVisibleContentPosition para prevenir el auto desplazamiento en IOS pero desafortunadamente, no funciona en el androide.

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

Solución 2:

Encontré otra solución: mantener la última compensación y con onScroll y también guardar la altura del contenido antes y después de añadir nuevos elementos con onContentSizeChange y calcular la diferencia de altura del contenido, y establecer la nueva compensación y con la última diferencia de altura del contenido y

Respondida el 28/05/2020 a las 15:36
fuente por usuario

votos
0

Aquí estoy agregando un nuevo artículo en la parte superior e inferior en un Flatlist invertido.

enter image description here

Espero que pueda comparar sus requerimientos con el código de muestra proporcionado :)

Código completo:

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,
  },
});
Respondida el 30/05/2020 a las 14:55
fuente por usuario

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