Împiedicați lista plană inversată să deruleze în jos când sunt adăugate articole noi

voturi
45

Construiesc o aplicație de chat, folosind o inversare Flatlist . Adaug elemente noi în partea de sus a listei când onEndReached se numește și totul funcționează bine.

Problema este că, dacă adăugați elemente în partea de jos, se derulează instantaneu la partea de jos a listei. Aceasta înseamnă că utilizatorul trebuie să deruleze înapoi pentru a citi mesajele care tocmai au fost adăugate (ceea ce este groaznic).

Am încercat să sun scrollToOffset în onContentSizeChange , dar aceasta are o întârziere de o secundă în care defilarea sare înapoi și înapoi.

Cum pot face ca lista să se comporte la fel atunci când adaug elemente în partea de sus ȘI în jos , păstrând aceleași mesaje pe ecran în loc să le afișez pe cele noi?

Întrebat 26/05/2020 la 14:44
sursa de către utilizator
În alte limbi...                            


3 răspunsuri

voturi
0

Ați încercat să utilizați keyExtractor? Este posibil să vă ajute să reacționați să evitați redarea, așa că încercați să utilizați chei unice pentru fiecare articol. puteți citi mai multe despre asta aici: https://reactnative.dev/docs/flatlist#keyextractor

Publicat 26/05/2020 la 18:35
sursa de către utilizator

voturi
0

aici este demo: https://snack.expo.io/@nomi9995/flatlisttest

Soluția 1:

utilizarea maintainVisibleContentPosition recuzita pentru prevenirea defilare auto în IOS , dar , din păcate, nu este de lucru pe Android.

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

Soluția 2:

Am găsit o altă soluție, păstrând ultimul y offset cu onScroll și, de asemenea, economisesc înălțimea conținutului înainte și după adăugarea de articole noi cu onContentSizeChange și calculez diferența de înălțime a conținutului și am setat o nouă compensare y la ultima diferență de înălțime a conținutului offset!

Publicat 28/05/2020 la 15:36
sursa de către utilizator

voturi
0

Aici adaug un articol nou în partea de sus și de jos într-o listă plană inversată .

introduceți descrierea imaginii aici

Sper că puteți compara cerințele dvs. cu codul de eșantion furnizat :)

Cod 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,
  },
});
Publicat 30/05/2020 la 14:55
sursa de către utilizator

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