在 Flutter 应用程序中的 Obx() 侦听器中调用 Get.back()

时间:2021-06-13 09:43:47

标签: flutter flutter-getx

当 GetXController 中的某个条件为真时,我试图从当前屏幕弹出。

我所做的是在 Obx 侦听器中调用 if (!_isReceiverIDLoggedIn) Get.back();

这给了我想要的最终结果,但我得到了一个例外。

如果有人可以建议修复处理此问题/异常,我将不胜感激?

════════ Exception caught by animation library ═════════════════════════════════
The following assertion was thrown while notifying status listeners for AnimationController:
setState() or markNeedsBuild() called during build.

This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets.  A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: Overlay-[LabeledGlobalKey<OverlayState>#5221d]
    state: OverlayState#794f1(tickers: tracking 0 tickers, entries: [OverlayEntry#26cd8(opaque: true; maintainState: false), OverlayEntry#d189a(opaque: false; maintainState: true), OverlayEntry#0dfc3(opaque: false; maintainState: false), OverlayEntry#0636b(opaque: false; maintainState: true)])
The widget which was currently being built when the offending call was made was: Obx
    dirty
    state: _ObxState#5b9ea
When the exception was thrown, this was the stack
#0      Element.markNeedsBuild.<anonymous closure>
package:flutter/…/widgets/framework.dart:4217
#1      Element.markNeedsBuild
package:flutter/…/widgets/framework.dart:4232
#2      State.setState
package:flutter/…/widgets/framework.dart:1108
#3      OverlayState._didChangeEntryOpacity
package:flutter/…/widgets/overlay.dart:475
#4      OverlayEntry.opaque=
package:flutter/…/widgets/overlay.dart:92
...
The AnimationController notifying status listeners was: AnimationController#4d86f(◀ 1.000; for MaterialPageRoute<dynamic>(/message))
════════════════════════════════════════════════════════════════════════════════

这是完整的颤振代码:

import 'package:flutter/material.dart';
import 'package:flutter_frontend/controller/user/user_controller.dart';
import 'package:get/get.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

import 'package:flutter_frontend/controller/message/message_controller.dart';
import 'package:flutter_frontend/view/message/components/message_unit.dart';

class MessageView extends StatefulWidget {
  final String receiverID;

  MessageView({required this.receiverID});

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

class _MessageViewState extends State<MessageView> {
  final ItemScrollController itemScrollController = ItemScrollController();
  final ItemPositionsListener itemPositionsListener =
      ItemPositionsListener.create();
  final MessageController _messageController = Get.find();
  final UserController _userController = Get.find();

  bool _isWidgetTreeBuilt = false;

  @override
  void initState() {
    super.initState();
    _startUpSequence();
  }

  _startUpSequence() async {
    _isWidgetTreeBuilt = false;
    //if the messages are loading - is the messages fetched from the db is not empty
    //then using a WidgetsBinding.instance?.addPostFrameCallback a  itemScrollController.jumpTo is excuted
    //the WidgetsBinding.instance?.addPostFrameCallback ensures that the jumpTo happens after the Widget tree is mounted
    if (_messageController.getMessageStatus.value == MessageStatus.loaded) {
      WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
        itemScrollController.jumpTo(
            index: _messageController.getMessageList.length - 1);
      });
    }
    WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
      _isWidgetTreeBuilt = true;
    });
  }

  @override
  Widget build(BuildContext context) {
      return Obx(() {
        //if the receiverID is disconnected from the socket, the MessageScreen is popped 
        bool _isReceiverIDLoggedIn = _userController.getUsersList
          .any((user) => user.id == widget.receiverID);

      if (!_isReceiverIDLoggedIn) Get.back();

       /*if the MessageStatus in the MessageController is not empty 
       and if the widget tree is built and if the MessageList length is more than 9
      the itemScrollController is activated to scroll the latest  MessageUnit 
      from outside the viewinset to bottom of viewinset
       */

      if (_messageController.getMessageStatus.value != MessageStatus.empty &&
          _isWidgetTreeBuilt &&
          _messageController.getMessageList.length > 9) {
        itemScrollController.scrollTo(
            index: _messageController.getMessageList.length - 1,
            duration: Duration(milliseconds: 500),
            curve: Curves.easeInOutCubic,
            alignment: 0.725);
      }

      switch (_messageController.getMessageStatus.value) {
        case MessageStatus.loading:
          return Flexible(
            child: Center(
              child: CircularProgressIndicator(),
            ),
          );
        case MessageStatus.loaded:
          return Flexible(
            child: ScrollablePositionedList.builder(
              itemScrollController: itemScrollController,
              itemPositionsListener: itemPositionsListener,
              itemCount: _messageController.getMessageList.length,
              itemBuilder: (context, index) {
                return MessageUnit(
                    message: _messageController.getMessageList[index]);
              },
            ),
          );
        case MessageStatus.empty:
          return Flexible(
            child: Center(
              child: Text(
                'No Messages Found!',
                style: Theme.of(context).textTheme.subtitle1,
              ),
            ),
          );
        default:
          return Container();
      }
    });
  }
}

0 个答案:

没有答案