由于颤动中的凹口,覆盖物漂浮在 AppBar 小部件上方并留下空白屏幕

发布于 2025-01-11 00:33:55 字数 5622 浏览 1 评论 0原文

我的 flutter 代码中的 swiper 小部件内有一个 CompositedTransformTarget 小部件。我还有一个覆盖层包裹在链接到同一层链接的 CompositedTransformFollower 中。现在,当我滑动页面时,可以看到叠加层在我的应用程序的应用栏上方滚动,并且由于手机缺口而在左侧的空白屏幕中也可见。如何设置覆盖层的 z 索引,使其位于应用栏后面。这是我的小部件的代码。

// ignore_for_file: unnecessary_const

class CreateQuestion extends StatefulWidget {
  final GlobalKey<FormState> formKey;
  final Function(String value) getQuestion;
  final double? optionSpacing;
  const CreatePollQuestion(
      {Key? key,
      required this.formKey,
      required this.getQuestion,
      this.optionSpacing})
      : super(key: key);

  @override
  _CreateQuestionState createState() => _CreateQuestionState();
}

class _CreateQuestionState extends State<CreateQuestion> {
  final FocusNode _focusNode = FocusNode();
  late OverlayEntry _overlayEntry;
  final questionInputController = TextEditingController();
  List<String> questionList = ["abc?", "efg?", "hijf?", "lmnop?", "uyti?"];
  //To implement target follow between two widgets we need to pass same layerlink to both target
  //and follow widget.
  final LayerLink _layerlink = LayerLink();
  bool suffixIconDisplay = false;
  List<ListTile> tiles = [];

  @override
  void initState() {
    super.initState();
    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        setState(() {
          suffixIconDisplay = true;
        });
    _overlayEntry = _createOverlayEntry();
    Overlay.of(context)?.insert(_overlayEntry);
  } else {
    setState(() {
      suffixIconDisplay = false;
      widget.getPollQuestion(questionInputController.value.text);
    });
    _overlayEntry.remove();
  }
});

for (int i = 0; i < questionList.length; i++) {
  tiles.add(ListTile(
    title: Align(
      alignment: Alignment.center,
      child: Text(
        questionList[i],
        style: const TextStyle(
          fontSize: 14.0,
          height: 2.0,
          color: Colors.black54,
          fontWeight: FontWeight.w700,
        ),
      ),
    ),
    onTap: () {
      //debugPrint(questionList[i] + "is selected");
      questionInputController.text = questionList[i];
      _focusNode.unfocus();
    },
  ));
}
 

 }

  OverlayEntry _createOverlayEntry() {
    RenderBox renderBox = context.findRenderObject() as RenderBox;
    var size = renderBox.size;
return OverlayEntry(
  builder: (context) => Positioned(
    width: size.width -
        max(responsive(context, 12) * 2, 2 * (widget.optionSpacing ?? 0)),
    height: size.height * 3,
    child: CompositedTransformFollower(
      link: _layerlink,
      showWhenUnlinked: false,
      offset: Offset(
          max(responsive(context, 12), widget.optionSpacing ?? 0),
          size.height),
      child: Material(
        color: kAliceBlue,
        elevation: 4.0,
        borderRadius: BorderRadius.circular(8.0),
        child: Scrollbar(
          child: ListView(
            padding: EdgeInsets.zero,
            shrinkWrap: true,
            children: ListTile.divideTiles(
              context: context,
              tiles: tiles,
            ).toList(),
          ),
        ),
      ),
    ),
  ),
);
  

}

  @override
  Widget build(BuildContext context) {
    return CompositedTransformTarget(
      link: _layerlink,
      child: Container(
        //alignment: Alignment.center,
        margin: EdgeInsets.only(
          left: max(responsive(context, 12), widget.optionSpacing ?? 0),
          right: max(responsive(context, 12), widget.optionSpacing ?? 0),
          top: responsive(context, 10),
        ),
        child: TextFormField(
          controller: questionInputController,
          focusNode: _focusNode,
          minLines: 2,
          maxLines: 2,
          maxLength: 90,
          cursorColor: Colors.black54,
          cursorWidth: 0.5,
          textAlignVertical: TextAlignVertical.center,
          textAlign: TextAlign.center,
          keyboardType: TextInputType.multiline,
          style: const TextStyle(
            fontSize: 14.0,
            height: 2.0,
            color: Colors.black,
            fontWeight: FontWeight.w500,
          ),
          decoration: InputDecoration(
            filled: true,
            fillColor: kAliceBlue,
            floatingLabelBehavior: FloatingLabelBehavior.never,
            counterText: "",
            contentPadding:
                const EdgeInsets.only(top: 8, bottom: 8, left: 10, right: 10),
            border: const OutlineInputBorder(),
            label: const Center(
              child: Text(
                'Type Your Question Here...',
                style: TextStyle(
                  fontSize: 14.0,
                  height: 1.0,
                  color: Colors.black,
                  fontWeight: FontWeight.w500,
                ),
              ),
            ),
            suffixIcon: suffixIconDisplay
                ? GestureDetector(
                    child: const Align(
                      widthFactor: 0.5,
                      heightFactor: 0.5,
                      child: Icon(
                        Icons.send,
                        color: kGreenBlue,
                      ),
                    ),
                    onTap: () {
                      _focusNode.unfocus();
                    })
                : null,
          ),
          validator: (value) {
            if (value == null || value.isEmpty) {
              return 'Please enter question';
            } else if (value.length > 90) {
              return 'Question should not be large then 90 char';
            }
            return null;
          },
        ),
      ),
    );
  }
}

