我想在SmartRefresher上实现futurebuilder,但是在刷新时无法获取最新数据。我不使用listView,但只想将数据放在现有字段中。

主程序:

class _StatisticPageState extends State<StatisticPage> {

  Future<Banjir> futureBanjir;

  RefreshController _refreshController =
    RefreshController(initialRefresh: false);

  @override
  void initState(){
    super.initState();
    futureBanjir = fetchBanjir();
  }

  ProgressDialog pr;

  @override
  Widget build(BuildContext context) {
    return SmartRefresher(
      controller: _refreshController,
      enablePullDown: true,
      enablePullUp: false,
      onRefresh: () async{
        // this is my problem
        _refreshController.loadComplete();
      },
      child: SingleChildScrollView(
        physics: const AlwaysScrollableScrollPhysics(),
        child: FutureBuilder<Banjir>(
          future: futureBanjir,
          builder: (context, snapshot){
            if(snapshot.hasData == null){
              return _buildAll(
                AppColors.offColor,
                "N/A",
                "N/A",
                "N/A",
                "N/A",
                "N/A",
                "N/A",
                "N/A",
                "N/A",
                "N/A",
              );
            } else if(snapshot.hasError){
              return Center(
                child: Text("Error : ${snapshot.error}"),
              );
            } else{
              if(snapshot.data.siteStatus != "Active"){
                return _buildAll(
                  AppColors.offColor,
                  (snapshot.data.data.tanggal).toString(),
                  (snapshot.data.data.jam).toString(),
                  snapshot.data.data.ketinggian,
                  "SITE MATI",
                  snapshot.data.today.min,
                  snapshot.data.today.max,
                  (snapshot.data.today.banjir).toString(),
                  (snapshot.data.today.awas).toString(),
                  (snapshot.data.today.waspada).toString()
                );
              }
            }
            return SpinKitDoubleBounce(
              color: AppColors.mainColor,
            );
          },
        ),
      ),
    );
  }

这是我的 future 功能
Future<Banjir> fetchBanjir() async{
  final response = await http.get(RestAPI.BASE_URL + "/last");

  if(response.statusCode == 200){
    return Banjir.fromJson(json.decode(response.body));
  } else{
    throw Exception('Failed to Load Data');
  }
}

我不知道如何在FutureBuilder上实现SmartRefresher,我被困在这一点上

最佳答案

您可以在下面复制粘贴运行完整代码
您可以再次使用set futureBanjir并调用setState

onRefresh: () async {
      futureBanjir = fetchBanjir();
      setState(() {});
      _refreshController.refreshCompleted();
    },

工作演示

android - 如何在SmartRefresher上实现FutureBuilder-Flutter Dart-LMLPHP

完整的代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:http/http.dart' as http;
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'dart:convert';

class RefreshScrollBehavior extends ScrollBehavior {
  @override
  Widget buildViewportChrome(
      BuildContext context, Widget child, AxisDirection axisDirection) {
    // When modifying this function, consider modifying the implementation in
    // _MaterialScrollBehavior as well.
    switch (getPlatform(context)) {
      case TargetPlatform.iOS:
        return child;
      case TargetPlatform.macOS:
      case TargetPlatform.android:
        return GlowingOverscrollIndicator(
          child: child,
          // this will disable top Bouncing OverScroll Indicator showing in Android
          showLeading: true, //顶部水波纹是否展示
          showTrailing: true, //底部水波纹是否展示
          axisDirection: axisDirection,
          notificationPredicate: (notification) {
            if (notification.depth == 0) {
              // 越界了拖动触发overScroll的话就没必要展示水波纹
              if (notification.metrics.outOfRange) {
                return false;
              }
              return true;
            }
            return false;
          },
          color: Theme.of(context).primaryColor,
        );
      case TargetPlatform.fuchsia:
    }
    return null;
  }
}

Banjir banjirFromJson(String str) => Banjir.fromJson(json.decode(str));

String banjirToJson(Banjir data) => json.encode(data.toJson());

class Banjir {
  Banjir({
    this.data,
  });

