From 0218c71e8ce556e004dac04576369eb404a03adc Mon Sep 17 00:00:00 2001 From: friedolin Date: Wed, 24 Aug 2022 17:25:44 +0200 Subject: [PATCH] feat: support for min index --- .../scroll/ScrollView.java | 5 ++-- src/FlatList.tsx | 3 +- src/config.ts | 1 + src/hooks/usePrerenderedData.tsx | 29 +++++++++++-------- 4 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 src/config.ts diff --git a/android/src/main/java/com/reactnativebidirectionalflatlist/scroll/ScrollView.java b/android/src/main/java/com/reactnativebidirectionalflatlist/scroll/ScrollView.java index 3b9dc73..ed793ed 100644 --- a/android/src/main/java/com/reactnativebidirectionalflatlist/scroll/ScrollView.java +++ b/android/src/main/java/com/reactnativebidirectionalflatlist/scroll/ScrollView.java @@ -38,10 +38,11 @@ public void setShiftOffset(double shiftOffset) { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { super.onLayoutChange(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom); + int shiftHeight = Math.min(bottom - oldBottom, (int)mShiftHeight); int scrollWindowHeight = getHeight() - getPaddingBottom() - getPaddingTop(); - if(mShiftHeight != 0 && mShiftOffset <= getScrollY() + scrollWindowHeight / 2) { + if(mShiftHeight != 0 && shiftHeight > 0 && mShiftOffset <= getScrollY() + scrollWindowHeight / 2) { // correct - scrollTo(0, getScrollY() + (int)mShiftHeight); + scrollTo(0, getScrollY() + shiftHeight); if(getOverScrollerFromParent() != null && !getOverScrollerFromParent().isFinished()) { // get current directed velocity from scroller int direction = getOverScrollerFromParent().getFinalY() - getOverScrollerFromParent().getStartY() > 0 ? 1 : -1; diff --git a/src/FlatList.tsx b/src/FlatList.tsx index f5cd894..d8b8480 100644 --- a/src/FlatList.tsx +++ b/src/FlatList.tsx @@ -3,8 +3,9 @@ import { FlatList as FlatListRN, LayoutChangeEvent, Platform, ScrollViewProps, S import { ScrollView } from './ScrollView'; import { usePrerenderedData } from './hooks/usePrerenderedData'; import type { BidirectionalFlatListProps, FlatListType } from './types'; +import { MIN_INDEX } from './config'; -const maintainVisibleContentPosition = { minIndexForVisible: 1 }; +const maintainVisibleContentPosition = { minIndexForVisible: MIN_INDEX }; const FlatListImpl = forwardRef((props, ref) => { const renderScrollComponent = useCallback((props: ScrollViewProps) => { diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..f2da17e --- /dev/null +++ b/src/config.ts @@ -0,0 +1 @@ +export const MIN_INDEX = 1; diff --git a/src/hooks/usePrerenderedData.tsx b/src/hooks/usePrerenderedData.tsx index cbe28b8..2c54fcc 100644 --- a/src/hooks/usePrerenderedData.tsx +++ b/src/hooks/usePrerenderedData.tsx @@ -1,6 +1,7 @@ import React, { MutableRefObject, ReactNode, useCallback, useEffect, useRef, useState } from 'react'; import { FlatListProps, LayoutChangeEvent, View } from 'react-native'; import type { FlatListType, OnUpdateData, RenderItem } from '../types'; +import { MIN_INDEX } from '../config'; type OnLayout = (options: {id: string; height: number}) => void; @@ -41,13 +42,15 @@ export const usePrerenderedData = ({data, keyExtractor, renderItem, scrollRef, o return p; }, {}); const index = data.findIndex((d) => d === newD[0]); - const shift = { - height: newD.reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), - offset: data.slice(0, index).reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), - }; - scrollRef.current?.shift(shift); + if(index > 0 && index <= MIN_INDEX) { + const shift = { + height: newD.reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), + offset: data.slice(0, index).reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), + }; + scrollRef.current?.shift(shift); + onUpdateData?.({heights: heightsRef.current, ...shift}); + } setFinalData(data); - onUpdateData?.({heights: heightsRef.current, ...shift}); return; } setNewData(data.filter((d, i) => !heightsRef.current[keyExtractor(d, i)])); @@ -67,14 +70,16 @@ export const usePrerenderedData = ({data, keyExtractor, renderItem, scrollRef, o return; } const index = data.findIndex((d) => d === newData[0]); - const shift = { - height: newData.reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), - offset: data.slice(0, index).reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), - }; - scrollRef.current?.shift(shift); + if(index > 0 && index <= MIN_INDEX) { + const shift = { + height: newData.reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), + offset: data.slice(0, index).reduce((p, c, i) => p + heightsRef.current[keyExtractor(c, i)], 0), + }; + scrollRef.current?.shift(shift); + onUpdateData?.({heights: heightsRef.current, ...shift}); + } setNewData([]); setFinalData(data); - onUpdateData?.({heights: heightsRef.current, ...shift}); }, [data, keyExtractor, newData, onUpdateData, scrollRef]); return {