带有CircularProgressIndicator、Provider和三元运算符的用户界面,Flutter



我遇到一个问题,我的一个小部件在完成三元运算符之前一直显示。我想显示一个CircularProgressIndicator()或任何加载程序,同时三元运算符检查哪个是正确的解决方案并显示Widget。但是,当指示器运行时,它切换到Widget1((,然后三元运算符检查值并返回第二个值。我想做的是显示加载程序,直到三元运算符说,好吧,我检查过了,你需要显示Widget2((并显示它,但现在它首先显示Widget1((,然后三元运算符检查是否满足显示Widget2((的条件,然后切换到那个条件。我不想向用户显示过程中的一个屏幕,这很令人困惑。我尝试使用FutureBuilder(),但数据已经处于状态,所以我不想再次调用API,因此出现了问题。以下是带有注释的代码:

发生操作的主屏幕:

class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreen State();
}
class _MainScreenState extends State<MainScreen> {
@override
Widget build(BuildContext context) {
/// all the data from the provider state, so I don't call the api again
final vehicleStore = Provider.of<VehicleDataModel>(context, listen: true);
final vehicleData = vehicleStore.vehicleListLength != 0
? vehicleStore.getVehicleByIndex(0)
: null;
final user = Provider.of<LoggedUserStore>(context, listen: true);
final userData = user.getUserByGnetId(
Provider.of<LoggedUserStore>(context, listen: false)
.userEmail
.toString());
final tenant = Provider.of<LoggedTenantStore>(context, listen: true);
final tenantData = tenant.getTenantInfoByTenantId(
Provider.of<LoggedTenantStore>(context, listen: false)
.tenantId
.toString());
/// I first check if there is data for name and surname, show the progressindicator, then another ternary operator to see which widget to display, Widget1 or Widget2
return (userData?.name == null ||
userData?.surname == null ||
tenantData?.firstName == null ||
tenantData?.lastName == null)
?  Center(child: CircularProgressIndicator())
: (userData?.addressCity == null ||
tenantData?.addressCity == null ||
vehicleData?.licencePlate == null)
? Widget1()
: Widget2();
}
}

正如我所说,最好的解决方案是显示CircularProgressIndicator,直到第二个三元运算符完成他的任务,但我不确定什么是最好的方法。

提前感谢您的帮助!

我想最好的解决方案是在Provider类中添加一个加载参数。换句话说,在执行get*操作的函数中,应该在进程开始时将加载参数设置为true,在进程结束时将其设置为false。

这样你就可以听到课堂是否繁忙。

( user.providerLoadingObject ||
tenant.providerLoadingObject)
? 
Center(child: CircularProgressIndicator())  
: 
(userData?.addressCity == null ||
tenantData?.addressCity == null ||
vehicleData?.licencePlate == null)
? Widget1()
: Widget2();

您需要按每个条件显示每个小部件,并用Stack包装它。

class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreen State();
}
class _MainScreenState extends State<MainScreen> {
@override
Widget build(BuildContext context) {
/// all the data from the provider state, so I don't call the api again
final vehicleStore = Provider.of<VehicleDataModel>(context, listen: true);
final vehicleData = vehicleStore.vehicleListLength != 0
? vehicleStore.getVehicleByIndex(0)
: null;
final user = Provider.of<LoggedUserStore>(context, listen: true);
final userData = user.getUserByGnetId(
Provider.of<LoggedUserStore>(context, listen: false)
.userEmail
.toString());
final tenant = Provider.of<LoggedTenantStore>(context, listen: true);
final tenantData = tenant.getTenantInfoByTenantId(
Provider.of<LoggedTenantStore>(context, listen: false)
.tenantId
.toString());
/// I first check if there is data for name and surname, show the progressindicator, then another ternary operator to see which widget to display, Widget1 or Widget2
bool isLoading = userData?.name == null ||
userData?.surname == null ||
tenantData?.firstName == null ||
tenantData?.lastName == null;
Widget? currentWidget = isLoading ? null : (userData?.addressCity == null ||
tenantData?.addressCity == null ||
vehicleData?.licencePlate == null)
? Widget1()
: Widget2();

return Stack(children: [if(isLoading) Center(child: CircularProgressIndicator()), if(currentWidget != null) currentWidget]);
}
}

最新更新