The default value of an optional parameter must be constant

谁都会走 提交于 2020-08-10 23:08:09

问题


So Im creating this Event Tracker app and I have two screens which are the map and the events list. I am trying to get the place list to be equal to my places in my App state. Bare in mind that placeList is a modifiable list that I need to add places to this list.

However I am getting a "The default value of an optional parameter must be constant" whenever I initialize this.places=PlaceMapState.placeList and I cant change it to a constant since i need it to update my list of places in the PlaceMapState class and I cant remove it from AppState since I am using it in the PlaceList class to get the places as a list.

I also dont want to remove the AppState entirely because it also contains the map.

Please any solution to this???

Here is my class where I use this list:

class AppState {
   AppState({
    this.places = PlaceMapState.placeList,           //// here is the problem!!!!!!!!!!!!!!!!!!!
    this.selectedCategory = PlaceCategory.events,
    this.viewType = PlaceTrackerViewType.map,
   }) : //assert(places != null),
        assert(selectedCategory != null);

   List<Place> places;
   PlaceCategory selectedCategory;
   PlaceTrackerViewType viewType;

  AppState copyWith({
    List<Place> places,
    PlaceCategory selectedCategory,
    PlaceTrackerViewType viewType,
  }) {
    return AppState(

      selectedCategory: selectedCategory ?? this.selectedCategory,
      viewType: viewType ?? this.viewType,
    );
  }

  static AppState of(BuildContext context) => AppModel.of<AppState>(context);

  static void update(BuildContext context, AppState newState) {
    AppModel.update<AppState>(context, newState);
  }

  static void updateWith(
    BuildContext context, {
    List<Place> places,
    PlaceCategory selectedCategory,
    PlaceTrackerViewType viewType,
  }) {
    update(
      context,
      AppState.of(context).copyWith(
        places: places,
        selectedCategory: selectedCategory,
        viewType: viewType,
      ),
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    if (other.runtimeType != runtimeType) return false;
    return other is AppState &&
        other.places == places &&
        other.selectedCategory == selectedCategory &&
        other.viewType == viewType;
  }

  @override
  int get hashCode => hashValues(places, selectedCategory, viewType);
}

Here is the class of placeList where I use places to get a list:

class PlaceList extends StatefulWidget {
  const PlaceList({Key key}) : super(key: key);

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

class PlaceListState extends State<PlaceList> {
  ScrollController _scrollController = ScrollController();

  void _onCategoryChanged(PlaceCategory newCategory) {
    _scrollController.jumpTo(0.0);
    AppState.updateWith(context, selectedCategory: newCategory);
  }

  void _onPlaceChanged(Place value) {
    // Replace the place with the modified version.
    final newPlaces = List<Place>.from(AppState.of(context).places);
    final index = newPlaces.indexWhere((place) => place.id == value.id);
    newPlaces[index] = value;

    AppState.updateWith(context, places: newPlaces);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        _ListCategoryButtonBar(
          selectedCategory: AppState.of(context).selectedCategory,
          onCategoryChanged: (value) => _onCategoryChanged(value),
        ),
        Expanded(
          child: ListView(
            padding: const EdgeInsets.fromLTRB(16.0, 0.0, 16.0, 8.0),
            controller: _scrollController,
            shrinkWrap: true,
            children: AppState.of(context)
                .places                  //this the places im talking about!!!!!!!!!!!!!!!!!
                .where((place) =>
                    place.category == AppState.of(context).selectedCategory)
                .map((place) => _PlaceListTile(
                      place: place,
                      onPlaceChanged: (value) => _onPlaceChanged(value),
                    ))
                .toList(),
          ),
        ),
      ],
    );
  }
}

回答1:


A common workaround to requiring constant values for default arguments is to instead provide a sentinel argument as the default that can be const. Typically that sentinel argument can be null:

class AppState {
   AppState({
    List<Place> places,
    ...
   }) : places = places ?? PlaceMapState.placeList,
        assert(places != null),
        assert(selectedCategory != null);


来源:https://stackoverflow.com/questions/61956960/the-default-value-of-an-optional-parameter-must-be-constant

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!