Home > OS >  Listview search and filter not working flutter
Listview search and filter not working flutter

Time:08-30

This is my model;

/*
// To parse this JSON data, do
//
//     final hisselist = hisselistFromJson(jsonString);

import 'dart:convert';

Hisselist hisselistFromJson(String str) => Hisselist.fromJson(json.decode(str));

String hisselistToJson(Hisselist data) => json.encode(data.toJson());

class Hisselist {
  Hisselist({
    required this.success,
    required this.result,
  });

  bool success;
  List<ResultClass> result;

  factory Hisselist.fromJson(Map<String, dynamic> json) => Hisselist(
    success: json["success"], result: json["result"].map<ResultClass>((x) => ResultClass.fromJson(x)).toList(),
  );

  Map<String, dynamic> toJson() => {
    "success": success,
    "result": result.map((x) => x.toJson()),
  };
}

class ResultClass {
  ResultClass({
    required this.rate,
    required this.lastprice,
    required this.lastpricestr,
    required this.hacim,
    required this.hacimstr,
    required this.text,
    required this.code,
  });

  double rate;
  double lastprice;
  String lastpricestr;
  double hacim;
  String hacimstr;
  String text;
  String code;

  factory ResultClass.fromJson(Map<String, dynamic> json) => ResultClass(
    rate: double.tryParse(json["rate"].toString()) ?? 0.0,
    lastprice: double.tryParse(json["lastprice"].toString()) ?? 0.0,
    lastpricestr: json["lastpricestr"],
    hacim: double.tryParse(json["hacim"].toString()) ?? 0.0,
    hacimstr: json["hacimstr"],
    text: json["text"],
    code: json["code"],
  );

  Map<String, dynamic> toJson() => {
    "rate": rate,
    "lastprice": lastprice,
    "lastpricestr": lastpricestr,
    "hacim": hacim,
    "hacimstr": hacimstr,
    "text": text,
    "code": code,
  };
}


 */

// To parse this JSON data, do
//
//     final hisselist = hisselistFromJson(jsonString);

import 'dart:convert';

Hisselist hisselistFromJson(String str) => Hisselist.fromJson(json.decode(str));

String hisselistToJson(Hisselist data) => json.encode(data.toJson());

class Hisselist {
  Hisselist({
    required this.success,
    required this.result,
  });

  bool success;
  List<Result> result;

  factory Hisselist.fromJson(Map<String, dynamic> json) => Hisselist(
    success: json["success"],
    result: List<Result>.from(json["result"].map((x) => Result.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "success": success,
    "result": List<dynamic>.from(result.map((x) => x.toJson())),
  };
}

class Result {
  Result({
    this.rate,
    this.lastprice,
    this.lastpricestr,
    this.hacim,
    this.hacimstr,
    this.min,
    this.minstr,
    this.max,
    this.maxstr,
    this.time,
    this.text,
    this.code,
  });

  double? rate;
  double? lastprice;
  String? lastpricestr;
  String? hacim;
  String? hacimstr;
  dynamic min;
  String? minstr;
  dynamic max;
  String? maxstr;
  Time? time;
  String? text;
  String? code;

  factory Result.fromJson(Map<String, dynamic> json) => Result(
    rate: json["rate"].toDouble(),
    lastprice: json["lastprice"].toDouble(),
    lastpricestr: json["lastpricestr"],
    hacim: json["hacim"],
    hacimstr: json["hacimstr"],
    min: json["min"],
    minstr: json["minstr"],
    max: json["max"],
    maxstr: json["maxstr"],
    time: timeValues.map[json["time"]],
    text: json["text"],
    code: json["code"],
  );

  Map<String, dynamic> toJson() => {
    "rate": rate,
    "lastprice": lastprice,
    "lastpricestr": lastpricestr,
    "hacim": hacim,
    "hacimstr": hacimstr,
    "min": min,
    "minstr": minstr,
    "max": max,
    "maxstr": maxstr,
    "time": timeValues.reverse[time],
    "text": text,
    "code": code,
  };
}

enum Time { THE_1809, THE_1808, THE_1805, THE_1810, THE_1759, THE_1755 }

final timeValues = EnumValues({
  "17:55": Time.THE_1755,
  "17:59": Time.THE_1759,
  "18:05": Time.THE_1805,
  "18:08": Time.THE_1808,
  "18:09": Time.THE_1809,
  "18:10": Time.THE_1810
});

class EnumValues<T> {
  Map<String, T> map;
  Map<T, String>? reverseMap;

  EnumValues(this.map);

  Map<T, String> get reverse {
    if (reverseMap == null) {
      reverseMap = map.map((k, v) => new MapEntry(v, k));
    }
    return reverseMap!;
  }
}

This is where i call api:

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

  @override
  State<Hisseler> createState() => _HisselerState();
}

class _HisselerState extends State<Hisseler> {
  final controller = TextEditingController();


  final scaffoldKey = GlobalKey<ScaffoldState>();
  final url = Uri.parse('https://api.collectapi.com/economy/hisseSenedi');
  var counter;

  Hisselist? hisseResult;

  Future callHisse() async {
    try{
      Map<String, String> requestHeaders = {
        'Content-Type': 'application/json',
        'Authorization': 'apikey xxx:xxx'
      };
      final response = await http.get(url,headers:requestHeaders);

      if(response.statusCode == 200){
        var result = hisselistFromJson(response.body);

        if(mounted);
        setState(() {

          counter = result.result.length;
          result.result.sort((a, b) => (a.text ?? "").compareTo(b.text ?? ""));

          hisseResult = result;
        });
        return result;
      } else {
        print(response.statusCode);
      }
    } catch(e) {
      print(e.toString());
    }
  }
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    callHisse();
  }

