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

Tutorial Coach Mark组件TargetContent溢出屏幕问题求助

Tutorial Coach Mark组件TargetContent溢出屏幕问题求助

我在App里用Tutorial Coach Mark做引导功能,但发现一个棘手的问题:焦点区域的内容大小不同时,焦点和TargetContent之间的间距会跟着变化——当焦点是大表单这类内容时,间距会变得很大,直接导致TargetContent溢出屏幕,完全影响正常使用。

可以看视频里的对比:焦点是大表单时,描述框和焦点的间距明显过大,超出了屏幕范围;而焦点是按钮这种小元素时,间距就很合适,描述框能完整显示。

我已经尝试过这些方案,但都没彻底解决问题:

  • 给TutorialCoachMark的paddingFocus设负数,虽然允许小于-11的值,但设-10时只是稍微改善,还是存在溢出问题
  • 把CoachMarkDescription用Positioned包裹,但是完全没效果
  • 翻了TutorialCoachMark的官方文档,没找到能直接缩小这个间距的参数

以下是我的相关代码:

引导显示与目标初始化代码

showTour(){
  initTargets();
  tutorialCoachMark = TutorialCoachMark(
    targets: targets,
    hideSkip: true,
    paddingFocus: 0
  )..show(context: context, rootOverlay: true);
}

initTargets(){
  targets = [
    TargetFocus(
      identify: "qr-code-key",
      keyTarget: barCodeKey,
      contents: [
        TargetContent(
          align: ContentAlign.bottom,
          builder: (context, controller) {
            return CoachMarkDescription(
              text: "Ou utilize o leitor de código de barras. Basta clicar no ícone e apontar a câmera para o equipamento.",
              margin: EdgeInsets.only(left: 70, right: 10),
              onNext: (){
                controller.next();
              },
              onSkip: (){
                controller.skip();
                if(widget.isRevisitTour == true) {
                  _setFlagToShowRegistrationEquipmentTour(false);
                  Navigator.of(context).pop();
                }
              },
            );
          }),
      ]
    ),
    TargetFocus(
      identify: "form-key",
      keyTarget: formKey,
      shape: ShapeLightFocus.RRect,
      contents: [
        TargetContent(
          builder: (context, controller) {
            return Positioned(
              top: 20,
              child: CoachMarkDescription(
                text: "Preencha todos os campos e insira o arquivo da sua nota fiscal.",
                margin: EdgeInsets.only(left: 40, right: 40),
                onNext: (){
                  controller.next();
                },
                onSkip: (){
                  controller.skip();
                  if(widget.isRevisitTour == true){
                    _setFlagToShowRegistrationEquipmentTour(false);
                    Navigator.of(context).pop();
                  }
                },
              ),
            );
          }),
      ]
    ),
    TargetFocus(
      identify: "register-button-key",
      keyTarget: registerButtonKey,
      shape: ShapeLightFocus.RRect,
      contents: [
        TargetContent(
          align: ContentAlign.top,
          builder: (context, controller) {
            return CoachMarkDescription(
              text: "Clique em “cadastrar”, para prosseguir e seu equipamento será listado.",
              margin: EdgeInsets.only(left: 40, right: 40),
              isFinish: true,
              onSkip: (){
                controller.skip();
                if(widget.isRevisitTour == true){
                  _setFlagToShowRegistrationEquipmentTour(false);
                  Navigator.of(context).pop();
                }
              },
            );
          }),
      ]
    ),
  ];
}

CoachMarkDescription自定义组件代码

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CoachMarkDescription extends StatefulWidget {
  final String text;
  final String skip;
  final String next;
  final bool? isFinish;
  final EdgeInsets margin;
  final Function? onSkip;
  final Function? onNext;

  const CoachMarkDescription({
    Key? key,
    required this.text,
    this.skip = "Pular",
    this.next = "Próximo",
    this.onSkip,
    this.onNext,
    required this.margin,
    this.isFinish
  }) : super(key: key);

  @override
  State<CoachMarkDescription> createState() => _CoachMarkDescriptionState();
}

class _CoachMarkDescriptionState extends State<CoachMarkDescription> {
  bool isFinish = false;

  @override
  Widget build(BuildContext context) {
    if(widget.isFinish == true){
      isFinish = true;
    }
    return Container(
      padding: EdgeInsets.only(top: 20, left: 20, right: 20, bottom: 20),
      margin: widget.margin,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(10)
      ),
      child: Column(
        children: [
          Text(
            widget.text,
            textAlign: isFinish ? TextAlign.center : TextAlign.left,
            style: TextStyle(
              fontSize: 14,
              fontFamily: "OpenSans",
              color: Color.fromRGBO(51, 51, 51, 1)
            ),
          ),
          SizedBox(height: 20),
          !isFinish ?
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              GestureDetector(
                onTap: (){
                  widget.onSkip!();
                },
                child: Text(
                  "PULAR",
                  style: TextStyle(
                    fontSize: 14,
                    fontFamily: "OpenSans",
                    color: Color.fromRGBO(51, 51, 51, 1)
                  ),
                ),
              ),
              GestureDetector(
                onTap: (){
                  widget.onNext!();
                },
                child: Text(
                  "PRÓXIMO",
                  style: TextStyle(
                    fontSize: 14,
                    fontFamily: "OpenSans",
                    fontWeight: FontWeight.w600,
                    color: Theme.of(context).primaryColor
                  ),
                ),
              )
            ],
          )
          : GestureDetector(
            onTap: (){
              widget.onSkip!();
            },
            child: Text(
              "FINALIZAR",
              style: TextStyle(
                fontSize: 14,
                fontFamily: "OpenSans",
                fontWeight: FontWeight.w600,
                color: Theme.of(context).primaryColor
              ),
            ),
          )
        ],
      ),
    );
  }
}

现在想请教大家,有没有办法缩小焦点(比如这个大表单)和描述框之间的间距,让描述框能完整显示在屏幕内,就像其他小焦点的情况一样?

备注:内容来源于stack exchange,提问作者Gabi Mangili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 07:19:32