Flutter将来的json列表定义为最终版本,请停止对其进行更新

问题描述 投票:0回答:1

我可以从服务器获取JSON响应并列出清单。现在,我想向该列表添加一个过滤器。

为此,我遵循了在线教程。在该教程中,变量“ duplicateItems”已最终创建。参见代码:

final duplicateItems = List<String>.generate(10000, (i) => "Item $i");
var items = List<String>();

但是在我的情况下,由于我正在使用Future方法从服务器获取列表,所以我不能或不知道将该变量作为最终变量。参见代码:

class _ListServiceProvidersState extends State<ListServiceProviders> {  
  List items;
  List duplicateItems;  

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

  getSharedValues() async {
    bool value = await sharedPreferenceService.getSharedPreferencesInstance();
    if (value) {
      token = await sharedPreferenceService.token;
      fetchServices();
    } else {
      commonModelServices.showMessage(
          'You must log in before use the services', _scaffoldKey, Colors.red);
      Navigator.pushNamed(
        context,
        '/LoginPage',
      );
    }
  }

  Future<String> fetchServices() async {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      commonModelServices.onLoading(context);
    });
    final response = await http.get(
        'API URL?category_id=$catId&city=$cityId&latitude=$latitude&longitude=$longitude');
    setState(() {
      commonModelServices.offLoading(context);
      var resBody = json.decode(response.body);
      if (resBody['success'] == true) {
        setState(() {
          duplicateItems = resBody['data']['data'];
          items = duplicateItems;
        });
      }
    });
    return "Success";
  }

这是我的过滤功能

  void filterSearchResults(String query) {
    List dummySearchList = List();
    print('Original List');
    dummySearchList.addAll(duplicateItems);
    print(dummySearchList);
    print('Search Query');
    print(query);
    if (query.isNotEmpty) {
      print('search query not empty');
      List dummyListData = List();
      print('Start of the loop');
      dummySearchList.forEach((item) {
        print('List single item');
        print(item);
        if (item['name'].contains(query)) {
          print('Item contain search query');
          dummyListData.add(item);
        }
      });
      print('End of the loop');
      setState(() {
        print('Clear duplicated List');
        items.clear();
        print('Set searched results');
        items.addAll(dummyListData);
      });
      return;
    } else {
      print('Search query empty');
      setState(() {
        print('Clear prevoius searched in duplicate list');
        items.clear();
        print('Add Original List to duplicate');
        items.addAll(duplicateItems);
      });
    }
  }

过滤器将按预期在搜索字段中的第一个字母起作用。但是对于下一次按键,在执行filterSearchResults函数时,原始列表也将更新为第一次按键的搜索结果。因此,它从先前的搜索结果中搜索搜索词,而不是从原始列表中搜索。因此,结果是错误的。

我想在搜索后保持原始变量“ duplicateItems”不变。

你能告诉我这里缺少什么吗?

供您参考,下面将完整的代码。

import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_healthcare_app/src/theme/extention.dart';
import 'package:flutter_healthcare_app/src/theme/light_color.dart';
import 'package:flutter_healthcare_app/src/theme/text_styles.dart';
import 'package:flutter_healthcare_app/src/theme/theme.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_healthcare_app/src/model/shared_pref_model.dart';
import 'package:flutter_healthcare_app/src/model/common_model.dart';

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

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

class _ListServiceProvidersState extends State<ListServiceProviders> {
  TextEditingController editingController = TextEditingController();
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  SharedPreferenceService sharedPreferenceService = SharedPreferenceService();
  CommonModel commonModelServices = CommonModel();
  List items;
  List duplicateItems;
  String token;
  String cityId;
  int catId;
  String latitude;
  String longitude;

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

  getSharedValues() async {
    bool value = await sharedPreferenceService.getSharedPreferencesInstance();
    if (value) {
      token = await sharedPreferenceService.token;
      cityId = await sharedPreferenceService.cityId;
      catId = await sharedPreferenceService.catId;
      latitude = await sharedPreferenceService.latitude;
      longitude = await sharedPreferenceService.longitude;
      fetchServices();
    } else {
      commonModelServices.showMessage(
          'You must log in before use the services', _scaffoldKey, Colors.red);
      Navigator.pushNamed(
        context,
        '/LoginPage',
      );
    }
  }

