在Flutter中从FutureBuilder设置状态

时间:2020-07-29 07:05:16

标签: flutter

我一直在尝试根据FutureBuilder的响应来设置属性,但似乎无法使其正常工作。将来解决之后,如何在构建期间不进行设置的情况下设置_activityLength

FutureBuilder<QuerySnapshot>(
            future: _future,
            builder: (BuildContext context,
                AsyncSnapshot<QuerySnapshot> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                  return Text('Press button to start');
                case ConnectionState.waiting:
                  return Center(
                    child: CircularProgressIndicator(),
                  );
                default:
                  if (snapshot.hasError) {
                    return Text('Error: ${snapshot.error}');
                  } else {
                    final documents = snapshot.data.documents;

                    _activityLength = documents.length;

                    return Expanded(
                      child: ListView.separated(
                        shrinkWrap: true,
                        separatorBuilder: (context, index) => Divider(
                          color: Colors.black,
                          height: 0,
                        ),
                        itemCount: documents.length,
                        itemBuilder: (context, index) => _activityTile(
                          documents[index],
                        ),
                      ),
                    );
                  }
              }
            },
          )

FutureBuildeColumn主体的Scaffold小部件中,而我需要设置的值在_itemsHeaderText中,如下所示:

body:
   ...

                  child: Column(
                    children: <Widget>[
                      Container(
                        width: double.infinity,
                        decoration: BoxDecoration(
                          border: Border(
                            bottom:
                                BorderSide(color: Colors.grey, width: 1.0),
                          ),
                        ),
                        child: Padding(
                          padding: const EdgeInsets.only(
                              left: 15.0,
                              right: 15.0,
                              top: 10.0,
                              bottom: 10.0),
                          child: _itemsHeaderText(),
                        ),
                      ),
                      _itemsBody(),
                    ],
                  ),

2 个答案:

答案 0 :(得分:0)

您的问题有一些解决方法。

  1. 您可以将futureBuilder提升到小部件树上,而不是设置状态,一旦ConnectionState.done就会重置状态。
  2. 您可以将future放置在一个被称为init状态的函数中,然后将future的结果置于状态上。

答案 1 :(得分:0)

您可以在下面复制粘贴运行完整的演示代码
您可以在_future.then((value)中使用initState()并在addPostFrameCallback中像setState一样做工作
在以后解决之后,您可以获得value中的_future,并且在需要时可以进行进一步处理
在演示代码中,我得到value length并显示在屏幕上
您可以看到正在运行的演示,数据长度从0更改为9

代码段

  @override
  void initState() {
    super.initState();
    _future = _getUsers();
    _future.then((value) {
      print("data length ${value.length}");
      WidgetsBinding.instance.addPostFrameCallback((_) {
        print("other job");
        setState(() {
          _dataLength = value.length;
        });
      });
    });
  }

工作演示

enter image description here

输出

I/flutter (18414): data length 9
I/flutter (18414): other job

完整代码

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: CategoryTab(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

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

class _CategoryTabState extends State<CategoryTab> {
  Future<List<CategoryList>> _future;
  int _dataLength = 0;

  Future<List<CategoryList>> _getUsers() async {
    var data = await http
        .get("https://appiconmakers.com/demoMusicPlayer/API/getallcategories");

    var jsonData = json.decode(data.body);
    List<CategoryList> cat = [];
    for (var u in jsonData) {
      CategoryList categoryList = CategoryList(
          u["category_id"],
          u["category_name"],
          u["parent_category_id"],
          u["category_status"],
          u["created_date"]);
      cat.add(categoryList);
    }

    return cat;
  }

  @override
  void initState() {
    super.initState();
    _future = _getUsers();
    _future.then((value) {
      print("data length ${value.length}");
      WidgetsBinding.instance.addPostFrameCallback((_) {
        print("other job");
        setState(() {
          _dataLength = value.length;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Categories",
          style: TextStyle(color: Colors.black),
        ),
        backgroundColor: Colors.white,
      ),
      body: Column(
        children: [
          Text("data length $_dataLength"),
          Expanded(
            child: Container(
              child: FutureBuilder(
                future: _future,
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                  if (snapshot.data == null) {
                    return Container(child: Center(child: Text("Loading...")));
                  } else {
                    return ListView.builder(
                      itemCount: snapshot.data.length,
                      itemBuilder: (BuildContext context, int index) {
                        return ListTile(
                          leading: CircleAvatar(),
                          title: Text(
                            "${snapshot.data[index].categoryName}",
                            // subtitle: Text(snapshot.data[index].categoryId
                          ),
                        );
                      },
                    );
                  }
                },
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class CategoryList {
  String categoryId;
  String categoryName;
  String parentCategoryId;
  String categoryStatus;
  String createdDate;

  CategoryList(this.categoryId, this.categoryName, this.parentCategoryId,
      this.categoryStatus, this.createdDate);
}