Я хочу сохранить состояние виджета в Scaffold.drawer
. The Scaffold.drawer
— это пользовательский виджет, в котором есть ПоднятьКнопку.
При нажатии кнопки текст в кнопке изменился.
Но когда ящик закрывается и снова открывается, измененный текст сбрасывается.
Я использую "с AutomaticKeepAliveClientMixin<>
" в своем пользовательском Выдвижной ящик, но это не работает.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo"),
),
drawer: Drawer(child: CustomDrawer(),),
body: Center(
child: Text("Flutter Demo"),
),
);
}
}
class CustomDrawer extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _CustomDrawerState();
}
}
class _CustomDrawerState extends State<CustomDrawer> with AutomaticKeepAliveClientMixin<CustomDrawer> {
String btnText = "Click!";
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return Center(
child: RaisedButton(onPressed: () {
setState(() {
btnText = "Clicked!!";
});
}, child: Text(btnText),),
);
}
}
Я ожидаю, что состояние виджета может сохраниться, даже если ящик закрыт.
В вашем случае у вас есть 2 варианта:
_MyHomePageState
;Redux
, Bloc
, ScopedModel
. Я думаю, что ScopedModel
отлично подходит для вас в этом случае.иначе вы не сможете контролировать состояние Drawer
. потому что он воссоздает каждый момент, когда вы вызываете Drawer
кнопкой действия в Appbar
;
Создайте отдельный виджет для ящика и просто используйте его там, где вам нужно.
Управляйте состоянием ящика с помощью Провайдер
class DrawerStateInfo with ChangeNotifier {
int _currentDrawer = 0;
int get getCurrentDrawer => _currentDrawer;
void setCurrentDrawer(int drawer) {
_currentDrawer = drawer;
notifyListeners();
}
void increment() {
notifyListeners();
}
}
Добавление управления состоянием в дерево виджетов
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
),
providers: <SingleChildCloneableWidget>[
ChangeNotifierProvider<DrawerStateInfo>(
builder: (_) => DrawerStateInfo()),
],
);
}
}
Создание виджета ящика для повторного использования в приложении
class MyDrawer extends StatelessWidget {
MyDrawer(this.currentPage);
final String currentPage;
@override
Widget build(BuildContext context) {
var currentDrawer = Provider.of<DrawerStateInfo>(context).getCurrentDrawer;
return Drawer(
child: ListView(
children: <Widget>[
ListTile(
title: Text(
"Home",
style: currentDrawer == 0
? TextStyle(fontWeight: FontWeight.bold)
: TextStyle(fontWeight: FontWeight.normal),
),
trailing: Icon(Icons.arrow_forward),
onTap: () {
Navigator.of(context).pop();
if (this.currentPage == "Home") return;
Provider.of<DrawerStateInfo>(context).setCurrentDrawer(0);
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) =>
MyHomePage(title: "Home")));
},
),
ListTile(
title: Text(
"About",
style: currentDrawer == 1
? TextStyle(fontWeight: FontWeight.bold)
: TextStyle(fontWeight: FontWeight.normal),
),
trailing: Icon(Icons.arrow_forward),
onTap: () {
Navigator.of(context).pop();
if (this.currentPage == "About") return;
Provider.of<DrawerStateInfo>(context).setCurrentDrawer(1);
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) => MyAboutPage()));
},
),
],
),
);
}
}
Использование ящика на одной из ваших страниц
class MyAboutPage extends StatefulWidget {
@override
_MyAboutPageState createState() => _MyAboutPageState();
}
class _MyAboutPageState extends State<MyAboutPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('About Page'),
),
drawer: MyDrawer("About"),
);
}
}
Рабочий раствор. Хотя Примечание: Здесь:
Provider.of<DrawerStateInfo>(context).setCurrentDrawer(0);
и здесьProvider.of<DrawerStateInfo>(context).setCurrentDrawer(1);
должны бытьProvider.of<DrawerStateInfo>(context, listen: false).setCurrentDrawer(0);
иProvider.of<DrawerStateInfo>(context, listen: false).setCurrentDrawer(1);
соответственно. В противном случае это выдаст ошибку, специфичную для провайдера.