在有状态窗口小部件上实现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)
)
],
)
)
),
)
]
)
)
//)
);
})
);
}
}
答案 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))
],
))),
)
])));
}));
}
}