消费者不使用 Riverpod 重建 UI
Posted
技术标签:
【中文标题】消费者不使用 Riverpod 重建 UI【英文标题】:Consumer not rebuilding UI using riverpod 【发布时间】:2021-04-21 23:12:12 【问题描述】:我正在尝试使用 Riverpod 制作简单的 stateNotifier。当我单击按钮时,它将在值之间切换。我检查了值,按下按钮时它会改变。问题是 UI 没有自行重建。我检查了文档并且很确定我做得对。
主屏幕
class HomeScreen extends StatefulWidget
@override
_HomeScreenState createState() => _HomeScreenState();
class _HomeScreenState extends State<HomeScreen>
@override
void initState()
super.initState();
@override
Widget build(BuildContext context)
return SafeArea(
child: Consumer(
builder: (context, watch, child)
final drawer = watch(drawerProvider.state);
return Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Text(drawer.isOpen.toString()),
Text(drawer.x.toString()),
Text(drawer.y.toString()),
Text(drawer.scale.toString()),
FloatingActionButton(
onPressed: ()
context.read(drawerProvider).toggleDrawer();
)
],
),
);
,
),
);
提供者
import 'package:flutter_riverpod/all.dart';
class Drawer
double x,y,scale;
bool isOpen;
Drawer(this.x,this.y,this.scale,this.isOpen);
class DrawerNotifier extends StateNotifier<Drawer>
DrawerNotifier() : super(Drawer(0,0,1,false));
void toggleDrawer()
if(state.isOpen)
state.x = 0;
state.y = 0;
state.scale = 1;
else
state.x = 0.5;
state.y = 0.1;
state.scale = 0.8;
state.isOpen = !state.isOpen;
final drawerProvider = StateNotifierProvider((ref) => new DrawerNotifier());
【问题讨论】:
【参考方案1】: import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@immutable
class Drawer
final double x;
final double y;
final double scale;
final bool isOpen;
Drawer(this.x, this.y, this.scale, this.isOpen);
factory Drawer.initial()
return Drawer(0, 0, 1, false);
Drawer copyWith(
double x,
double y,
double scale,
bool isOpen,
)
return Drawer(
x ?? this.x,
y ?? this.y,
scale ?? this.scale,
isOpen ?? this.isOpen,
);
@override
String toString()
return 'Drawer(x: $x, y: $y, scale: $scale, isOpen: $isOpen)';
class DrawerNotifier extends StateNotifier<Drawer>
final Drawer drawer;
DrawerNotifier(this.drawer) : super(drawer ?? Drawer.initial());
void toggleDrawer()
if (state.isOpen)
state = state.copyWith(x: 0, y: 0, scale: 1);
else
state = state.copyWith(x: 0.5, y: 0.1, scale: 0.8);
state = state.copyWith(isOpen: !state.isOpen);
print("new state>> $state");
final drawerProvider =
StateNotifierProvider((ref) => new DrawerNotifier(Drawer.initial()));
class DrawerScreen extends StatefulWidget
@override
_DrawerScreenState createState() => _DrawerScreenState();
class _DrawerScreenState extends State<DrawerScreen>
@override
void initState()
super.initState();
@override
Widget build(BuildContext context)
return SafeArea(
child: Consumer(
builder: (context, watch, child)
final drawer = watch(drawerProvider.state);
return Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Text(drawer.isOpen.toString()),
Text(drawer.x.toString()),
Text(drawer.y.toString()),
Text(drawer.scale.toString()),
FloatingActionButton(onPressed: ()
context.read(drawerProvider).toggleDrawer();
)
],
),
);
,
),
);
【讨论】:
我已经尝试将代码从 ChangeNotifier() 更改为 StateNotifier() 1 周。我有类似的问题,但用“copyWith()”方法解决了这个问题。谢谢!作为旁注,我不是专业的颤振开发人员,不要评判我:) 这是一个体面且正确的答案,但它没有明确说明修复工作的方式或原因。关键是你替换状态对象,而不是简单地更新它的属性......以上是关于消费者不使用 Riverpod 重建 UI的主要内容,如果未能解决你的问题,请参考以下文章
当消费者触发重建时,MaterialApp 主页小部件不会被渲染。需要油漆