  Future<String> fetchServices() async {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      commonModelServices.onLoading(context);
    });
    final response = await http.get(
        'API URL?category_id=$catId&city=$cityId&latitude=$latitude&longitude=$longitude');
    setState(() {
      commonModelServices.offLoading(context);
      var resBody = json.decode(response.body);
      if (resBody['success'] == true) {
        setState(() {
          duplicateItems = resBody['data']['data'];
          items = duplicateItems;
        });
      }
    });
    return "Success";
  }

  void filterSearchResults(String query) {
    List dummySearchList = List();
    print('Original List');
    dummySearchList.addAll(duplicateItems);
    print(dummySearchList);
    print('Search Query');
    print(query);
    if (query.isNotEmpty) {
      print('search query not empty');
      List dummyListData = List();
      print('Start of the loop');
      dummySearchList.forEach((item) {
        print('List single item');
        print(item);
        if (item['name'].contains(query)) {
          print('Item contain search query');
          dummyListData.add(item);
        }
      });
      print('End of the loop');
      setState(() {
        print('Clear duplicated List');
        items.clear();
        print('Set searched results');
        items.addAll(dummyListData);
      });
      return;
    } else {
      print('Search query empty');
      setState(() {
        print('Clear prevoius searched in duplicate list');
        items.clear();
        print('Add Original List to duplicate');
        items.addAll(duplicateItems);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: commonModelServices.appBar(context),
        body: SingleChildScrollView(
            child: Column(
          children: <Widget>[
            Container(
              child: _header(),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: TextField(
                onChanged: (value) {
                  filterSearchResults(value);
                },
                controller: editingController,
                decoration: InputDecoration(
                    labelText: "Search",
                    hintText: "Search",
                    prefixIcon: Icon(Icons.search),
                    border: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(25.0)))),
              ),
            ),
            Container(
                height: AppTheme.fullHeight(context),
                child: new ListView.builder(
                    itemCount: items == null ? 0 : items.length,
                    itemBuilder: (BuildContext context, int index) {
                      return _categoryListView(index, items, context);
                    })),
          ],
        )));
  }

  Widget _header() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Text("Categories", style: TextStyles.titleM),
      ],
    ).p16;
  }

/*  Widget _doctorsList(index, data, context) {

  }*/

  Widget _categoryListView(index, model, context) {
    return Container(
      margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(20)),
        boxShadow: <BoxShadow>[
          BoxShadow(
            offset: Offset(4, 4),
            blurRadius: 10,
            color: LightColor.grey.withOpacity(.2),
          ),
          BoxShadow(
            offset: Offset(-3, 0),
            blurRadius: 15,
            color: LightColor.grey.withOpacity(.1),
          )
        ],
      ),
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 18, vertical: 8),
        child: ListTile(
          contentPadding: EdgeInsets.all(0),
          leading: ClipRRect(
            borderRadius: BorderRadius.all(Radius.circular(13)),
            child: Container(
              height: 55,
              width: 55,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(15),
                color: randomColor(),
                image: DecorationImage(
                  image: NetworkImage(model[index]['image'].toString()),
                  fit: BoxFit.cover,
                ),
              ),
              /*child: Image.asset(
                model[index]['image'].toString(),
                height: 50,
                width: 50,
                fit: BoxFit.contain,
              ),*/
            ),
          ),
          title: Text(model[index]['name'], style: TextStyles.title.bold),
          subtitle: Text(
            model[index]['description'],
            style: TextStyles.bodySm.subTitleColor.bold,
          ),
          trailing: Icon(
            Icons.keyboard_arrow_right,
            size: 30,
            color: Theme.of(context).primaryColor,
          ),
        ),
      ).ripple(() {
        Navigator.pushNamed(context, "/DetailPage", arguments: model);
      }, borderRadius: BorderRadius.all(Radius.circular(20))),
    );
  }

  void _showCategoryListPage(selectedCategory, catId, context) {
    sharedPreferenceService.setCatId(catId);
    Navigator.pushNamed(
      context,
      '/SelectServiceProvider',
    );
  }

  Color randomColor() {
    var random = Random();
    final colorList = [
      Theme.of(context).primaryColor,
      LightColor.orange,
      LightColor.green,
      LightColor.grey,
      LightColor.lightOrange,
      LightColor.skyBlue,
      LightColor.titleTextColor,
      Colors.red,
      Colors.brown,
      LightColor.purpleExtraLight,
      LightColor.skyBlue,
    ];
    var color = colorList[random.nextInt(colorList.length)];
    return color;
  }
}
flutter dart
1个回答
0
投票

我在Google flutter社区中得到了答案。我在这里分享它,供将来其他人使用。

只有一行要更新。

我刚刚这样做

setState(() {
      duplicateItems = resBody['data']['data'];
      items = duplicateItems;
    });

它仅使参考变量。因此,当我更新items变量时,它也会自动更新duplicateItems变量。

所以我必须像下面这样更新。因此,两者都作为两个不同的列表工作。

duplicateItems = List.from(items);

所以完整的代码如下。

setState(() {
  commonModelServices.offLoading(context);
  var resBody = json.decode(response.body);
  if (resBody['success'] == true) {
    setState(() {
      items = resBody['data']['data'];
    });
  }
  //items = duplicateItems;
  duplicateItems = List.from(items);
});
热门问题
推荐问题
最新问题