diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dccce46a..8af1b1a49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +- Add support for `experimentalMaintainTopContentPosition` ## [1.4.0] - 2022-11-07 diff --git a/fixture/src/List.tsx b/fixture/src/List.tsx index 5bdf87cb6..b91e95f7e 100644 --- a/fixture/src/List.tsx +++ b/fixture/src/List.tsx @@ -9,45 +9,27 @@ import { Pressable, LayoutAnimation, StyleSheet, - Button, } from "react-native"; import { FlashList } from "@shopify/flash-list"; -import { useFocusEffect } from "@react-navigation/native"; -import { TouchableOpacity } from "react-native-gesture-handler"; -interface ListItem { - value: number; - type?: string; -} - -let newItemIndexes = 1001; - -const generateArray = (size: number): ListItem[] => { - const arr = new Array(size); +const generateArray = (size: number) => { + const arr = new Array(size); for (let i = 0; i < size; i++) { - arr[i] = { value: i }; + arr[i] = i; } - return arr; }; const List = () => { const [refreshing, setRefreshing] = useState(false); const [data, setData] = useState(generateArray(100)); - const [isLoading, setIsLoading] = useState(false); - const list = useRef | null>(null); - - useFocusEffect( - React.useCallback(() => { - newItemIndexes = 1001; - }, []) - ); + const list = useRef | null>(null); const removeItem = (item: number) => { setData( data.filter((dataItem) => { - return dataItem.value !== item; + return dataItem !== item; }) ); list.current?.prepareForLayoutAnimationRender(); @@ -55,81 +37,44 @@ const List = () => { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); }; - const renderItem = ({ item }: { item: ListItem }) => { - const backgroundColor = item.value % 2 === 0 ? "#00a1f1" : "#ffbb00"; - - // if (Number(item.value) >= 90 && Number(item.value) <= 99) { - // return ; - // } - // item.value % 2 === 0 - // ? 100 + (item.value > 1000 ? item.value / 10 : item.value) + 1 - // : 200 + (item.value > 1000 ? item.value / 10 : item.value), + const renderItem = ({ item }: { item: number }) => { + const backgroundColor = item % 2 === 0 ? "#00a1f1" : "#ffbb00"; return ( { - removeItem(item.value); + removeItem(item); }} > - Cell Id: {item.value} + Cell Id: {item} ); }; return ( - <> - { - setData([{ value: newItemIndexes++ }, ...data]); - }} - > - - ADD A NEW ITEM - - - - { - // setRefreshing(true); - // setTimeout(() => { - // setRefreshing(false); - // }, 2000); - // }} - keyExtractor={(item: ListItem) => { - return item.value.toString(); - }} - getItemType={(item: ListItem) => { - return item.type; - }} - renderItem={renderItem} - estimatedItemSize={100} - data={data} - drawDistance={250} - horizontal - // ListHeaderComponent={ - // - // {isLoading ? "LOADING" : ""} - // - // } - experimentalMaintainTopContentPosition - /> - + { + setRefreshing(true); + setTimeout(() => { + setRefreshing(false); + }, 2000); + }} + keyExtractor={(item: number) => { + return item.toString(); + }} + renderItem={renderItem} + estimatedItemSize={100} + data={data} + /> ); }; diff --git a/ios/Sources/AutoLayoutView.swift b/ios/Sources/AutoLayoutView.swift index c9ef1531a..e87bcfb34 100644 --- a/ios/Sources/AutoLayoutView.swift +++ b/ios/Sources/AutoLayoutView.swift @@ -50,12 +50,6 @@ import UIKit private var lastMaxBound: CGFloat = 0 /// Tracks where first pixel is drawn in the visible window private var lastMinBound: CGFloat = 0 - - /// Marks the first Item in the Scroll View - private var firstItemMarker: CellContainer? = nil - - /// The position of the item in the Scroll View after insertion / deletion - private var previousMarkerOffset: CGFloat = -1 /// State that informs us whether this is the first render private var isInitialRender: Bool = true diff --git a/src/FlashList.tsx b/src/FlashList.tsx index 50ff0116c..f10afb913 100644 --- a/src/FlashList.tsx +++ b/src/FlashList.tsx @@ -155,7 +155,6 @@ class FlashList extends React.PureComponent< prevState: FlashListState ): FlashListState { const newState = { ...prevState }; - if (prevState.numColumns !== nextProps.numColumns) { newState.numColumns = nextProps.numColumns || 1; newState.layoutProvider = FlashList.getLayoutProvider( @@ -167,8 +166,6 @@ class FlashList extends React.PureComponent< newState.numColumns, nextProps ); - // RLV retries to reposition the first visible item on layout provider change. - // It's not required in our case so we're disabling it } if (nextProps.data !== prevState.data) { newState.data = nextProps.data; @@ -183,6 +180,9 @@ class FlashList extends React.PureComponent< newState.extraData = { value: nextProps.extraData }; } newState.renderItem = nextProps.renderItem; + + // RLV retries to reposition the first visible item on layout provider change. + // It's not required in our case so we're disabling it newState.layoutProvider.shouldRefreshWithAnchoring = false; return newState; }