CupertinoActionSheet在布局错误期间抛出无限大小

时间:2020-05-02 07:44:43

标签: flutter flutter-cupertino

在有状态窗口小部件上实现CupertinoActionSheet时调用SingleChildScrollView时出现以下错误:

在布局期间,

_RenderCupertinoAlertActions对象被赋予了无限大小。相关的引起错误的小部件是 CupertinoActionSheet lib \ main.dart:82引发异常时,正在处理以下RenderObject: _RenderCupertinoAlertActions#56898 relayoutBoundary = up19 NEEDS布局NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE RenderObject: _RenderCupertinoAlertActions#56898 relayoutBoundary = up19需求布局需求需求油漆需求需求组成位更新 约束:BoxConstraints(w = 395.4,0.0 <= h <= Infinity) 尺寸:尺寸(395.4,无限) 子1:RenderPointerListener#7df6e relayoutBoundary = up20 NEEDS-PAINT parentData:offset = Offset(0.0,0.0); id = null(可以使用大小) 约束:BoxConstraints(w = 395.4,0.0 <= h <= Infinity) 尺寸:尺寸(395.4,无穷大) 行为:不透明 听众:下来

完整的代码附在此处(根据下面的注释进行编辑以解决无限大小错误):

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.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: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  List<String> leaveTypes = ["Vacation Leave","Ordinary Sick Leave","Childcare Leave"];
  String applyLeaveType;

  @override
  Widget build(BuildContext context) {
    if(applyLeaveType == null){
      applyLeaveType = leaveTypes[0];
    };
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: LayoutBuilder(builder:(context, constraints){
        return SingleChildScrollView(
          /*child: ConstrainedBox(
            constraints: BoxConstraints(
              minWidth: constraints.maxWidth, minHeight: constraints.maxHeight
            ),*/
            child: Container(
              height: constraints.maxHeight,
              color: Color.fromARGB(255, 244, 246, 249),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  //Text for leave type
                  Container(                            
                    alignment: Alignment(-1.0,0.0),
                    padding:EdgeInsets.only(
                      top: 10, bottom: 5, left: 20, right: 20
                    ),
                    child: Text("I want to apply for",
                      style: TextStyle(fontSize: 16),
                      textAlign: TextAlign.left,
                    )
                  ),
                  SizedBox(
                    width: MediaQuery.of(context).size.width,
                    height:80,
                    child: GestureDetector(
                      onTap:() {
                        buildLeaveList(){
                          List<Widget> widgets = List();
                          leaveTypes.forEach((leaveType){
                            print(leaveType);
                            widgets.add(
                              CupertinoActionSheetAction(
                                child: Text(leaveType),
                                onPressed: () {
                                  setState(() {
                                    applyLeaveType = leaveType;
                                  });
                                  Navigator.pop(context);
                                }
                              )
                            );

                          });
                          return widgets;
                        }
                        final action = Container(
                          height: MediaQuery.of(context).size.height,
                          child: CupertinoActionSheet(

                            title: Text(
                              "Leave Type",
                              style: TextStyle(fontSize:16)
                            ),
                            actions: buildLeaveList(),
                            cancelButton: CupertinoActionSheetAction(
                              child: Text("Back"),
                              onPressed:(){
                                Navigator.pop(context);
                              }
                            )
                          )
                        );
                        showCupertinoModalPopup(context: context, builder: (context) => action);
                      },
                      child: Container(
                        alignment: Alignment(0.0,0.0),
                        padding:EdgeInsets.only(
                          top: 10, bottom: 10, left: 20, right: 20
                        ),
                        decoration: BoxDecoration(
                          color: Colors.white,
                          //border: Border.all(),
                          //borderRadius: BorderRadius.all(Radius.circular(10))
                        ),                     
                        child:Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: <Widget>[
                            Container(
                              padding: EdgeInsets.all(10),
                              child: Text(applyLeaveType),
                            ),
                            Container(
                              padding: EdgeInsets.all(10),
                              child: Icon(Icons.keyboard_arrow_down)
                            )
                          ],
                        )
                      )
                    ),
                  )
                ]
              )
            )
          //)
        );  
      })  
    );
  }
}

1 个答案:

答案 0 :(得分:0)

问题是,如果您使用任何列表,那么它需要其父小部件的特定高度,可以在其中构建listview。

如果将ListView与ShrinkWrap:true结合使用,它将生成其他小部件,但底页的高度将变为整个屏幕的高度。

最终解决方案: 我们可以在单独的方法中创建一个变量,然后将所有项目添加到其中,最后在操作中调用该方法。

以下代码可帮助您进一步理解。

创建以下方法:

 callme() {
    List<Widget> mywidget = List();
    leaveTypes.forEach((e) => mywidget.add(CupertinoActionSheetAction(
        child: Text(e),
        onPressed: () {
          setState(() {
            applyLeaveType = e;
          });
          Navigator.pop(context);
        })));
    return mywidget;
  }

通过以下方式调用此方法。

actions: callme()

更新:

工作演示:

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> leaveTypes = [
    "Vacation Leave",
    "Ordinary Sick Leave",
    "Childcare Leave"
  ];
  String applyLeaveType;
  callme() {
    List<Widget> mywidget = List();
    leaveTypes.forEach((e) => mywidget.add(CupertinoActionSheetAction(
        child: Text(e),
        onPressed: () {
          setState(() {
            applyLeaveType = e;
          });
          Navigator.pop(context);
        })));
    return mywidget;
  }

  @override
  Widget build(BuildContext context) {
    if (applyLeaveType == null) {
      applyLeaveType = leaveTypes[0];
    }

    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: LayoutBuilder(builder: (context, constraints) {
          return SingleChildScrollView(
              child: Container(
                  height: constraints.maxHeight,
                  color: Color.fromARGB(255, 244, 246, 249),
                  child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Container(
                            alignment: Alignment(-1.0, 0.0),
                            padding: EdgeInsets.only(
                                top: 10, bottom: 5, left: 20, right: 20),
                            child: Text(
                              "I want to apply for",
                              style: TextStyle(fontSize: 16),
                              textAlign: TextAlign.left,
                            )),
                        SizedBox(
                          width: MediaQuery.of(context).size.width,
                          height: 80,
                          child: GestureDetector(
                              onTap: () {
                                final action = Container(
                                    child: CupertinoActionSheet(
                                        title: Text("Leave Type",
                                            style: TextStyle(fontSize: 16)),
                                        actions: callme(),
                                        cancelButton:
                                            CupertinoActionSheetAction(
                                                child: Text("Back"),
                                                onPressed: () {
                                                  Navigator.pop(context);
                                                })));
                                showCupertinoModalPopup(
                                    context: context,
                                    builder: (context) => action);
                              },
                              child: Container(
                                  alignment: Alignment(0.0, 0.0),
                                  padding: EdgeInsets.only(
                                      top: 10, bottom: 10, left: 20, right: 20),
                                  decoration: BoxDecoration(
                                    color: Colors.white,
                                  ),
                                  child: Row(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceBetween,
                                    children: <Widget>[
                                      Container(
                                        padding: EdgeInsets.all(10),
                                        child: Text(applyLeaveType),
                                      ),
                                      Container(
                                          padding: EdgeInsets.all(10),
                                          child:
                                              Icon(Icons.keyboard_arrow_down))
                                    ],
                                  ))),
                        )
                      ])));
        }));
  }
}