by using RiverPod
State management, which i try to work on self improvment to learn and how can i use that i made a simple project and i'm trying to open Drawer
by pressing on icon in AppBar
which that's on another class and file, unfortunately doing like with RiverPod
sample code my code doesn't work correctly and main class don't trigger on clicking on icon
simply i want to open drawer by clicking icon on AppBar
main file:
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Riverpod Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
final drawerState = StateNotifierProvider<DrawerVisibility>((_)=>DrawerVisibility());
return Consumer(
builder: (context, read, _) {
final state = read(drawerState.state);
print('CLICKED $state');
if(state){
_scaffoldKey.currentState.openDrawer();
}
return Scaffold(
key: _scaffoldKey,
appBar: MyAppBar(),
drawer: Drawer(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
],
),
),
);
},
);
}
}
AppBar
class file content:
class MyAppBar extends StatelessWidget with PreferredSizeWidget {
@override
Widget build(BuildContext context) {
final drawerState = StateNotifierProvider<DrawerVisibility>((_)=>DrawerVisibility());
return AppBar(
automaticallyImplyLeading: false,
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
IconButton(icon: Icon(Icons.menu), onPressed: () {
context.read(drawerState).changeDrawerState();
}),
Text('My Sample'),
],
),
);
}
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
and finally RiverPod
class
class DrawerVisibility extends StateNotifier {
DrawerVisibility() : super(false);
void changeDrawerState() => state = true;
}
another issue is when i start application in first time i get this output:
I/flutter (12240): CLICKED false
I/flutter (12240): CLICKED false
without any click on icon
instead of Consumer
you should try using ProviderListener
, its better when you want to show dialogs, snackbars, push/pop, or in this case opening a drawer. Finally instead of creating a final provider inside each build method, just create it once as a final global parameter so in each widget you read/watch it it uses the same instance
/// Create a final global StateNotifierProvider in your file instead of one inside each widget
final drawerState = StateNotifierProvider<DrawerVisibility>((_)=>DrawerVisibility());
class _MyHomePageState extends State<MyHomePage> {
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return ProviderListener<bool>(
onChange: (context, state) {
if(state) _scaffoldKey.currentState.openDrawer();
//maybe check if the _scaffoldKey is mounted or is the drawer open before doing something
},
provider: drawerState.state,
child: Scaffold(
key: _scaffoldKey,
appBar: MyAppBar(),
drawer: Drawer(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
],
),
),
),
);
}
}
And in MyAppBar
delete the drawerState so it uses the same global that your HomePage
, also when closing the drawer at some point you should make the state false again
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.