每次单击进入底部导航栏上的页面时,如何防止调用http请求?

时间:2019-07-10 03:08:22

标签: flutter flutter-layout

在主页上,我有4个不同的api调用,它们从wordpress网站获取4个不同的数据。我当前编码的方式是,每次我们进入首页initState()时,都会在发生异步api提取的地方调用get _getHomePageData()函数。在发生这种情况时,allDataLoaded首先将布尔值设置为false。 将数据allDataLoaded设置为true后,将停止加载并显示窗口小部件。

这是主页小部件:

class HomePage extends StatefulWidget {
 @override
 _HomePageState createState() => _HomePageState();
}


class _HomePageState extends State<HomePage> {

  final String homePageLatestArtworkApi = 
  'https://example.com/wp-json/wp/v2/artworks? 
   per_page=1&_embed';
  final String homePageAllArtworkApi = 
  'https://example.com/wp-json/wp/v2/artworks? 
   per_page=6&_embed';
  final String homePageAllEventsApi = 
  'https://example.com/wp-json/wp/v2/events? 
   per_page=6&_embed';
  final String homePageAllVenuesApi = 
  'https:example.com/wp-json/wp/v2/venues? 
   per_page=6&_embed';

   List homePageLatestArtwork;
   List homePageAllArtworks;
   List homePageAllEvents;
   List homePageAllVenues;

   var allDataLoaded = false;



   @override
   void initState(){
     super.initState();

     print('init state is called everytime the page is loaded');
     _getHomePageData();
   }



  Future<String> _getHomePageData() async{

    var responseLatestArtwork = await http.get(Uri.encodeFull(homePageLatestArtworkApi));

    var responseAllArtworks = await http.get(Uri.encodeFull(homePageAllArtworkApi));

    var responseAllEvents = await http.get(Uri.encodeFull(homePageAllEventsApi));

    var responseAllVenues = await http.get(Uri.encodeFull(homePageAllVenuesApi));



  setState(() {

  //latest artwork
  var convertDataToJsonLatestArtwork = json.decode(responseLatestArtwork.body);
  homePageLatestArtwork = convertDataToJsonLatestArtwork;

  //All Artworks
  var convertDataToJsonAllArtworks = json.decode(responseAllArtworks.body);
  homePageAllArtworks = convertDataToJsonAllArtworks;

  // All Events
   var convertDataToJsonAllEvents = json.decode(responseAllEvents.body);
   homePageAllEvents = convertDataToJsonAllEvents;

  //All venues
   var convertDataToJson = json.decode(responseAllVenues.body);
    homePageAllVenues = convertDataToJson;


  if(homePageLatestArtwork != null && homePageAllArtworks != null && homePageAllEvents != null && homePageAllVenues != null){
    allDataLoaded = true;
  }
  // print('converted data is here');
  //print(homePageLatestArtwork);

  //print('the title is here :');


  //print(homePageLatestArtwork[0]['title']['rendered']);
  //print(homePageLatestArtwork[0]['_embedded']['wp:featuredmedia'][0]['source_url']);

  });



@override
Widget build(BuildContext context) {


if(allDataLoaded){ //wait for the data to load and show spinning loader untill data is completely loaded

  return Scaffold(
    // body: Text('title'),
    // body: Text("title: ${homePageLatestArtwork[0]['title']['rendered']} "),
    body: Container(
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[ 
            // Expanded(
              Container(
              height: 200.0,
              child: Image.network(homePageLatestArtwork[0]['_embedded']['wp:featuredmedia'][0]['source_url'],
              fit: BoxFit.fill,
              width: double.maxFinite,),
              ),
              Container(
                padding: EdgeInsets.only(left:15.0,right:15.0,top:10.0),
                child: Text(homePageLatestArtwork[0]['title']['rendered'],textAlign: TextAlign.left,

                style: new TextStyle(
                      fontSize: 20.0,
                      fontFamily: 'Montserrat-Regular',
                      color: Color(0XFF212C3A),
                      fontWeight: FontWeight.bold
                      ),),
              ),
             ])
            ),
           ),
         );

    }else{

      return new Center(
        child: new CircularProgressIndicator(
      valueColor: new AlwaysStoppedAnimation<Color> . 
     (Theme.of(context).primaryColor),
    ),
  );
}

} //end of _HOMEPAGESTATE

我不希望每次查看主页都加载一次,或者说我只想在应用启动时获取一次api数据,然后让用户手动下拉以刷新数据。

1 个答案:

答案 0 :(得分:1)

方法1:

如果您只是在谈论数据,那么应该有一个单例对象,您可以在initState()中初始化一次;

class _HomePageData {
  var allDataLoaded = false;
  String contents = "";
  Future<String> _getHomePageData() async {
    // Assuming contents is the data model and you load the data into contents
    this.contents = "Loaded";
    this.allDataLoaded = true;
    return this.contents;
  }
}

final _HomePageData data = _HomePageData();

class _HomePageState extends State<HomePage> {
  String contents;

  @override
  void initState(){
    super.initState();

    if (!data.allDataLoaded) {
      data._getHomePageData().then((contents) {
        setState(() {
          this.contents = contents;
        })
      });
    } else {
      this.contents = data.contents;
    }
  }
}

方法2:

以前,我所处理的标签是每次移动到另一个标签时都会不断重新加载的标签。当Flutter未附加到任何活动小部件树时,它们会主动删除状态。想法是将小部件放在堆栈中,并置于Offstage和TickerMode中,以控制可见性和动画。

class MyTabState extends State<MyTabPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: MyBottomBar(
        onTab: _onTab,
        currentIndex: _currentIndex,
      ),
      body: Stack(
        children: List.generate(3, (index) {
          return Offstage(
            offstage: _currentIndex != index,
            child: TickerMode(
              enabled: _currentIndex == index,
              child: getChild(index),
            ),
          );
        }, growable: false),
      ),
    );
  }
}