我是 Bloc 和 Flutter 的新手。我目前正在设计一个财务/预算应用程序。
目前用户界面很简单,我有 2 个列表视图,一个用于显示收入,另一个显示费用。用户按下按钮,就会显示一个表格供他们填写(例如,如果是收入/支出、金额、类别等)。然后用户填写表格并按下保存按钮。
我有一个名为 FinanceBloc 的 Bloc。当按下保存按钮时,小部件会发出 SaveEvent。我的 Bloc 处理它,一旦保存,它就会发出 IncomeSavedState 或 ExpenseSavedState。我的问题是我已经用 BlocBuilder 和 if 语句包装了两个列表视图..例如
收入清单:
if (state is IncomeSavedState) {
Return the list view for income
} else { return Text(“…”)}
费用清单:
if (state is ExpenseSavedState) {
Return the list view for expense
} else { return Text(“…”)}
现在的问题是,IncomeSavedState 和 ExpenseSavedState 是由同一个父抽象类派生的。因此,当保存任何内容时,两个列表都会被触发。这样做的副作用是,因为 BlocBuilder 需要返回一个小部件,所以每当保存收入时,由于“else”代码块,支出的 ListView 就会被评估为文本“...”,反之亦然。
是否可以告诉 Bloc 不要更新状态?如果我在 2 个不同的小部件中使用相同类型的 2 个状态,如何维护状态?
我正在考虑拥有 2 个 Bloc; IncomeBloc 和 ExpenseBloc,但后来一个,我计划填充一个折线图来绘制支出金额,所以我认为如果它们是分开的,我将无法做到这一点?
如果你确实想使用ListView或者有必要使用它,你应该实现
AutomaticKeepAliveClientMixin
以确保状态不丢失。否则,如果您想要快速简单的解决方案,请使用 SingleChildScrollView
。
将
AutomaticKeepAliveClientMixin
与 ListView 一起使用:
import 'package:flutter/material.dart';
class MyListViewPage extends StatefulWidget {
@override
_MyListViewPageState createState() => _MyListViewPageState();
}
class _MyListViewPageState extends State<MyListViewPage> with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: AppBar(title: Text('ListView Example')),
body: ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
),
);
}
}
使用
SingleChildScrollView
获得快速简单的解决方案:
import 'package:flutter/material.dart';
class MySingleChildScrollViewPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('SingleChildScrollView Example')),
body: SingleChildScrollView(
child: Column(
children: List.generate(100, (index) {
return ListTile(title: Text('Item $index'));
}),
),
),
);
}
}
请根据您的具体用例的需要随意调整示例!