Android React Native Glue Stack UI中Action Sheet初始位置异常求助
问题
使用Expo React Native + Glue Stack UI开发项目时,添加Popover或Actionsheet后出现初始位置异常:Popover从屏幕中央弹出,Actionsheet从屏幕上方弹出,随后才会移动到触发它的橙色邮件Fab按钮的正确位置。
已尝试排查:
- 移除屏幕居中的
messagesScreenContainer样式,问题仍存在 - 找到过相关旧问题,但不确定是否适用
- 除了将触发按钮替换为Fab,完全沿用Glue Stack UI Actionsheet文档中的代码模板
相关代码
import { useState, useEffect, useRef } from 'react'; import { View, StyleSheet } from 'react-native'; import { Spinner, Box, VStack, Alert, AlertIcon, AlertText, Fab, FabIcon, Actionsheet, ActionsheetBackdrop, ActionsheetContent, ActionsheetDragIndicatorWrapper, ActionsheetDragIndicator, ActionsheetItem, ActionsheetItemText } from '@gluestack-ui/react-native'; import { InfoIcon, AlertOctagon, AlertTriangle, MailPlus } from 'lucide-react-native'; export default function MessagesScreen() { const [isLoading, setIsLoading] = useState(true); const [showActionsheet, setShowActionsheet] = useState(false); const handleClose = () => setShowActionsheet(!showActionsheet); useEffect(() => { setTimeout(() => { setIsLoading(false); }, 2000); }, []); return ( <View style={styles.messagesScreenContainer}> {isLoading ? ( <Spinner size="xl" color="#EC472E" /> ) : ( <Box h="95%" w="95%" borderRadius="$md"> <VStack space="md"> <Alert mx="$2.5" action="info" variant="accent" bg="$info200" borderColor="$info700" > <AlertIcon as={InfoIcon} mr="$3" color="$info700" /> <AlertText color="$textLight900"> Suspect is small. May have robbed a couple of trash cans. We los... </AlertText> </Alert> <Alert mx="$2.5" action="warning" variant="accent" bg="$warning200" borderColor="$warning700" > <AlertIcon as={AlertOctagon} mr="$3" color="$warning700" /> <AlertText color="$textLight900"> so my husband climbed up to get the cat and now he's stuck too... </AlertText> </Alert> <Alert mx="$2.5" action="error" variant="accent" bg="$error200" borderColor="$error700" > <AlertIcon as={AlertTriangle} mr="$3" color="$error700" /> <AlertText color="$textLight900"> over turned vehicle, flames showing, and body parts everywhere, how... </AlertText> </Alert> </VStack> <Fab bg="#EC472E" size="lg" placement="bottom right" onPress={handleClose} > <FabIcon as={MailPlus} size="xl" /> </Fab> <Actionsheet isOpen={showActionsheet} onClose={handleClose} zIndex={999} > <ActionsheetBackdrop /> <ActionsheetContent h="$72" zIndex={999}> <ActionsheetDragIndicatorWrapper> <ActionsheetDragIndicator /> </ActionsheetDragIndicatorWrapper> <ActionsheetItem onPress={handleClose}> <ActionsheetItemText>Delete</ActionsheetItemText> </ActionsheetItem> <ActionsheetItem onPress={handleClose}> <ActionsheetItemText>Share</ActionsheetItemText> </ActionsheetItem> <ActionsheetItem onPress={handleClose}> <ActionsheetItemText>Play</ActionsheetItemText> </ActionsheetItem> <ActionsheetItem onPress={handleClose}> <ActionsheetItemText>Favourite</ActionsheetItemText> </ActionsheetItem> <ActionsheetItem onPress={handleClose}> <ActionsheetItemText>Cancel</ActionsheetItemText> </ActionsheetItem> </ActionsheetContent> </Actionsheet> </Box> )} </View> ); } const styles = StyleSheet.create({ messagesScreenContainer: { flex: 1, alignItems: "center", justifyContent: "center", }, });
修复方案
1. 绑定触发元素的引用给Actionsheet
Glue Stack UI的弹出组件需要获取触发元素的位置信息,给Fab添加ref并传递给Actionsheet的triggerRef属性:
// 新增useRef const fabRef = useRef(null); // Fab组件绑定ref <Fab ref={fabRef} bg="#EC472E" size="lg" placement="bottom right" onPress={handleClose} > <FabIcon as={MailPlus} size="xl" /> </Fab> // Actionsheet添加triggerRef属性 <Actionsheet isOpen={showActionsheet} onClose={handleClose} zIndex={999} triggerRef={fabRef} >
2. 强制Actionsheet初始位置从底部开始
给ActionsheetContent添加样式,固定初始位置为屏幕底部:
<ActionsheetContent h="$72" zIndex={999} style={{ position: 'absolute', bottom: 0, left: 0, right: 0 }} >
3. 延迟弹出时机,确保布局稳定
由于页面存在加载状态切换,弹出时可能布局未完全稳定,用requestAnimationFrame延迟状态切换:
const handleClose = () => { requestAnimationFrame(() => { setShowActionsheet(!showActionsheet); }); };
4. 检查并升级依赖版本
确认Glue Stack UI版本与当前Expo/React Native版本兼容,建议升级到最新稳定版:
npm install @gluestack-ui/react-native@latest
内容的提问来源于stack exchange,提问作者ColstonBod-oy
相关产品推荐
相关产品推荐

