-
Notifications
You must be signed in to change notification settings - Fork 106
Description
Describe the bug
When a Popover is triggered to appear on Android, anchored to a View via a ref passed to the from prop, the initial rendering animation exhibits a "jitter". The popover briefly appears at one position, then quickly jumps slightly (e.g., ~1cm visually) to its final, correct position. This happens very fast but is noticeable. The issue does not occur on iOS.
Here is how I use it:
import { useRef, useState } from 'react'
import { View, Text, TouchableOpacity } from 'react-native'
import Popover, { PopoverPlacement } from 'react-native-popover-view'
export default function ContactScreen() {
const [popoverVisible, setPopoverVisible] = useState(false)
const buttonRef = useRef<View>(null)
const handleButtonPress = () => {
setPopoverVisible(true)
}
const closePopover = () => {
setPopoverVisible(false)
}
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TouchableOpacity onPress={handleButtonPress}>
{/* Inner View receives the ref */}
<View
ref={buttonRef}
collapsable={false}
renderToHardwareTextureAndroid={true}
style={{ padding: 10, backgroundColor: 'lightblue' }}
>
<Text>Show Popover</Text>
</View>
</TouchableOpacity>
<Popover
debug={true}
isVisible={popoverVisible}
from={buttonRef}
onRequestClose={closePopover}
popoverStyle={{ borderRadius: 8, padding: 10 }}
placement={PopoverPlacement.TOP} // Explicit placement
animationConfig={{ duration: 1 }} // Minimal animation
>
<Text>Test Popover Content</Text>
</Popover>
</View>
)
}Device/Setup Info:
- Device: [Xioami 10T Pro]
- OS: [MIUI 14.0.1]
react-nativeversion: [0.76] (Expo)react-native-popover-viewversion: [6.1.0]
Screenshots
I recorded a video: https://drive.google.com/file/d/1MAFdmk5hs-XCzzuyGe65y-vjFoiONrTc/view?usp=sharing
Debug Output
I opened and closed the modal:
(NOBRIDGE) LOG Config for development environment validated successfully
(NOBRIDGE) LOG [2025-04-16T16:45:18.459Z] calculateRectFromRef - waiting for ref
(NOBRIDGE) LOG [2025-04-16T16:45:18.463Z] calculateRectFromRef - waiting for ref to move from: {"x":0,"y":0,"width":0,"height":0}
(NOBRIDGE) LOG [2025-04-16T16:45:18.484Z] calculateRectFromRef - calculated Rect: {"x":151.27273559570312,"y":450.54544830322266,"width":90.54545593261719,"height":19.272735595703125}
(NOBRIDGE) LOG [2025-04-16T16:45:18.519Z] setDefaultDisplayArea - newDisplayArea: {"x":0,"y":0.00004438920450411388,"width":392.7272644042969,"height":825.4545288085938}
(NOBRIDGE) LOG [2025-04-16T16:45:18.520Z] setDefaultDisplayArea - displayAreaOffset: {"x":0,"y":0}
(NOBRIDGE) LOG [2025-04-16T16:45:18.544Z] [BasePopover] componentDidUpdate - changedProps: ["displayArea"]
(NOBRIDGE) LOG [2025-04-16T16:45:18.548Z] componentDidUpdate - isVisible not changed, handling other changes
(NOBRIDGE) LOG [2025-04-16T16:45:18.551Z] handleChange - no requestedContentSize, exiting...
(NOBRIDGE) LOG [2025-04-16T16:45:18.554Z] calculateRectFromRef - waiting for ref
(NOBRIDGE) LOG [2025-04-16T16:45:18.555Z] calculateRectFromRef - waiting for ref to move from: {"x":151.27273559570312,"y":450.54544830322266,"width":90.54545593261719,"height":19.272735595703125}
(NOBRIDGE) LOG [2025-04-16T16:45:18.557Z] measureContent - new requestedContentSize: {"width":168.00001525878906,"height":78.9090576171875} (used to be null)
(NOBRIDGE) LOG [2025-04-16T16:45:18.578Z] handleChange - waiting 100ms to accumulate all changes
(NOBRIDGE) LOG [2025-04-16T16:45:18.689Z] handleChange - requestedContentSize: {"width":168.00001525878906,"height":78.9090576171875}
(NOBRIDGE) LOG [2025-04-16T16:45:18.690Z] handleChange - displayArea: {"x":0,"y":0.00004438920450411388,"width":392.7272644042969,"height":825.4545288085938}
(NOBRIDGE) LOG [2025-04-16T16:45:18.691Z] handleChange - fromRect: {"x":151.27273559570312,"y":450.54544830322266,"width":90.54545593261719,"height":19.272735595703125}
(NOBRIDGE) LOG [2025-04-16T16:45:18.691Z] handleChange - placement: "auto"
(NOBRIDGE) LOG [2025-04-16T16:45:18.691Z] computeAutoGeometry - displayArea: {"x":0,"y":0.00004438920450411388,"width":392.7272644042969,"height":825.4545288085938}
(NOBRIDGE) LOG [2025-04-16T16:45:18.692Z] computeAutoGeometry - fromRect: {"x":151.27273559570312,"y":450.54544830322266,"width":90.54545593261719,"height":19.272735595703125}
(NOBRIDGE) LOG [2025-04-16T16:45:18.692Z] computeAutoGeometry - List of available space: {"left":{"sizeAvailable":135.27273559570312,"sizeRequested":168.00001525878906,"fits":false,"extraSpace":-32.72727966308594},"right":{"sizeAvailable":134.90907287597656,"sizeRequested":168.00001525878906,"fits":false,"extraSpace":-33.0909423828125},"top":{"sizeAvailable":434.54540391401815,"sizeRequested":78.9090576171875,"fits":true,"extraSpace":355.63634629683065},"bottom":{"sizeAvailable":339.6363892988725,"sizeRequested":78.9090576171875,"fits":true,"extraSpace":260.727331681685}}
(NOBRIDGE) LOG [2025-04-16T16:45:18.693Z] computeAutoGeometry - Found best postition for placement: "top"
(NOBRIDGE) LOG [2025-04-16T16:45:18.693Z] computeGeometry - initial chosen geometry: {"popoverOrigin":{"x":112.54545593261719,"y":363.63639068603516},"anchorPoint":{"x":196.54546356201172,"y":450.54544830322266},"placement":"top","forcedContentSize":{"width":372.7272644042969,"height":432.54540391401815},"viewLargerThanDisplayArea":{"height":false,"width":false}}
(NOBRIDGE) LOG [2025-04-16T16:45:18.694Z] computeGeometry - final chosen geometry: {"popoverOrigin":{"x":112.54545593261719,"y":363.63639068603516},"anchorPoint":{"x":196.54546356201172,"y":450.54544830322266},"placement":"top","forcedContentSize":{"width":372.7272644042969,"height":432.54540391401815},"viewLargerThanDisplayArea":{"height":false,"width":false}}
(NOBRIDGE) LOG [2025-04-16T16:45:18.714Z] handleChange - animating in
(NOBRIDGE) LOG [2025-04-16T16:45:18.718Z] getTranslateOrigin - popoverSize: {"width":168.00001525878906,"height":86.9090576171875}
(NOBRIDGE) LOG [2025-04-16T16:45:18.721Z] getTranslateOrigin - anchorPoint: {"x":196.54546356201172,"y":450.54544830322266}
(NOBRIDGE) LOG [2025-04-16T16:45:18.730Z] animateIn - translateStart: {"x":112.54545593261719,"y":1992.5454649491744}
(NOBRIDGE) LOG [2025-04-16T16:45:18.734Z] animateIn - translatePoint: {"x":112.54545593261719,"y":363.63639068603516}
(NOBRIDGE) LOG [2025-04-16T16:45:18.743Z] Setting up keyboard listeners
(NOBRIDGE) LOG [2025-04-16T16:45:19.126Z] animateIn - onOpenComplete - Calculated Popover Rect: {"x":112.54545593261719,"y":363.6363525390625,"width":168.00001525878906,"height":78.9091796875}
(NOBRIDGE) LOG [2025-04-16T16:45:19.127Z] animateIn - onOpenComplete - Calculated Arrow Rect: {"x":188.5454559326172,"y":440.727294921875,"width":18.181808471679688,"height":10.181884765625}
(NOBRIDGE) LOG [2025-04-16T16:45:20.631Z] measureContent - Skipping, content size did not change
(NOBRIDGE) LOG [2025-04-16T16:45:20.680Z] [BasePopover] componentDidUpdate - changedProps: ["isVisible"]
(NOBRIDGE) LOG [2025-04-16T16:45:20.683Z] componentDidUpdate - isVisible changed, now false
(NOBRIDGE) LOG [2025-04-16T16:45:20.686Z] animateOut - isMounted: true
(NOBRIDGE) LOG [2025-04-16T16:45:20.689Z] getTranslateOrigin - popoverSize: {"width":168.00001525878906,"height":86.9090576171875}
(NOBRIDGE) LOG [2025-04-16T16:45:20.692Z] getTranslateOrigin - anchorPoint: {"x":196.54546356201172,"y":450.54544830322266}
(NOBRIDGE) LOG [2025-04-16T16:45:20.697Z] componentDidUpdate - Hiding popover
(NOBRIDGE) LOG [2025-04-16T16:45:20.727Z] Tearing down keyboard listeners