此代码非常简单:显示一个有模态的底部工作表,当用户单击按钮时,它会将工作表的高度增加10。
但是什么也没发生。实际上,只有在用户用手指“滑动”底部工作表的情况下,它才会更新其大小(我相信滑动会导致工作表内部出现setState)。
我的问题是:如何调用ModalBottomSheet的更新状态?
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
height: heightOfModalBottomSheet,
child: RaisedButton(
onPressed: () {
setState(() {
heightOfModalBottomSheet += 10;
});
}),
);
});
答案 0 :(得分:5)
请参考以下工作代码。我为ModalBottomSheet
创建了一个新的有状态小工具(showModalBottomSheet
)。按下按钮时,我们正在重建仅ModalBottomSheet
,它现在要干净得多。如果需要动画来更改高度,我们可以使用AnimationController
。
import 'dart:async';
import 'package:flutter/material.dart';
class ModalBottomSheet extends StatefulWidget {
_ModalBottomSheetState createState() => _ModalBottomSheetState();
}
class _ModalBottomSheetState extends State<ModalBottomSheet>
with SingleTickerProviderStateMixin {
var heightOfModalBottomSheet = 100.0;
Widget build(BuildContext context) {
return Container(
height: heightOfModalBottomSheet,
child: RaisedButton(
child: Text("Press"),
onPressed: () {
heightOfModalBottomSheet += 100;
setState(() {});
}),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
Future(() => showModalBottomSheet(
context: context,
builder: (context) {
return ModalBottomSheet();
}));
return new Scaffold(
appBar: new AppBar(
title: new Text("Modal example"),
),
);
}
}
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(title: 'Flutter Demo', home: new MyHomePage());
}
}
答案 1 :(得分:2)
您也许可以使用showBottomSheet
中的ScaffoldState
。了解更多关于此showBottomSheet的here。
这将显示bottomSheet并返回一个控制器PersistentBottomSheetController
。使用此控制器,您可以调用controller.SetState((){})
,它将重新渲染bottomSheet。
这是一个例子
PersistentBottomSheetController _controller; // <------ Instance variable
final _scaffoldKey = GlobalKey<ScaffoldState>(); // <---- Another instance variable
.
.
.
void _incrementBottomSheet(){
_controller.setState(
(){
heightOfModalBottomSheet += 10;
}
)
}
.
void _createBottomSheet() async{
_controller = await _scaffoldKey.currentState.showBottomSheet(
context: context,
builder: (context) {
return Container(
height: heightOfModalBottomSheet,
child: RaisedButton(
onPressed: () {
_incrementBottomSheet()
}),
);
});
}
答案 2 :(得分:1)
您可以使用Flutter的StatefulBuilder
来包装您的ModalBottomSheet,如下所示:
showModalBottomSheet(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState /*You can rename this!*/) {
return Container(
height: heightOfModalBottomSheet,
child: RaisedButton(onPressed: () {
setState(() {
heightOfModalBottomSheet += 10;
});
}),
);
});
});
请注意,新的setState
将覆盖您的主窗口小部件setState
,但请确保您可以对其进行重命名,以便您可以设置父窗口小部件和模态的状态
//This sets modal state
setModalState(() {
heightOfModalBottomSheet += 10;
});
//This sets parent widget state
setState(() {
heightOfModalBottomSheet += 10;
});
答案 3 :(得分:1)
截屏:
创建一个类:
class MyBottomSheet extends StatefulWidget {
@override
_MyBottomSheetState createState() => _MyBottomSheetState();
}
class _MyBottomSheetState extends State<MyBottomSheet> {
bool _flag = false;
@override
Widget build(BuildContext context) {
return Column(
children: [
FlutterLogo(
size: 300,
style: FlutterLogoStyle.stacked,
textColor: _flag ? Colors.black : Colors.red,
),
RaisedButton(
onPressed: () => setState(() => _flag = !_flag),
child: Text('Change Color'),
)
],
);
}
}
用法:
showModalBottomSheet(
context: context,
builder: (_) => MyBottomSheet(),
);
答案 4 :(得分:0)
为 showModalBottomSheet() 创建一个单独的 StatefulWidget,如
showModalBottomSheet(
context: context,
builder: (ctx) {
return MapBottomSheet();
});
底部有状态小部件
class MapBottomSheet extends StatefulWidget {
@override
_MapBottomSheetState createState() => _MapBottomSheetState();
}
class _MapBottomSheetState extends State<MapBottomSheet> {
List<String> places = [];
void _setPlaces(String place) {
setState(() {
places.add(place);
});
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.black12,
child: Column(
children: [
AppTextField(
hint: "Search",
onEditingComplete: () {},
onChanged: (String text) {},
onSubmitted: (String text) async {
// Await the http get response, then decode the json-formatted response.
var response = await http.get(Uri.parse(
'https://api.mapbox.com/geocoding/v5/mapbox.places/$text.json?access_token=pk.eyJ1IjoidjNyc2lvbjkiLCJhIjoiY2ttNnZldmk1MHM2ODJxanh1ZHZqa2I3ZCJ9.e8pZsg87rHx9FSM0pDDtlA&country=PK&fuzzyMatch=false&place=park'));
if (response.statusCode == 200) {
Map<String, dynamic> data = jsonDecode(response.body);
print(data.toString());
List<dynamic> features = data['features'];
features.forEach((dynamic feature) {
setState(() {
_setPlaces(feature['place_name']);
});
});
} else {
print('Request failed with status: ${response.statusCode}.');
}
},
),
Expanded(
child: Container(
height: 250.0,
width: double.infinity,
child: ListView.builder(
itemCount: places.length,
itemBuilder: (ctx, idx) {
return Container(
child: Text(places[idx]),
);
}),
),
),
],
),
);
}
}
答案 5 :(得分:-1)
使用全局控制器保存showen bottomMenue并调用setState 完成她的例子 https://github.com/mhmoudsabry/flutter_Examples/blob/master/buildBottomNavigationMenuWithSetStata.dart