  List<Datum> data;

  factory Banjir.fromJson(Map<String, dynamic> json) => Banjir(
        data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "data": List<dynamic>.from(data.map((x) => x.toJson())),
      };
}

class Datum {
  Datum({
    this.tanggal,
    this.jam,
    this.ketinggian,
  });

  int tanggal;
  int jam;
  String ketinggian;

  factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        tanggal: json["tanggal"],
        jam: json["jam"],
        ketinggian: json["ketinggian"],
      );

  Map<String, dynamic> toJson() => {
        "tanggal": tanggal,
        "jam": jam,
        "ketinggian": ketinggian,
      };
}

class StatisticPage extends StatefulWidget {
  @override
  _StatisticPageState createState() => _StatisticPageState();
}

class _StatisticPageState extends State<StatisticPage> {
  Future<Banjir> futureBanjir;

  RefreshController _refreshController =
      RefreshController(initialRefresh: false);
  List<Datum> dataList = [];

  @override
  void initState() {
    super.initState();
    futureBanjir = fetchBanjir();
  }

  Future<Banjir> fetchBanjir() async {
    //final response = await http.get(RestAPI.BASE_URL + "/last");
    print("fetchBanjir");
    dataList.add(Datum(tanggal: 1, jam: 2, ketinggian: "test"));
    print(dataList.length);
    return Future.value(Banjir(data: dataList));
  }

  //ProgressDialog pr;

  @override
  Widget build(BuildContext context) {
    return SmartRefresher(
        header: WaterDropHeader(),
        controller: _refreshController,
        enablePullDown: true,
        enablePullUp: true,
        onRefresh: () async {
          futureBanjir = fetchBanjir();
          setState(() {});
          _refreshController.refreshCompleted();
        },
        child: Column(
          children: [
            Text("test"),
            Expanded(
              child: FutureBuilder<Banjir>(
                  future: futureBanjir,
                  builder: (context, snapshot) {
                    switch (snapshot.connectionState) {
                      case ConnectionState.none:
                        return Text('none');
                      case ConnectionState.waiting:
                        return Center(child: CircularProgressIndicator());
                      case ConnectionState.active:
                        return Text('');
                      case ConnectionState.done:
                        if (snapshot.hasError) {
                          return Text(
                            '${snapshot.error}',
                            style: TextStyle(color: Colors.red),
                          );
                        } else {
                          return ListView.builder(
                              itemCount: snapshot.data.data.length,
                              itemBuilder: (context, index) {
                                return Card(
                                    elevation: 6.0,
                                    child: Padding(
                                      padding: const EdgeInsets.only(
                                          top: 6.0,
                                          bottom: 6.0,
                                          left: 8.0,
                                          right: 8.0),
                                      child: Row(
                                        crossAxisAlignment:
                                            CrossAxisAlignment.start,
                                        children: <Widget>[
                                          Text(snapshot.data.data[index].jam
                                              .toString()),
                                          Spacer(),
                                          Text(snapshot
                                              .data.data[index].ketinggian),
                                        ],
                                      ),
                                    ));
                              });
                        }
                    }
                  }),
            ),
          ],
        ));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RefreshConfiguration(
      footerTriggerDistance: 1.0,
      dragSpeedRatio: 0.91,
      headerBuilder: () => MaterialClassicHeader(),
      footerBuilder: () => ClassicFooter(),
      enableLoadingWhenNoData: false,
      shouldFooterFollowWhenNotFull: (state) {
        // If you want load more with noMoreData state ,may be you should return false
        return false;
      },
      autoLoad: true,
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        builder: (context, child) {
          return ScrollConfiguration(
            child: child,
            behavior: RefreshScrollBehavior(),
          );
        },
        home: MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: StatisticPage(),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

09-28 09:33