  @override
  Widget build(BuildContext context) {
    final style = controller.text.isEmpty
        ? const TextStyle(color: Colors.black54)
        : const TextStyle(color: Colors.black);
    return Scaffold(
      appBar: AppBar(
        centerTitle: false,
        automaticallyImplyLeading: false,
        title: Text(
            'Hisseler'
        ),
      ),
      body: Column(
        children: [
          Container(
            margin: const EdgeInsets.fromLTRB(16, 16, 16, 16),
            child: TextField(
              controller: controller,
              decoration: InputDecoration(
                prefixIcon: const Icon(Icons.search),
                suffixIcon: controller.text.isNotEmpty
                    ? GestureDetector(
                  child: Icon(Icons.close, color: style.color),
                  onTap: () {
                    controller.clear();
                    FocusScope.of(context).requestFocus(FocusNode());

                    searchHisse('');
                  },
                )
                    : null,
                hintText: 'Hisse Ara',
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(20),
                  borderSide: const BorderSide(color: Colors.black26),
                ),
              ),
              onChanged: searchHisse,
            ),
          ),
          Expanded(
            child: Center(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: counter != null ?

                ReorderableListView.builder(

                    itemCount: counter,


                    itemBuilder: (context, index){

                      return Card(
                        key: ValueKey(hisseResult?.result[index]),

                        child: ListTile(
                          contentPadding: EdgeInsets.all(10),
                          title: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Text((hisseResult?.result[index].code ?? "")
                                  .replaceAll("https:", ""),
                                  style: TextStyle(
                                      color: Colors.black,
                                      fontSize: 16,
                                      fontWeight: FontWeight.w500)),
                              Text(hisseResult?.result[index].text??"",style: TextStyle(color: Colors.grey[500], fontSize: 14))
                            ],
                          ),
                          trailing: Column(
                            children: <Widget>[
                              Text(hisseResult?.result[index].lastpricestr??"", style: TextStyle(color: Colors.black, fontSize: 16, fontWeight: FontWeight.w500)),
                              Container(
                                  alignment: Alignment.center,
                                  decoration: BoxDecoration(
                                      borderRadius: BorderRadius.circular(5),
                                      color: (hisseResult?.result[index].rate ?? 0) > 0
                                          ? Colors.green
                                          : Colors.red),
                                  width: 75,
                                  height: 25,
                                  child: Text(hisseResult?.result[index].rate.toString() ?? "",
                                      style: TextStyle(color: Colors.white)))
                            ],
                          ),
                          onTap: () => Navigator.push(
                            context, MaterialPageRoute(builder: (context) => StocksDetailScreen(
                            degisimoran: hisseResult?.result[index].rate!.toDouble(),
                            sondeger: hisseResult?.result[index].lastpricestr??"",
                            hacim: hisseResult?.result[index].hacimstr ?? "",
                            mindeger : hisseResult?.result[index].minstr?? "",
                            maxdeger : hisseResult?.result[index].maxstr?? "",
                            hisseismi : hisseResult?.result[index].text?? "",
                            hissekodu : hisseResult?.result[index].code?? "",
                            min : hisseResult?.result[index].min!.toDouble(),
                            max : hisseResult?.result[index].max!.toDouble(),
                            son : hisseResult?.result[index].lastprice!.toDouble(),




                          )),),

                        ),

                      );

                    },
                  onReorder: (oldIndex, newIndex) {
                    setState(() {
                      if (newIndex > oldIndex) {
                        newIndex = newIndex - 1;
                      }
                      final element = hisseResult?.result.removeAt(oldIndex);
                      hisseResult?.result.insert(newIndex, element!);
                    });
                  },) : Center(child: CircularProgressIndicator(

                )),
              ),
            ),
          ),
        ],
      ),
    );
  }

void searchHisse(String query) {
  final suggestions = hisseResult?.result.where((code) {
    final hisseTitle = hisseResult?.result;
    final input = query.toLowerCase();

    return hisseTitle!.contains(input);
  }).toList();

  setState(() => hisseResult = suggestions as Hisselist?);
}
}

But nothing happens on search result : enter image description here

I think the problem is on searchHisse() but i am not sure. How can i make this work? Thanks for your help

CodePudding user response:

Based on your code , you only call api once and you get the full list only once too.

i think you need to separated in to 2 list object.

eg case:

  • initstate you fetch api callHisse(); and get the data.
  • then you can show all the data from hisseResult.
  • after 1 onchanged on Textfield you call searchHisse(String query) , which is updated your hisseResult. now you only have data with first letters from onchanged
  • then you tapped on textfield and clear the controller. there is no data on the list left that match to query

this is what i suggest

Hisselist? hisseResult; // data you get from API
Hisselist? hisseShow; // list that you show

and on your search function you need to add this condition

void searchHisse(String query) {
  if (query == '') {
  setState((){hisseShow =hisseResult;});
  return; 
  }

  final suggestions = hisseResult?.result.where((code) {
    final hisseTitle = hisseResult?.result;
    final input = query.toLowerCase();

    return hisseTitle!.contains(input);
  }).toList();

// based on your model data

  setState(() => hisseShow =  Hisselist(result: suggestions, success:true );
}
}

and you show your list

 return Card(
   key: ValueKey(hisseShow?.result[index]),
   child: ListTile(
.....
  • Related