android - 无法构建,因为 frawework 已经在构建 - Flutter

标签 android flutter dart flutter-layout

我想在点击抽屉项目时显示 AlertDialog

我正在使用下面的代码在我的 flutter 应用程序中使用抽屉导航项目

class HomePage extends StatefulWidget {
  final drawerItems = [
    DrawerItem("View Your account", Icons.account_circle),
    DrawerItem("Request", Icons.receipt),
    DrawerItem("Order", Icons.shopping_cart),
    DrawerItem("Report", Icons.report_problem),
    DrawerItem("Log out", Icons.info)
  ];

  @override
  State<StatefulWidget> createState() {
    return new HomePageState();
  }
}

class HomePageState extends State<HomePage> {
  int _selectedDrawerIndex = 0;
  bool visibilityTag = false;

  showAlertDialog(BuildContext context) {
    // set up the button
    Widget okButton = FlatButton(
      child: Text("OK"),
      onPressed: () {
        Navigator.of(context).pop();
      },
    );
    Widget cancelButton = FlatButton(
      child: Text("Cancel"),
      onPressed: () {
        Navigator.of(context).pop();
      },
    );

    // set up the AlertDialog
    AlertDialog alert = AlertDialog(
      elevation: 10,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(20.0))),
      title: Text("ORICON"),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text("Are you sure you want to logout?"),
          Padding(
            padding: const EdgeInsets.only(top: 20.0),
            child: Text(
              "1300 898 989",
              style: TextStyle(
                  color: Colors.blue,
                  fontWeight: FontWeight.bold,
                  fontSize: 20.0),
            ),
          ),
        ],
      ),
      actions: [okButton, cancelButton],
    );

    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return alert;
      },
    );
  }

  _getDrawerItemWidget(int pos) {
    switch (pos) {
      case 0:
        visibilityTag = false;
        return AccountDetails();
      case 1:
        visibilityTag = true;
        return RequestBin();
      case 2:
        visibilityTag = true;
        return OrderBin();
      case 3:
        visibilityTag = true;
        return Report();
      case 4:
        showAlertDialog(context);
        visibilityTag = false;
        return AccountDetails();
      default:
        return new Text("Error");
    }
  }

  _onSelectItem(int index) {
    if (index == 0) {
      visibilityTag = false;
    } else {
      visibilityTag = true;
    }
//    setState(() => _selectedDrawerIndex = index);
    _selectedDrawerIndex = index; // removed setState call
    Navigator.of(context).pop(); // close the drawer
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> drawerOptions = [];
    for (var i = 0; i < widget.drawerItems.length; i++) {
      var d = widget.drawerItems[i];
      drawerOptions.add(new ListTile(
        leading: Icon(d.icon),
        title: Text(d.title),
        selected: i == _selectedDrawerIndex,
        onTap: () => _onSelectItem(i),
      ));
    }

    Future<bool> customPop() {
      if (_selectedDrawerIndex == 0) {
        visibilityTag = false;
        return Future.value(true);
      } else {
        setState(() {
          visibilityTag = false;
          _selectedDrawerIndex = 0;
        });
        return Future.value(false);
      }
    }

    void navigateToHomeScreen() {
      if (_selectedDrawerIndex == 0) {
        visibilityTag = false;
      } else {
        visibilityTag = false;
        setState(() {
          _selectedDrawerIndex = 0;
        });
      }
    }

    return WillPopScope(
      onWillPop: customPop,
      child: Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.white,
            iconTheme: IconThemeData(color: Colors.black), //add this line here
            // here we display the title corresponding to the fragment
            // you can instead choose to have a static title
            title: Text(
              widget.drawerItems[_selectedDrawerIndex].title,
              style: TextStyle(color: Colors.black),
            ),
            actions: <Widget>[
              Padding(
                padding: const EdgeInsets.only(right: 10),
                child: Visibility(
                    visible: visibilityTag,
                    child: Row(
                      children: <Widget>[
                        IconButton(
                          icon: new Icon(Icons.arrow_back_ios),
                          color: Colors.grey,
                          onPressed: navigateToHomeScreen,
                        ),
                        Text(
                          "BACK",
                          style: TextStyle(color: Colors.grey),
                        )
                      ],
                    )),
              )
            ],
          ),
          drawer: Drawer(
            child: Column(
              children: <Widget>[
                UserAccountsDrawerHeader(
                    accountName: new Text("Nilesh Rathod"), accountEmail: null),
                Column(children: drawerOptions)
              ],
            ),
          ),
          body: _getDrawerItemWidget(_selectedDrawerIndex)),
    );
  }
}

