如何在Flutter中构建刷新方法



我正试图为我的flutter应用程序制作一个刷新按钮(稍后还有一个下拉手势(。我希望如果我按下刷新按钮,调用a方法,从Web服务器中提取数据,并重建布局。

这是我迄今为止的代码:我的主要作品:

class MyHomePageState extends State<MyHomePage>  {
  final GetWebsites _getWebsites = GetWebsites();
  @override
  void initState() {
    refresh();
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: getSites(),
    );
  }
  //Get sites => Document, store them in a Document list
  Widget getSites() {
    return FutureBuilder<List<html.Document>>(
      //gets Dates of each date in other class and puts it in an List -> snapshot
      future: _getWebsites.getWebsite(),
      builder: (BuildContext context, AsyncSnapshot<List<html.Document>> snapshot) {
        //Cases for Connections
        switch(snapshot.connectionState) {
          case ConnectionState.active:
          case ConnectionState.waiting:
            return const Center(
              //TODO: Make better loading screen
              child: RefreshProgressIndicator(),
            );
          case ConnectionState.none:
            return const Center(
              child: Text("Keine Verbindung"),
            );
          case ConnectionState.done:
            if (snapshot.hasError) {
              return const Center(
                child: Text('Fehler'),
              );
            }
            //create tabs
            return buildrefresh(snapshot);
        }
      },
    );
  }
  Widget buildrefresh(AsyncSnapshot<List<html.Document>> snapshot) {
    return RefreshIndicator(
      onRefresh: () {
        return refresh();
      },
      child: rowortabbedLayout(snapshot),
    );
  }
  Widget rowortabbedLayout(AsyncSnapshot<List<html.Document>> snapshot) {
    if(Settings.getValue<bool>("keyrowortabbed", true)){
      return TabbedLayout().createTabbedLayout(snapshot, context);
    }else{
      return RowLayout().createRowLayout(snapshot, context);
    }
  }
  Future<void> refresh() async {
    setState((){
      FutureBuilder<List<html.Document>>(
        //gets Dates of each date in other class and puts it in an List -> snapshot
        future: _getWebsites.getWebsite(),
        builder: (BuildContext context, AsyncSnapshot<List<html.Document>> snapshot) {
          //Cases for Connections
          switch(snapshot.connectionState) {
            case ConnectionState.active:
            case ConnectionState.waiting:
              return const Center(
                child: RefreshProgressIndicator(),
              );
            case ConnectionState.none:
              return const Center(
                child: Text("Keine Verbindung"),
              );
            case ConnectionState.done:
              if (snapshot.hasError) {
                return const Center(
                  child: Text('Fehler'),
                );
              }
              //create tabs
              return buildrefresh(snapshot);
          }
        },
      );
    });
    print("Do something!");
  }
  Future<void> setstaterefresh() async {
    setState((){});
    print("Do something!");
  }

}

对于选项卡式布局(也有一个行布局,但我稍后会这样做(

class TabbedLayout{
  final SiteParser _getSiteData = SiteParser();
  Widget createTabbedLayout(AsyncSnapshot<List<html.Document>> snapshot, BuildContext context){
    return buildrevresh(snapshot,context);
  }
  Widget buildrevresh(AsyncSnapshot<List<html.Document>> snapshot, BuildContext context) {
    return RefreshIndicator(
      onRefresh: () {
        return MyHomePageState().setstaterefresh();
      },
      child: tabcontroller(snapshot,context),
    );
  }
  Widget tabcontroller(AsyncSnapshot<List<html.Document>> snapshot, BuildContext context) {
    return DefaultTabController(length: snapshot.data!.length,
      child: Scaffold(
        appBar: AppBar(
            actions: <Widget> [
              IconButton(
                onPressed: () {
                  Navigator.push(context, MaterialPageRoute(builder: (context) => const MySettings()),
                  );
                },
                icon: const Icon(Icons.settings),
              ),
 //Refresh Button:
              IconButton(
                icon: const Icon(Icons.refresh),
                onPressed: () {
                  MyHomePageState().refresh();
                },
              ),
            ],
            bottom: TabBar(
              isScrollable: true,
              tabs:
              //Tab names
              tabBarMaker(snapshot),
            ),
            title: const Text("Vertretungsplan")
        ),
        body:
        TabBarView(
          children:
          tabMaker(snapshot),
          physics: const BouncingScrollPhysics(),
        ),
      ),
    );
  }
  List<Widget> tabBarMaker(AsyncSnapshot<List<html.Document>> snapshot) {
    List<Tab> tabs = [];
    for(int x = 0; x<snapshot.data!.length; x++) {
      tabs.add(Tab(text: snapshot.data![x].querySelector('h1.list-table-caption')!.text
          .toString()));
    }
    return tabs;
  }
  //Create Tabs with contetnt for each site
  List<Widget> tabMaker(AsyncSnapshot<List<html.Document>> snapshot) {
    List<Widget> tabwidgets = [];
    for(int x = 0; x<snapshot.data!.length; x++) {
      tabwidgets.add(_buildDay(snapshot.data![x]));
    }
    return tabwidgets;
  }
  //Widget to create Tabs of each day and their contents
  //Get Contents of a day
  Widget _buildDay(html.Document site) {
    List<tage> days = _getSiteData.getData(site);
    return ListView.builder(
      padding: const EdgeInsets.all(10),
      itemCount: days.length,
      physics: const BouncingScrollPhysics(),
      itemBuilder: (context, index) {
        //Build cards for each content
        return MyThemes().buildCard(days[index]);
      },
    );
  }
}

当我尝试这个时,我得到了这个错误:

E/flutter (13792): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: setState() called in constructor: MyHomePageState#a8b0c(lifecycle state: created, no widget, not mounted)
E/flutter (13792): This happens when you call setState() on a State object for a widget that hasn't been inserted into the widget tree yet. It is not necessary to call setState() in the constructor, since the state is already assumed to be dirty when it is initially created.
E/flutter (13792): #0      State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1076:9)
E/flutter (13792): #1      State.setState (package:flutter/src/widgets/framework.dart:1087:6)
E/flutter (13792): #2      MyHomePageState.refresh (package:khsplan/main.dart:140:5)
E/flutter (13792): #3      TabbedLayout.tabcontroller.<anonymous closure> (package:khsplan/Vplan/tabbedlayout.dart:42:37)
E/flutter (13792): #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)
E/flutter (13792): #5      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:193:24)
E/flutter (13792): #6      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:608:11)
E/flutter (13792): #7      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:296:5)
E/flutter (13792): #8      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:230:7)
E/flutter (13792): #9      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:558:9)
E/flutter (13792): #10     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:94:12)
E/flutter (13792): #11     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:139:9)
E/flutter (13792): #12     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:400:8)
E/flutter (13792): #13     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:137:18)
E/flutter (13792): #14     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:123:7)
E/flutter (13792): #15     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:440:19)
E/flutter (13792): #16     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:420:22)
E/flutter (13792): #17     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:278:11)
E/flutter (13792): #18     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:374:7)
E/flutter (13792): #19     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:338:5)
E/flutter (13792): #20     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:296:7)
E/flutter (13792): #21     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:279:7)
E/flutter (13792): #22     _rootRunUnary (dart:async/zone.dart:1444:13)
E/flutter (13792): #23     _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (13792): #24     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1244:7)
E/flutter (13792): #25     _invoke1 (dart:ui/hooks.dart:185:10)
E/flutter (13792): #26     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:293:7)
E/flutter (13792): #27     _dispatchPointerDataPacket (dart:ui/hooks.dart:98:31)
E/flutter (13792): 

将initState((方法更改为以下方法:

@override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      refresh();
    });
  }

这样,一旦小部件完成第一次构建,就会执行refresh((函数。

只需制作一个刷新功能

void refresh(({setState({

});}

并在按下按钮时使用它。

相关内容

最新更新