Search code examples
flutterpull-to-refresh

Flutter RefreshIndicator 'No data' Widget


I have a RefreshIndicator that loads a ListView when Feature completes, however, I wanted to make it so that if the feature returns a data set that's empty - show another widget - 'No data' instead of the ListView.

I was able to accomplish that using ternary operator, however, the 'No data' widget is displayed during the refresh, until replaced by ListView.

How to show the 'No data' widget ONLY AFTER the refresh has finished?

Here's my code:

return RefreshIndicator(
    key: _refreshIndicatorKey,
    onRefresh: AppConfig.of(context).flavorName != FLAVOR_NAME.DEV
        ? () {
            bloc.page = 1;
            return bloc.getTasks(status, context).then((list) {
              setState(() {
                tasksList = list;
              });
            });
          }
        : () => Future.delayed(Duration(seconds: 2)),
    child: tasksList.length > 0
        ? ListView.builder(
            physics: const AlwaysScrollableScrollPhysics(),
            controller: _scrollController,
            itemCount: tasksList.length + 1,
            itemBuilder: (context, index) {
              if (index == tasksList.length) {
                return _buildProgressIndicator();
              } else {
                Task item = tasksList != null ? tasksList[index] : null;
                return GestureDetector(
                    onTap: () {
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) {
                                return TaskDetailsScreen(index, item);
                              },
                              settings: RouteSettings(
                                  name: ScreenName.taskDetails)));
                    },
                    child: MyTasksListItem(taskData: item));
              }
            },
          )
        : Stack(children: [
            Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Image.asset(
                    'assets/tumbleweed.gif',
                  ),
                ]),
            Positioned(
                bottom: 50,
                left: 0.0,
                right: 0.0,
                child: Align(child: Text(allTranslations.text('no_tasks'))))
          ]));

The 'No data' Widget is Stack in my case.


Solution

  • Maybe a solution like this would work:

     onRefresh: AppConfig.of(context).flavorName != FLAVOR_NAME.DEV
        ? () {
            setState(() {
                loading = true;
            });
    
            bloc.page = 1;
            return bloc.getTasks(status, context).then((list) {
              setState(() {
                loading = false;
                tasksList = list;
              });
            });
          }
    

    and in your indicator child:

    child: Container(
        child: loading ?
           null :
           tasksList.length > 0
              ? ListView.builder(..........