但我正在低于异常

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>#7e1a8]
  state: OverlayState#72b8b(entries: [OverlayEntry#cf40a(opaque: false; maintainState: false), OverlayEntry#e10aa(opaque: false; maintainState: true), OverlayEntry#e0ccc(opaque: false; maintainState: false), OverlayEntry#5fdab(opaque: false; maintainState: true)])
The widget which was currently being built when the offending call was made was: HomePage
  dirty
  dependencies: [_InheritedTheme, _LocalizationsScope-[GlobalKey#c84d4]]
  state: HomePageState#982b0
User-created ancestor of the error-causing widget was: 
  MaterialApp file:///home/ctpl119/Documents/NEW_PROJECT/oricon/oricon/lib/main.dart:11:10
When the exception was thrown, this was the stack: 
#0      Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:3687:11)
#1      Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:3702:6)
#2      State.setState (package:flutter/src/widgets/framework.dart:1161:14)
#3      OverlayState.insertAll (package:flutter/src/widgets/overlay.dart:346:5)
#4      OverlayRoute.install (package:flutter/src/widgets/routes.dart:43:24)

I have already checked below Stack-overflow links

如果需要更多信息,请告诉我。提前致谢。我们将不胜感激。

最佳答案

您可以在下面复制粘贴运行完整代码
你需要 WidgetsBinding.instance.addPostFrameCallback

代码 fragment

case 4:
        //showAlertDialog(context);
        WidgetsBinding.instance.addPostFrameCallback((_) {
          showAlertDialog(context);
        });
        visibilityTag = false;
        return AccountDetails();

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class DrawerItem {
  String title;
  IconData icon;

  DrawerItem(this.title, this.icon);
}

class HomePage extends StatefulWidget {
  final drawerItems = [
    DrawerItem("View Your account", Icons.account_circle),
    DrawerItem("Request", Icons.receipt),
    DrawerItem("Order", Icons.shopping_cart),
    DrawerItem("Report", Icons.report_problem),
    DrawerItem("Log out", Icons.info)
  ];

  @override
  State<StatefulWidget> createState() {
    return new HomePageState();
  }
}

class HomePageState extends State<HomePage> {
  int _selectedDrawerIndex = 0;
  bool visibilityTag = false;

  showAlertDialog(BuildContext context) {
    // set up the button
    Widget okButton = FlatButton(
      child: Text("OK"),
      onPressed: () {
        Navigator.of(context).pop();
      },
    );
    Widget cancelButton = FlatButton(
      child: Text("Cancel"),
      onPressed: () {
        Navigator.of(context).pop();
      },
    );

    // set up the AlertDialog
    AlertDialog alert = AlertDialog(
      elevation: 10,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(20.0))),
      title: Text("ORICON"),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text("Are you sure you want to logout?"),
          Padding(
            padding: const EdgeInsets.only(top: 20.0),
            child: Text(
              "1300 898 989",
              style: TextStyle(
                  color: Colors.blue,
                  fontWeight: FontWeight.bold,
                  fontSize: 20.0),
            ),
          ),
        ],
      ),
      actions: [okButton, cancelButton],
    );

    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return alert;
      },
    );
  }

  _getDrawerItemWidget(int pos) {
    switch (pos) {
      case 0:
        visibilityTag = false;
        return AccountDetails();
      case 1:
        visibilityTag = true;
        return RequestBin();
      case 2:
        visibilityTag = true;
        return OrderBin();
      case 3:
        visibilityTag = true;
        return Report();
      case 4:
        //showAlertDialog(context);
        WidgetsBinding.instance.addPostFrameCallback((_) {
          showAlertDialog(context);
        });
        visibilityTag = false;
        return AccountDetails();
      default:
        return new Text("Error");
    }
  }

  _onSelectItem(int index) {
    if (index == 0) {
      visibilityTag = false;
    } else {
      visibilityTag = true;
    }
    setState(() => _selectedDrawerIndex = index);
    //_selectedDrawerIndex = index; // removed setState call
    Navigator.of(context).pop(); // close the drawer
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> drawerOptions = [];
    for (var i = 0; i < widget.drawerItems.length; i++) {
      var d = widget.drawerItems[i];
      drawerOptions.add(new ListTile(
        leading: Icon(d.icon),
        title: Text(d.title),
        selected: i == _selectedDrawerIndex,
        onTap: () => _onSelectItem(i),
      ));
    }

    Future<bool> customPop() {
      if (_selectedDrawerIndex == 0) {
        visibilityTag = false;
        return Future.value(true);
      } else {
        setState(() {
          visibilityTag = false;
          _selectedDrawerIndex = 0;
        });
        return Future.value(false);
      }
    }

    void navigateToHomeScreen() {
      if (_selectedDrawerIndex == 0) {
        visibilityTag = false;
      } else {
        visibilityTag = false;
        setState(() {
          _selectedDrawerIndex = 0;
        });
      }
    }

    return WillPopScope(
      onWillPop: customPop,
      child: Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.white,
            iconTheme: IconThemeData(color: Colors.black), //add this line here
            // here we display the title corresponding to the fragment
            // you can instead choose to have a static title
            title: Text(
              widget.drawerItems[_selectedDrawerIndex].title,
              style: TextStyle(color: Colors.black),
            ),
            actions: <Widget>[
              Padding(
                padding: const EdgeInsets.only(right: 10),
                child: Visibility(
                    visible: visibilityTag,
                    child: Row(
                      children: <Widget>[
                        IconButton(
                          icon: new Icon(Icons.arrow_back_ios),
                          color: Colors.grey,
                          onPressed: navigateToHomeScreen,
                        ),
                        Text(
                          "BACK",
                          style: TextStyle(color: Colors.grey),
                        )
                      ],
                    )),
              )
            ],
          ),
          drawer: Drawer(
            child: Column(
              children: <Widget>[
                UserAccountsDrawerHeader(
                    accountName: new Text("Nilesh Rathod"), accountEmail: null),
                Column(children: drawerOptions)
              ],
            ),
          ),
          body: _getDrawerItemWidget(_selectedDrawerIndex)),
    );
  }
}

class AccountDetails extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text("AccountDetails");
  }
}

class RequestBin extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text("RequestBin");
  }
}

class OrderBin extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text("OrderBin");
  }
}

class Report extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text("Report");
  }
}

关于android - 无法构建,因为 frawework 已经在构建 - Flutter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59456069/

相关文章:

android - ListView 子项的 onclicklistener

android - Image_picker throws removeInvalidNode jank list 中的所有节点都超时而不是返回图像

flutter - 对齐底部导航中的小部件覆盖正文

firebase - 有没有办法检索 Firestore 集合中的文档并将它们存储为 list<user-defined class>?

安卓:NoClassDefFoundError android.os.AsyncTask

android - 服务如何将结果返回给 Activity

android - 尝试创建自定义 View.onFocusChangeListener 时出错

flutter - 消息 "flutter run: No connected devices"

android - 从 Android 平台发送位图到 Flutter

java - Dart 将 JSON 解析成表