我有使用 CupertinoTabScaffold 显示底部导航的代码,我想在其中一个菜单上显示底部对话框表,但出现错误
<块引用>以下断言在构建 Builder 时被抛出(脏,依赖项:[_InheritedTheme, _LocalizationsScope- [GlobalKey # a6d51]]): 在构建过程中调用 setState() 或 markNeedsBuild()。
这是我的代码
class AppTab extends StatefulWidget {
final dataUser;
AppTab(this.dataUser);
@override
_AppTabState createState() => _AppTabState(dataUser);
}
class _AppTabState extends State<AppTab> {
final user;
_AppTabState(this.user);
@override
Widget build(BuildContext context) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
if (state == AuthenticationState.unauthenticated()) {
Navigator.pushNamedAndRemoveUntil(context, '/login', (route) => false, arguments: state.loginPageState);
}
},
child: CupertinoTabScaffold(
controller: tabController,
tabBar: CupertinoTabBar(
activeColor: HexColor("#26ADE4"),
inactiveColor: HexColor("#707070"),
items: [
BottomNavigationBarItem(
label: "Menu 1",
icon: Image.asset("assets/icon_tab_home.png", height: 25, width: 22),
activeIcon: Image.asset("assets/icon_tab_home_active.png", height: 25, width: 22),
),
BottomNavigationBarItem(
label: "Menu 2",
icon: Image.asset("assets/icon_tab_buat_bill.png", height: 25, width: 22),
activeIcon: Image.asset("assets/icon_tab_buat_bill_active.png", height: 25, width: 22),
),
BottomNavigationBarItem(
label: "Menu 3",
icon: Image.asset("assets/icon_tab_account.png", height: 25, width: 22),
activeIcon: Image.asset("assets/icon_tab_account_active.png", height: 25, width: 22),
),
],
),
tabBuilder: (context, index) {
if (index == 0) {
return HomePage(user);
} else if (index == 1) {
return _bottomSheetMore(context);
}
return AccountPage(user);
}),
);
}
_bottomSheetMore(context) {
showModalBottomSheet(
context: context,
builder: (builder) {
return new Container(
padding: EdgeInsets.only(
left: 5.0,
right: 5.0,
top: 5.0,
bottom: 5.0,
),
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0))),
child: new Wrap(
children: <Widget>[
new ListTile(
title: const Text(
'Menu Akun',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w700,
),
),
subtitle: Text("Pilih salah satu"),
),
new Divider(
height: 10.0,
),
new ListTile(
title: const Text(
'Menu Home',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w700,
),
),
),
new Divider(
height: 10.0,
),
new ListTile(
title: const Text(
'Logout',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w700,
),
),
onTap: () async {
// Add Here
},
),
],
),
);
},
);
}
}
答案 0 :(得分:1)
它显示该错误是因为在显示模态底部表单之前应该首先绘制小部件。要显示模态底部工作表,请在 Future.delayed(...)
内调用它。
你可以试试这样的。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: AppTab()));
class AppTab extends StatefulWidget {
@override
_AppTabState createState() => _AppTabState();
}
class _AppTabState extends State<AppTab> {
final CupertinoTabController _controller = CupertinoTabController();
final List<CupertinoPageScaffold> _pages = <CupertinoPageScaffold>[
CupertinoPageScaffold(
child: const Center(child: Text('Home Page')),
),
CupertinoPageScaffold(
child: const Center(child: Text('2nd Page')),
),
CupertinoPageScaffold(
child: const Center(child: Text('Account Page')),
),
];
bool _isBottomSheetShown = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: CupertinoTabScaffold(
controller: _controller,
tabBar: CupertinoTabBar(
activeColor: Colors.red,
inactiveColor: Colors.blue,
items: const [
BottomNavigationBarItem(
label: "Menu 1",
icon: Icon(Icons.ac_unit),
),
BottomNavigationBarItem(
label: "Menu 2",
icon: Icon(Icons.local_activity),
),
BottomNavigationBarItem(
label: "Menu 3",
icon: Icon(Icons.assessment),
),
],
),
tabBuilder: (context, index) {
return CupertinoTabView(
builder: (BuildContext context) {
if (_controller.index == 1 && index == 1) {
_bottomSheetMore(context);
}
return _pages[index];
},
);
},
),
);
}
Future<void> _bottomSheetMore(context) async {
if (_isBottomSheetShown) {
return;
}
_isBottomSheetShown = true;
await Future<void>.delayed(
const Duration(milliseconds: 10),
() => showModalBottomSheet<void>(
context: context,
builder: (_) {
return Container(
height: 300,
padding: const EdgeInsets.all(5),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0),
),
),
child: Wrap(
children: <Widget>[
ListTile(
title: const Text(
'Menu Akun',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w700,
),
),
subtitle: const Text("Pilih salah satu"),
),
const Divider(height: 10.0),
ListTile(
title: const Text(
'Menu Home',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w700,
),
),
),
const Divider(height: 10.0),
ListTile(
title: const Text(
'Logout',
style: TextStyle(
fontSize: 14.0,
fontWeight: FontWeight.w700,
),
),
onTap: () async {
// Add Here
},
),
],
),
);
},
),
);
_isBottomSheetShown = false;
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
}