我现在有一个可以创建计时器列表的应用。它使用两个BLoC,一个用于单个计时器,另一个用于整体列表。您可以在下面看到列表的示例:
在图像中,您可以看到索引1和2尚未启动索引0和2。我的问题是,每当我在列表中添加或删除项目时,所有计时器都会重置。
是否有一种方法可以在重绘父窗口小部件时保持其状态不变?
这是列表代码:
此处的项目图块包含计时器的BLoC:
\s
最初,我认为这是一个关键问题,因为该列表未正确删除,但是我相信我已经按照示例中显示的方式实现了键,但仍然存在问题。
$
这是在BLoC列表中传递的计时器模型:
class HomePage extends StatefulWidget {
static const TextStyle timerTextStyle = TextStyle(
fontSize: 30,
fontWeight: FontWeight.bold,
);
final Stream shouldTriggerChange;
HomePage({@required this.shouldTriggerChange});
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
StreamSubscription streamSubscription;
@override
initState() {
super.initState();
streamSubscription = widget.shouldTriggerChange.listen((data) {
createTimer(context, data);
});
}
void createTimer(BuildContext context, timer_type timer) {
BlocProvider.of<ListBloc>(context).add(Add(
id: DateTime.now().toString(),
duration: timer == timer_type.timer ? 100 : 0,
timer: timer,
timerTextStyle: HomePage.timerTextStyle));
}
@override
didUpdateWidget(HomePage old) {
super.didUpdateWidget(old);
// in case the stream instance changed, subscribe to the new one
if (widget.shouldTriggerChange != old.shouldTriggerChange) {
streamSubscription.cancel();
streamSubscription = widget.shouldTriggerChange
.listen((data) => createTimer(context, data));
}
}
@override
dispose() {
super.dispose();
streamSubscription.cancel();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<ListBloc, ListState>(
builder: (context, state) {
if (state is Failure) {
return Center(
child: Text('Oops something went wrong!'),
);
}
if (state is Loaded) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
state.timers.isEmpty
? Center(
child: Text('no content'),
)
: Expanded(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return ItemTile(
index: index,
timer: state.timers[index],
onDeletePressed: (id) {
BlocProvider.of<ListBloc>(context)
.add(Delete(id: id));
},
);
},
itemCount: state.timers.length,
),
),
],
);
}
return Center(
child: CircularProgressIndicator(),
);
},
);
}
}
任何帮助将不胜感激。
谢谢!
答案 0 :(得分:1)
每次重建列表时,您都在创建一个新的UniqueKey
,这会强制删除该状态
要解决此问题,您必须将密钥与计时器相关联,例如,将计时器包装在一个包含计时器和密钥的类中,例如:
class KeyedTimer {
final key = UniqueKey();
Timer timer;
}
因此,现在您将拥有一个KeyedTimer对象列表,而不是计时器列表,并且可以在列表的itembuilder中使用该键