未来建设者不断更新

Future builder Constantly Updates

我正在使用 Future 构建器从快照中获取数据并将该数据过滤到另一个创建标记的 Future 函数中。我通过过滤所有餐厅的位置得到结果,但是该功能不断更新并且数据只是闪烁。

编辑 2:JSON 数据

    { restaurant:[  {
            "id": 4,
            "restaurant_name": "Good Chemistry",
            "phone": "1231231234",
            "street_address": "2 Penn Plaza",
            "restaurant_logo": "https://restaurants.s3.amazonaws.com/restaurant_logo/GOODCHEM-3-web_99314.jpg",
            "restaurant_photo": "https://restaurants.s3.amazonaws.com/restaurant_photo/GOODCHEM-3-web_99314.jpg",
            "city": "NY",
            "state": "New York",
            "zip_Code": 10010,
            "lat": 40.8931283,
            "lng": -73.8205375,
            "latlng": "(40.7770112244898, -74.2110798163265)",
            "opening_hours": [
                {
                    "day_of_week": "Tuesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Wednesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Thursday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Friday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Saturday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Sunday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": 7,
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                }
            ],
            "ratings": 4.1
        },
        {
            "id": 3,
            "restaurant_name": "The Farmacy",
            "phone": "1231231234",
            "street_address": "11 Penn Plaza",
            "restaurant_logo": "https://restaurants.s3.amazonaws.com/restaurant_logo/farma.jpg",
            "restaurant_photo": "https://restaurants.s3.amazonaws.com/restaurant_photo/farma.jpg",
            "city": "NY",
            "state": "New York",
            "zip_Code": 10010,
            "lat": 40.8931283,
            "lng": -73.8205375,
            "latlng": "(40.7770112244898, -74.2110798163265)",
            "opening_hours": [
                {
                    "day_of_week": "Tuesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Wednesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Thursday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Friday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Saturday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Sunday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": 7,
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                }
            ],
            "ratings": 4.7
        },
        {
            "id": 2,
            "restaurant_name": "Hoboken Smokin",
            "phone": "123-123-1234",
            "street_address": "11 Penn Plaza",
            "restaurant_logo": "https://restaurants.s3.amazonaws.com/restaurant_logo/urban-restaurant-web-1024x640.jpg",
            "restaurant_photo": "https://restaurants.s3.amazonaws.com/restaurant_photo/urban-restaurant-web-1024x640.jpg",
            "city": "NY",
            "state": "New York",
            "zip_Code": 10010,
            "lat": 40.8931283,
            "lng": -73.8205375,
            "latlng": "(40.7770112244898, -74.2110798163265)",
            "opening_hours": [
                {
                    "day_of_week": "Tuesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Wednesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Thursday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Friday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Saturday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Sunday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": 7,
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                }
            ],
            "ratings": 3.5
        },
        {
            "id": 1,
            "restaurant_name": "The Bakeree",
            "phone": "1231231234",
            "street_address": "433 5th Ave",
            "restaurant_logo": "https://restaurants.s3.amazonaws.com/restaurant_logo/restaurantimage.jpeg",
            "restaurant_photo": "https://restaurants.s3.amazonaws.com/restaurant_photo/restaurantimage.jpeg",
            "city": "NY",
            "state": "New York",
            "zip_Code": 10016,
            "lat": 40.7512061,
            "lng": -73.9822721,
            "latlng": "(40.7770112244898, -74.2110798163265)",
            "opening_hours": [
                {
                    "day_of_week": "Tuesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Wednesday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Thursday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Friday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Saturday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": "Sunday",
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                },
                {
                    "day_of_week": 7,
                    "opening_time": "08:00:00",
                    "closing_time": "22:00:00"
                }
            ],
            "ratings": 4.6
        }
    ]
}

编辑 1:_setRestaurant 函数

Future getRestaurants() async {
  var url = 'http://yellows-1929.herokuapp.com/api/customer/restaurant/';

  var response = await http.get(url);
  var responseData = json.decode(response.body);

  Restaurants _restaurant = Restaurants.fromJSON(responseData);

  return _restaurant.restaurant;
}




Filter Location function

<!-- begin snippet: js hide: false console: true babel: false -->

获取数据并调用函数 filterMarker 的未来构建器:

Widget _buildRestaurants() {
    return Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              FutureBuilder(
                  future: _setRestaurants,
                  builder: (context, AsyncSnapshot snapshot) {
                    var restaurants = snapshot.data;
                    recRestaurants = snapshot.data;

                    if (snapshot.data == null) {
                      return Center(child: CircularProgressIndicator());
                    } else {
                          filterMarker(restaurants, 20);

                      return Column(
                        children: <Widget>[
                          _makeRestaurants(restaurants),
                          _buildCoupon(),
                          _buildVendors(filteredVenues)
                        ],
                      );
                    }
                  })
            ]));
  }

过滤器不断更新和打印

flutter: the lat is 41.722068434324785 and the long is -74.34910777767849
flutter: There are 1 _filteredMarkers
flutter: There are 0 _filteredMarkers
flutter: There are 0 _filteredMarkers
flutter: There are 1 _filteredMarkers
flutter: There are 1 _filteredMarkers
flutter: There are 1 _filteredMarkers
flutter: There are 0 _filteredMarkers
flutter: There are 0 _filteredMarkers
flutter: There are 1 _filteredMarkers

如果没有完整的代码片段,很难判断发生了什么 - 如果您创建了一个小的工作示例来显示发生了什么,那会更有帮助。

不过,我相信有几件事可能会有所帮助。

  1. 尽可能停止构建具有函数的小部件。如果它复杂到需要一个函数来构建它,您很可能应该在它自己的小部件中构建它。这允许 flutter 优化不同小部件的构建以及清理代码。

  2. 不清楚 _setRestaurants 是什么,但您在 FutureBuilder 中引用了它。立即执行此操作是 _setRestaurants 成为 Future,并且仅在 完成新服务器请求时 更改它。将 _setRestaurants 对象视为小部件状态的一部分,并假设当它更改时小部件将被重建。所以这看起来像:

Future<Restaurants> _setRestaurants;

void initState() {
  super.initState();

  _setRestaurants = _getRestaurants();
}

void updateRestaurants() {
  setState(() {
    _setRestaurants = _getRestaurants();
  });
}

请注意,我实际上并不完全推荐这样做,这只是为了演示 OP 可能做错了什么

  1. 您可能不应该在客户端过滤数据。想想规模——如果你有 50 家餐厅,我想这是可持续的,但如果你有 1000 家,你就不能每次都要求。您应该改为向获取请求添加参数并在服务器上进行过滤。

  2. 从 "displaying the restaurants on the screen" 部分中分离出 "retrieving information from server and filtering" 部分是有意义的。这样你就可以分离关注点,你可以独立测试服务器部分和 UI 部分,它会更健壮。有很多不同的方法可以解决这个问题,所以我不打算在这里深入讨论,因为它超出了这个问题的范围,但请查看 MVVM 或查看 Flutter State Management page 上的一些链接.您还可以使用 StreamBuilder 和流而不是 futurebuilder,因为这样可以在每次更改数据时(即更改过滤器时)显示更新的结果。