Drawer的父类为StatelessWidget,不可刷新,今天来讲一下刷新的办法
需求:点击A用户,弹出侧边栏,侧边栏展示用户的数据。
需要使用StreamBuilder。但是使用stream发数据是行不通的,因为数据传递不进去。
但是使用StreamBuilder依旧可以收到通知。所以流程就需要改变一下
一、点击按键后刷新Drawer并展示
1、使用StatefulWidget
2、在state里创建备用数据,本例为SSML ssml=SSML();
3、点击按键,更新备用数据:ssml = ssmlList[index];
4、通知StreamBuilder:streamController.add(‘event’);
5、StreamBuilder接到通知,使用备用数据重新构造
二、刷新Drawer面板上的内容
具体为使用StatefulBuilder自带的setState方法,不要使用公共的,作为区别,名字改为setStateB。代码片段为_changeRate方法
class DrawerTest extends StatefulWidget {
final File file;
const DrawerTest(this.file, {super.key});
@override
State<StatefulWidget> createState() {
return _DrawerTestState();
}
}
class _DrawerTestState extends State<DrawerTest> {
SSML ssml = SSML();
StreamController streamController = StreamController.broadcast();
List<SSML> ssmlList = [];
@override
void initState() {
ssmlList.add(SSML()..name = 'dan');
ssmlList.add(SSML()..name = 'ada');
super.initState();
}
final GlobalKey<ScaffoldState> _ssKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _ssKey,
drawer: _getDrawer(),
appBar: AppBar(
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(Icons.arrow_back)),
title: const Text('Drawer测试'),
),
body: SafeArea(
child: Container(
color: Colors.white10,
padding: const EdgeInsets.all(15),
child: ListView.builder(
itemCount: ssmlList.length,
itemBuilder: (context, index) {
return ElevatedButton(
onPressed: () {
ssml = ssmlList[index];
streamController.add('event'); //通知StreamBuilder该刷新了
_ssKey.currentState!.openDrawer();
},
child: Text('${ssmlList[index].name}打开左边栏'));
}),
)));
}
StreamBuilder _getDrawer() {
return StreamBuilder(
stream: streamController.stream,
builder: (context, shot) {
return Drawer(child: StatefulBuilder(
builder: (context, setStateB) {
return _changeRate(ssml);
},
));
});
}
Widget _changeRate(SSML ssml) {
return StatefulBuilder(builder: (context, setStateB) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('速度:${ssml.rate}'),
Slider(
value: ssml.rate.toDouble(),
max: 500,
min: -500,
onChanged: (value) {
setStateB(() {
ssml.rate = value.toInt();
});
// setState(() {});
})
],
);
});
}
}
class SSML {
late String name;
int rate = 0;
}