【问题标题】:Show loading indicator /spinner when the page data isn't fully loaded from Firebase - Flutter当页面数据未从 Firebase 完全加载时显示加载指示器/微调器 - Flutter
【发布时间】:2021-01-16 03:17:20
【问题描述】:

在我的 Flutter 应用中,当我点击表单屏幕中的保存按钮时,我使用 ModalProgressHUD 显示一个微调器,一旦数据成功写入 Firebase,它就会停止微调器。

我有这个屏幕,它使用 Listview.builder 显示我所有费用的列表,我想在页面显示后立即自动显示微调器,并在 Firebase 中的所有数据完全加载后停止微调器。

我在执行此操作时需要帮助。我已经粘贴了我的代码摘录,如下所示。提前致谢。

//class wide declaration
bool showSpinner = true;



Widget build(BuildContext context) {

ExpenseNotifier expenseNotifier = Provider.of<ExpenseNotifier>(context);


Future<void> _resfreshList() async {
  expenseNotifier.getExpenses(expenseNotifier);
  var expenseList = ExpenseNotifier.getExpenses(expenseNotifier);
  if (expenseList != null) {
    setState(() {
      showSpinner = false;
    });
}

    return Scaffold(
      body: ModalProgressHUD(
            inAsyncCall: showSpinner,
            child: RefreshIndicator(
              onRefresh: _resfreshList,
              child: Consumer<ExpenseNotifier>(
                builder: (context, expense, child) {
                  return expense == null
                      ? Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: <Widget>[
                            PaddingClass(bodyImage: 'images/empty.png'),
                            SizedBox(
                              height: 20.0,
                            ),
                            Text(
                              'You don\'t have any expenses',
                              style: kLabelTextStyle,
                            ),
                          ],
                        )
                      : ListView.separated(
                          itemBuilder: (context, int index) {
                            var myExpense = expense.expenseList[index];
                            return Card(
                              elevation: 8.0,
                              color: Colors.white70,
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.start,
                                children: <Widget>[
                                  RegularExpenseTextPadding(
                                    regText:
                                        '${_formattedDate(myExpense.updatedAt)}',
                                  ),
                                  Container(
                                    margin: EdgeInsets.all(20.0),
                                    padding: const EdgeInsets.all(15.0),
                                    decoration: BoxDecoration(
                                      borderRadius:
                                          BorderRadius.all(Radius.circular(5.0)),
                                      border: Border.all(
                                          color: kThemeStyleBorderHighlightColour),
                                    ),
                                    child: Row(
                                      children: <Widget>[
                                        Expanded(
                                          flex: 5,
                                          child: Column(
                                            crossAxisAlignment:
                                                CrossAxisAlignment.start,
                                            children: <Widget>[
                                              Text(
                                                '${myExpense.amount}',
                                                style: kRegularTextStyle,
                                              ),
                                              SizedBox(
                                                height: 20.0,
                                              ),
                                              Text(
                                                myExpense.description,
                                                style: kRegularTextStyle,
                                              ),
                                            ],
                                          ),
                                        ),
                                        Expanded(
                                          flex: 1,
                                          child: GestureDetector(
                                            onTap: () {
                                              expenseNotifier.currentExpense =
                                                  expenseNotifier
                                                      .expenseList[index];
                                              Navigator.of(context).push(
                                                  MaterialPageRoute(builder:
                                                      (BuildContext context) {
                                                return ExpenseDetailsScreen();
                                              }));
                                            },
                                            child: Icon(
                                              FontAwesomeIcons.caretDown,
                                              color: kThemeIconColour,
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            );
                          },
                          separatorBuilder: (BuildContext context, int index) {
                            return SizedBox(
                              height: 20.0,
                            );
                          },
                          itemCount: expenseNotifier.expenseList.length,
                        );
                },
              ),
            ),
          ),
    );
    }
  

【问题讨论】:

    标签: firebase flutter flutter-layout flutter-dependencies


    【解决方案1】:

    这是我的应用程序中的一个示例:

    bool _isLoading = false; <- default false
      bool _isInit = true; <- to mae it only load once
    
    
    @override
      void initState() {
    
    if (_isInit) {
         // activating spinner
          _isLoading = true;
    
          // your function here <------
    
        _isInit = false;
        super.initState();
      }
    

    Initstate 在用户可以看到您的应用中的任何类型之前被调用,因此这是加载您的 Firebase 数据的理想场所。只要您收到数据,加载微调器就会显示上面的这个逻辑。然后你的身体看起来像下面这样:

    @override
      Widget build(BuildContext context) {
    
        return _isLoading <- is loading condition true? shows spinner
            ? Center(child: CircularProgressIndicator()) <- loading spinner
        // else shows your content of the app
        : SafeArea(
            child: Container()
                ....
    

    【讨论】:

    • 嘿马塞尔,我试着模仿你上面建议的样本。我将 isLoading 的默认值设置为 true,因为我希望微调器立即显示页面加载,并在从 db 成功读取数据时将其设置为 false。但是即使页面完全加载,微调器也不会停止。我已经编辑了我的问题以包括我所做的更新。要查找更改,请检查 showSpinner 声明、inAsyncCall、_resfreshList 函数。
    • @hermie_brown 请检查我的代码 我更改了它,当您回复我的代码时,我刚刚注意到我从文件中提取了错误的部分。现在它是正确的,把它作为你的构造,它现在应该可以工作了。您将使用 initstate 加载它,并在加载完成后显示应用程序内容。像在我的示例中那样保持 isLoading 为 false,这样您就不会遇到麻烦
    猜你喜欢
    • 1970-01-01
    • 2013-04-10
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 2014-12-12
    • 1970-01-01
    相关资源
    最近更新 更多