Flutter pull to refresh is showing a blank page before loading data

43 Views Asked by At

I have pull to refresh implemented. It was working fine when I used static data generated with a delay. When I updated to use API, it is loading new data but when I pull down it shows the arrow icon, then it disappears, it shows a list loading circle at the center, the list disappears, shows a blank loading page, then it shows the newly fetched list. How to make the list stay on the screen and update the data without page showing blank? Or is this the correct behaviour? The code I am using is:

Future<NotificationsList?>? notificationsListFuture;

Future<void> _refreshItems() async {
  offset = 0;
  notificationsListFuture = updateNotificationsList();
  setState(() {});
}

Future<NotificationsList?> updateNotificationsList() async {
  String udid = await FlutterUdid.udid;
  NotificationsList notifsList = await getNotifications(offset, max, udid);
  print("flutter - notifsList: " + notifsList.toString());
  updateBadgeCount(notifsList.unread);
  return notifsList;
}

The widget tree is:

Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    appBar: widget.showAppbar ? TopAppBar() : null,
    drawer: widget.showAppbar ? TopDrawer() : null,
    body: RefreshIndicator(
      onRefresh: _refreshItems,
      child: FutureBuilder<NotificationsList?>(
        future: notificationsListFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return _buildLoadingIndicator();
          } else if (snapshot.hasError) {
            return Text('Error: ${snapshot.error}');
          } else {
            final List<NotificationBody> notifs = snapshot.data?.notifications ?? [];
            return Container(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Padding(
                    padding: const EdgeInsets.only(top: 16, left: 16, bottom: 8),
                    child: Text(
                      'Notifications',
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: ScreenSizeService.h1FontSize),
                    ),
                  ),
                  Expanded(
                    child: notifs.isEmpty
                      ? Padding(
                          padding: const EdgeInsets.only(top: 8, left: 16, bottom: 0),
                          child: Text('No notifications'),
                        )
                      : ListView.separated(
                          controller: _scrollController,
                          itemCount: notifs.length + 1, // Add 1 for loading indicator
                          separatorBuilder: (_, __) => Divider(height: 1),
                          key: PageStorageKey('notificationListKey'),
                          itemBuilder: (context, index) {
                            if (index < notifs.length) {
                              return Padding(
                                padding: EdgeInsets.fromLTRB(0, 8, 0, 8),
                                child: ListTile(
                                  title: Padding(
                                    padding: EdgeInsets.only(bottom: 8.0),
                                    child: Text(
                                      notifs[index].title,
                                      style: TextStyle(
                                        fontWeight: notifs[index].status == "unread" ? FontWeight.bold : FontWeight.normal,
                                        color: Colors.black,
                                      ),
                                    ),
                                  ),
                                  subtitle: Padding(
                                    padding: EdgeInsets.fromLTRB(0, 0, 0, 8),
                                    child: Column(
                                      crossAxisAlignment: CrossAxisAlignment.start,
                                      children: [
                                        Padding(
                                          padding: EdgeInsets.only(bottom: 8.0),
                                          child: Text(
                                            notifs[index].msg,
                                            style: TextStyle(
                                              fontWeight: FontWeight.normal,
                                              color: Colors.black,
                                            ),
                                          ),
                                        ),
                                        Text(
                                          DateFormat("yyyy-MM-dd hh:mm a").format(DateTime.parse(notifs[index].date)),
                                          style: TextStyle(
                                            color: Colors.grey,
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                  trailing: Icon(Icons.arrow_forward, color: Colors.red),
                                  onTap: () {
                                    print("notification list item tapped");
                                  },
                                ),
                              );
                            } else if (_isLoading) {
                              return _buildLoadingIndicator();
                            } else {
                              return Container();
                            }
                          },
                        ),
                  )
                ]
              )
            );
          }
        }
      ),
    ),
  );
}

Thanks.

0

There are 0 best solutions below