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

Flutter中CustomInfoWindow无法设置圆角及背景透明问题求助

Flutter中custom_info_window无法设置圆角和透明背景的解决方法

问题描述

在Flutter项目中使用custom_info_window包实现Google Maps标记弹窗时,无法为CustomInfoWindow组件设置borderRadius(圆角)或背景透明样式。已实现承载弹窗内容的ContainerGoogleMaps组件和添加地图标记的MapScreen组件,但无法修改CustomInfoWindow外观,寻求可行方案。

当前弹窗效果:
弹窗当前效果

现有代码

ContainerGoogleMaps组件代码

import 'package:flutter/material.dart';
import 'package:streeti/static/static_colors.dart';
import 'package:streeti/widgets/bold_big_text.dart';
import 'package:streeti/widgets/small_text.dart';

class ContainerGoogleMaps extends StatelessWidget {
  String title;

  ContainerGoogleMaps({required this.title, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Container(
            width: double.maxFinite,
            decoration: const BoxDecoration(
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(15),
                topRight: Radius.circular(15),
              ),
              color: Colors.blue,
            ),
            child: Text(
              title,
              style: const TextStyle(
                  color: Colors.white,
                  fontSize: 16,
                  fontWeight: FontWeight.w500),
            ),
          ),
          Container()
        ],
      ),
    );
  }
}

MapScreen组件代码

import 'package:custom_info_window/custom_info_window.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:streeti/pages/plate_withOTP_page.dart';
import 'package:streeti/widgets/bold_big_text.dart';
import 'package:streeti/widgets/bottom_nav.dart';
import 'package:streeti/widgets/container_google_maps_info.dart';
import 'package:streeti/widgets/small_text.dart';

const LatLng consLocation = LatLng(48.355016218833654, 15.813391958051588);
const LatLng marker1 = LatLng(48.34161850665899, 15.778319914302879);
const LatLng marker2 = LatLng(48.32890042576883, 15.915319080569235);
const LatLng marker3 = LatLng(48.286968189915875, 15.841635818003887);
const LatLng marker4 = LatLng(48.26770643729367, 15.756396257371149);
const LatLng marker5 = LatLng(48.325018246453446, 15.70158482793595);

class MapScreen extends StatefulWidget {
  const MapScreen({super.key});

  @override
  State<MapScreen> createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  late GoogleMapController _mapController;
  Map<String, Marker> _markers = {};
  final _customInfoWindowController = CustomInfoWindowController();

  @override
  Widget build(BuildContext context) {
    double screenHeight = MediaQuery.of(context).size.height;
    double redContainerHeight = screenHeight * 0.1;

    return Scaffold(
      body: SafeArea(
        child: Stack(
          children: [
            Column(
              children: [
                Container(
                  padding: EdgeInsets.all(15),
                  height: redContainerHeight,
                  color: Colors.white,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          BoldBigText(
                            text: 'Suchen',
                            fontSize: 18,
                            isBold: true,
                          ),
                          SmallText(
                            text: "Top Betriebe",
                            fontSize: 12,
                          ),
                        ],
                      ),
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.end,
                        children: [
                          MaterialButton(
                            onPressed: () {
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) =>
                                      const PlateWIthOTPPage(),
                                ),
                              );
                            },
                            shape: CircleBorder(),
                            child: Icon(Icons.search),
                          ),
                        ],
                      )
                    ],
                  ),
                ),

                //! Google maps
                Expanded(
                  child: ClipRRect(
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(15),
                      topRight: Radius.circular(15),
                    ),
                    child: Container(
                      color: Colors.blue,
                      child: Stack(
                        children: [
                          GoogleMap(
                            onMapCreated: (controller) {
                              _mapController = controller;
                              _customInfoWindowController.googleMapController =
                                  controller;
                              addMarker('test', marker1, 'AAA');
                              addMarker('test2', marker2, 'VVV');
                              addMarker('test3', marker3, 'CCCC');
                              addMarker('test4', marker4, 'AAA');
                              addMarker('test5', marker5, 'HJHJ');
                            },
                            onTap: (location) {
                              _customInfoWindowController.hideInfoWindow!();
                            },
                            onCameraMove: (position) {
                              _customInfoWindowController.onCameraMove!();
                            },
                            markers: _markers.values.toSet(),
                            initialCameraPosition:
                                CameraPosition(target: consLocation, zoom: 11),
                          ),
                          CustomInfoWindow(
                            controller: _customInfoWindowController,
                            height: 100,
                            width: 250,
                            offset: 50,
                          )
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            ),

            //! bottomnav
            Positioned(
              bottom: 0,
              left: 0,
              right: 0,
              child: CustomBottomNavigationBar(
                isNachrichtActive: false,
                isKarteActive: false,
                isCommunityActive: false,
                isProfilActive: false,
              ),
            ),
          ],
        ),
      ),
    );
  }

//!add markers
  addMarker(String id, LatLng location, String title) async {
    var markerIcon = await BitmapDescriptor.fromAssetImage(
        ImageConfiguration(size: Size(50, 50)),
        'lib/assets/images/map_pin3.png');

    var marker = Marker(
      markerId: MarkerId(id),
      position: location,
      icon: markerIcon,
      onTap: () {
        _customInfoWindowController.addInfoWindow!(
          ContainerGoogleMaps(
            title: title,
          ),
          location,
        );
      },
    );

    _markers[id] = marker;
    setState(() {});
  }
}

解决方案

问题根源在于两点:一是ContainerGoogleMaps中使用了Scaffold,它自带白色背景会遮挡自定义样式;二是CustomInfoWindow默认有背景色,没有设置透明。按以下步骤修改:

1. 修改ContainerGoogleMaps组件

移除多余的Scaffold和空Container,直接在根Container上设置圆角和透明背景:

import 'package:flutter/material.dart';
// 保留你项目的其他import

class ContainerGoogleMaps extends StatelessWidget {
  final String title;

  ContainerGoogleMaps({required this.title, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.maxFinite,
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15), // 全圆角
        color: Colors.blue.withOpacity(0.9), // 半透明蓝色背景
      ),
      child: Text(
        title,
        style: const TextStyle(
            color: Colors.white,
            fontSize: 16,
            fontWeight: FontWeight.w500),
        textAlign: TextAlign.center,
      ),
    );
  }
}

2. 修改MapScreen中的CustomInfoWindow

给CustomInfoWindow添加backgroundColor: Colors.transparent,让组件背景透明,只显示自定义内容:

CustomInfoWindow(
  controller: _customInfoWindowController,
  height: 80, // 调整高度适配修改后的内容
  width: 250,
  offset: 50,
  backgroundColor: Colors.transparent, // 关键:设置背景透明
)

3. 调整弹窗高度(可选)

根据修改后的ContainerGoogleMaps内容,调整CustomInfoWindow的height参数,避免内容被截断或出现多余空白。

效果说明

修改后,弹窗会显示带圆角的半透明蓝色背景,完全符合自定义样式需求,同时不会被CustomInfoWindow的默认背景干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:45:54