1
donotquestion 1 天前
放弃吧,我研究了两周放弃了,傻逼 RN 不会按照你的想法的顺序走的,跳来跳去,双向滚动超级大坑
|
2
iOCZS 1 天前
相关代码看看?
|
3
jingrui 1 天前
我们还是用的 FlashList ,滚动到指定消息 很难优化
const firstScrollRef = useRef(false); function scrollToMsg(msgID){ let index = viewMessages.findIndex((value)=>value?.msgID === msgID) if (index <= 0) index = 1; console.log('scrollToMsg', index, msgID, viewMessages.length); flatListRef.current.scrollToIndex({ index:index-1, animated: true }); } const scrollToBottom = useCallback( debounce(() => { if (flatListRef.current) { console.log('scrollToBottom', firstScrollRef.current, from, msgID) IMSdk.readConversation(uid) if (!firstScrollRef.current) { if (from === 'history' && msgID) { scrollToMsg(msgID) } else { flatListRef.current.scrollToEnd({ animated: true }); } firstScrollRef.current = true } else { flatListRef.current.scrollToEnd({ animated: true }); } } }, 200), // 延迟时间可以根据需要调整 [from, msgID] ); |
4
letterLim OP const getMessageList = useMemo(() => (startPage: number, endPage: number) => {
return allMessageList .slice(startPage * PAGE_SIZE, (endPage + 1) * PAGE_SIZE) }, [allMessageList, PAGE_SIZE]) useEffect(() => { setMessageList(getMessageList(0, 0)) }, []) useEffect(() => { if (startPage === 0 && isAtBottom) { setMessageList(getMessageList(startPage, endPage)); } }, [startPage, endPage, getMessageList, isAtBottom]); const onReachTop = useCallback(() => { console.log('onReachTop'); if (isJumpingToUnread) { return; } if (startPage > 0) { const _startPage = startPage - 1; setStartPage(_startPage); setMessageList(getMessageList(_startPage, endPage)) } }, [startPage, isJumpingToUnread, endPage, getMessageList]); const onReachBottom = useCallback(() => { console.log('onReachBottom', isJumpingToUnread); if (isJumpingToUnread) { return; } if (messageList.length < allMessageList.length) { setEndPage(pre => { setMessageList(getMessageList(startPage, pre + 1)) return pre + 1 }) } }, [messageList.length, setEndPage, startPage, allMessageList.length, isJumpingToUnread, getMessageList]); const goUnreadMessage = useCallback(() => { setIsJumpingToUnread(true); setUnreadNum(0) let _messageList: any = [] const startPage = Math.floor(unreadNum / PAGE_SIZE) > 1 ? Math.floor(unreadNum / PAGE_SIZE) - 1 : 0; let endPage = startPage + 1; _messageList = getMessageList(startPage, endPage) const index = _messageList.findIndex(item => item._id === lastMessageId.current) if (index % PAGE_SIZE === 0) { endPage = startPage + 1 } setStartPage(startPage); setEndPage(endPage); setMessageList(_messageList) }, [allMessageList.length, getMessageList]); useEffect(() => { if (isJumpingToUnread && lastMessageId.current) { const index = messageList.findIndex(item => item._id === lastMessageId.current) if (index !== -1) { const timer = setTimeout(() => { clearTimeout(timer) flatListRef.current?.scrollToIndex({ index, animated: true, viewPosition: 0.1, }) }, 200) } } }, [messageList.length, isJumpingToUnread]); useEffect(() => { if (!lastMessageId.current && allMessageList.length >= (unreadNum-1) && unreadNum) { lastMessageId.current = allMessageList[unreadNum-1]?._id; } }, []); useEffect(() => { const initMessageList = () => { setStartPage(0) setEndPage(0) setMessageList(getMessageList(0, 0)) InteractionManager.runAfterInteractions(() => { flatListRef?.current?.scrollToOffset({ offset: 0, animated: true }) }) } EventCenter.on('init_message_list', initMessageList) return () => { EventCenter.remove('init_message_list', initMessageList) } }, [getMessageList]) const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => { const isBottom = event.nativeEvent.contentOffset.y <= 10; setIsAtBottom(isBottom); }, []); const onScrollToIndexFailed = useCallback((info: { index: number; highestMeasuredFrameIndex: number; averageItemLength: number; }) => { const offset = info.index * info.averageItemLength flatListRef.current?.scrollToOffset({ offset: offset, animated: true }) }, []); const threshold = isJumpingToUnread ? 0.1 : 1 <FlatList removeClippedSubviews windowSize={20} onStartReachedThreshold={threshold} onEndReachedThreshold={threshold} onEndReached={onReachBottom} onStartReached={onReachTop} onScroll={handleScroll} scrollEventThrottle={17} keyboardDismissMode="on-drag" maxToRenderPerBatch={10} initialNumToRender={10} onTouchStart={() => { setIsMore(false) setEmojiKeyboardVisible(false) }} onScrollBeginDrag={() => { setIsJumpingToUnread(false); }} maintainVisibleContentPosition={startPage && !isAtBottom ? { minIndexForVisible: 1, autoscrollToTopThreshold: 10 }:undefined} onScrollToIndexFailed={onScrollToIndexFailed} inverted contentContainerStyle={{ paddingHorizontal: 10 }} scrollsToTop={false} data={messageList} keyExtractor={item => item._id} showsVerticalScrollIndicator ref={flatListRef} renderItem={renderItem} |