I have a CompositedTransformTarget widget inside a swiper widget in my flutter code. I also have an overlay wrapped within a CompositedTransformFollower linked to the same layer link. Now, when I swipe the page, the overlay is seen scrolling above the appbar of my app and is also visible in the blank screen left due to phone notch. How can I set the z index of the overlay such that it is behind App Bar. Here is the code to my widget.

// ignore_for_file: unnecessary_const

class CreateQuestion extends StatefulWidget {
  final GlobalKey<FormState> formKey;
  final Function(String value) getQuestion;
  final double? optionSpacing;
  const CreatePollQuestion(
      {Key? key,
      required this.formKey,
      required this.getQuestion,
      this.optionSpacing})
      : super(key: key);

  @override
  _CreateQuestionState createState() => _CreateQuestionState();
}

class _CreateQuestionState extends State<CreateQuestion> {
  final FocusNode _focusNode = FocusNode();
  late OverlayEntry _overlayEntry;
  final questionInputController = TextEditingController();
  List<String> questionList = ["abc?", "efg?", "hijf?", "lmnop?", "uyti?"];
  //To implement target follow between two widgets we need to pass same layerlink to both target
  //and follow widget.
  final LayerLink _layerlink = LayerLink();
  bool suffixIconDisplay = false;
  List<ListTile> tiles = [];

  @override
  void initState() {
    super.initState();
    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        setState(() {
          suffixIconDisplay = true;
        });
    _overlayEntry = _createOverlayEntry();
    Overlay.of(context)?.insert(_overlayEntry);
  } else {
    setState(() {
      suffixIconDisplay = false;
      widget.getPollQuestion(questionInputController.value.text);
    });
    _overlayEntry.remove();
  }
});

for (int i = 0; i < questionList.length; i++) {
  tiles.add(ListTile(
    title: Align(
      alignment: Alignment.center,
      child: Text(
        questionList[i],
        style: const TextStyle(
          fontSize: 14.0,
          height: 2.0,
          color: Colors.black54,
          fontWeight: FontWeight.w700,
        ),
      ),
    ),
    onTap: () {
      //debugPrint(questionList[i] + "is selected");
      questionInputController.text = questionList[i];
      _focusNode.unfocus();
    },
  ));
}
 

 }

  OverlayEntry _createOverlayEntry() {
    RenderBox renderBox = context.findRenderObject() as RenderBox;
    var size = renderBox.size;
return OverlayEntry(
  builder: (context) => Positioned(
    width: size.width -
        max(responsive(context, 12) * 2, 2 * (widget.optionSpacing ?? 0)),
    height: size.height * 3,
    child: CompositedTransformFollower(
      link: _layerlink,
      showWhenUnlinked: false,
      offset: Offset(
          max(responsive(context, 12), widget.optionSpacing ?? 0),
          size.height),
      child: Material(
        color: kAliceBlue,
        elevation: 4.0,
        borderRadius: BorderRadius.circular(8.0),
        child: Scrollbar(
          child: ListView(
            padding: EdgeInsets.zero,
            shrinkWrap: true,
            children: ListTile.divideTiles(
              context: context,
              tiles: tiles,
            ).toList(),
          ),
        ),
      ),
    ),
  ),
);
  

}

  @override
  Widget build(BuildContext context) {
    return CompositedTransformTarget(
      link: _layerlink,
      child: Container(
        //alignment: Alignment.center,
        margin: EdgeInsets.only(
          left: max(responsive(context, 12), widget.optionSpacing ?? 0),
          right: max(responsive(context, 12), widget.optionSpacing ?? 0),
          top: responsive(context, 10),
        ),
        child: TextFormField(
          controller: questionInputController,
          focusNode: _focusNode,
          minLines: 2,
          maxLines: 2,
          maxLength: 90,
          cursorColor: Colors.black54,
          cursorWidth: 0.5,
          textAlignVertical: TextAlignVertical.center,
          textAlign: TextAlign.center,
          keyboardType: TextInputType.multiline,
          style: const TextStyle(
            fontSize: 14.0,
            height: 2.0,
            color: Colors.black,
            fontWeight: FontWeight.w500,
          ),
          decoration: InputDecoration(
            filled: true,
            fillColor: kAliceBlue,
            floatingLabelBehavior: FloatingLabelBehavior.never,
            counterText: "",
            contentPadding:
                const EdgeInsets.only(top: 8, bottom: 8, left: 10, right: 10),
            border: const OutlineInputBorder(),
            label: const Center(
              child: Text(
                'Type Your Question Here...',
                style: TextStyle(
                  fontSize: 14.0,
                  height: 1.0,
                  color: Colors.black,
                  fontWeight: FontWeight.w500,
                ),
              ),
            ),
            suffixIcon: suffixIconDisplay
                ? GestureDetector(
                    child: const Align(
                      widthFactor: 0.5,
                      heightFactor: 0.5,
                      child: Icon(
                        Icons.send,
                        color: kGreenBlue,
                      ),
                    ),
                    onTap: () {
                      _focusNode.unfocus();
                    })
                : null,
          ),
          validator: (value) {
            if (value == null || value.isEmpty) {
              return 'Please enter question';
            } else if (value.length > 90) {
              return 'Question should not be large then 90 char';
            }
            return null;
          },
        ),
      ),
    );
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文