You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Native地图点击Marker时触发react-native-bottom-sheet弹窗?

MapView Marker点击触发底部弹窗实现方案

完整实现代码

import React, { useState, useRef } from 'react';
import { View, Animated, Text, Button } from 'react-native';
import MapView, { Marker, Callout, PROVIDER_GOOGLE } from 'react-native-maps';

// 复用你已有的BottomSheet组件(示例实现供参考)
const BottomSheet = ({ onCancel, animation }) => {
  return (
    <Animated.View
      style={{
        position: 'absolute',
        bottom: 0,
        left: 0,
        right: 0,
        height: 300,
        backgroundColor: '#fff',
        transform: [{ translateY: animation }],
        borderTopLeftRadius: 16,
        borderTopRightRadius: 16,
        paddingVertical: 20,
        paddingHorizontal: 16,
      }}
    >
      <Text style={{ fontSize: 18, fontWeight: '600', marginBottom: 16 }}>弹窗内容</Text>
      <Button title="关闭弹窗" onPress={onCancel} />
    </Animated.View>
  );
};

const App = () => {
  const [animationValue, setAnimationValue] = useState(-1000);
  const showAnimation = useRef(new Animated.Value(animationValue)).current;

  const toggleAnimation = () => {
    const targetVal = animationValue === 0 ? -1000 : 0;
    Animated.timing(showAnimation, {
      useNativeDriver: false,
      toValue: targetVal,
      duration: 350,
    }).start();
    setAnimationValue(targetVal);
  };

  return (
    <View style={{ flex: 1 }}>
      {/* 地图组件 */}
      <MapView
        provider={PROVIDER_GOOGLE}
        style={{ flex: 1 }}
        initialRegion={{
          latitude: 34.052235,
          longitude: -118.243683,
          latitudeDelta: 0.01,
          longitudeDelta: 0.09,
        }}
        {/* 点击地图空白区域关闭弹窗 */}
        onPress={() => animationValue === 0 && toggleAnimation()}
      >
        <Marker
          coordinate={{ latitude: 34.052235, longitude: -118.243683 }}
          {/* 点击Marker触发弹窗 */}
          onPress={toggleAnimation}
        >
          <Callout>
            <Text>Marker</Text>
          </Callout>
        </Marker>
      </MapView>

      {/* 底部弹窗:放在地图之后保证层级在上方 */}
      <BottomSheet onCancel={toggleAnimation} animation={showAnimation} />
    </View>
  );
};

export default App;

核心要点

  • 事件绑定:
    • 给Marker添加onPress事件,调用toggleAnimation触发弹窗
    • 给MapView添加onPress事件,仅当弹窗处于打开状态时关闭它
  • 层级控制:将BottomSheet组件放在MapView之后,React Native中后渲染的组件默认层级更高,确保弹窗显示在地图上方
  • 动画复用:直接保留你原有的Animated动画逻辑,无需修改核心实现
  • Callout区分:若需要点击Callout不触发弹窗,可单独给Callout添加onPress事件并阻止冒泡

内容的提问来源于stack exchange,提问作者Elias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 14:39:25