How to add refresh indicator outside stream builder flutter

Viewed 1183

I am trying to add pull to refresh in my streambuilder widget.. here is part of my code that I have tried so far

@override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      key: _refreshIndicatorKey,
      onRefresh: _handleRefresh,
      child: StreamBuilder<DataModel>(
          stream: dataBloc.subject.stream,
          builder: (context, AsyncSnapshot<DataModel> snapshot) {
            if (snapshot.hasData) {
              return passData(snapshot.data);
            } else if (snapshot.hasError) {
              return .....
            } else {
              return ......
            }
          }),
    );
  }

Future<void> _handleRefresh() async {
    try {
      bool trustSelfSigned = true;
      HttpClient httpClient = new HttpClient()
        ..badCertificateCallback =
            ((X509Certificate cert, String host, int port) => trustSelfSigned);
      IOClient http = new IOClient(httpClient);
      final response = await http.post('...',
          headers: {
            HttpHeaders.contentTypeHeader: 'application/json',
          },
          body: json.encode({...}));
      Map<String, dynamic> responseJson = json.decode(response.body);
      return;
    } catch (ex) {
      print(ex.message);
    }
  }

but whenever I try to swipe down...I can not see the reload icon of refresh indicator.. is there something that I should add more? I also have added this code

final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
      GlobalKey<RefreshIndicatorState>();
3 Answers

You need to put the refresh indicator inside the stream builder:

    @override
    Widget build(BuildContext context) {
        return StreamBuilder<DataModel>(
        stream: dataBloc.subject.stream,
            builder: (context, AsyncSnapshot<DataModel> snapshot) {
                if (snapshot.hasData) {
                    return Expanded(
                        child: RefreshIndicator(
                            child: methodToHandleTheData(snapshot.data)
                        )
                    );
                } else if (snapshot.hasError) {
                    return .....
                } else {
                    return ......
                }
            }
        );
    }

    Widget methodToHandleTheData(DataModel data) {
        return SingleChildScrollView(
            physics: const AlwaysScrollableScrollPhysics(),
            child: MyAwesomeWidget(data)
        );
    }

It's necessary that the first child of the RefreshIndicator is a scrollable widget, i.e. a SingleChildScrollView or a ListView, and also you need to add the parameter physics: const AlwaysScrollableScrollPhysics()in order to make it work.

Yes, you will need a scrollable child. Put a SingleChildScrollView after the RefreshIndicator and it should work

I had this issue in the past when I assigned a misconfigured ScrollController in the ListView that returns to the builder. Once I removed the ScrollController, the circular refresh indicator showed, and onRefresh was called.

I did not have to use a SingleChildScrollView

Related