Home > Software design >  Flutter Dynamic Searching appBar
Flutter Dynamic Searching appBar

Time:05-26

I'm trying to create a dynamic search in the appBar, but unfortunately I'm not succeeding and I have an error on this line.

results = _listPlaces.where((places) => places["place"].toLowerCase().contains(enteredKeyword.toLowerCase())

Full code:

import 'package:favspot/src/views/places_card.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '../../services/places.dart';
import 'dart:async';

class SeachPlaces extends StatefulWidget {

  @override
  State<SeachPlaces> createState() => _SeachPlacesState();
}

class _SeachPlacesState extends State<SeachPlaces> {
  List<Object> _listPlaces = [];
  List<Object> _searchSearch = [];

  @override
  initState(){
    _searchSearch = _listPlaces;
    super.initState();
  }

  void _runFilter(String enteredKeyword) {
    List<Object> results = [];
    if (enteredKeyword.isEmpty) {
      results = _listPlaces;
    } else {
      results = _listPlaces.where((places) => places["place"].toLowerCase().contains(enteredKeyword.toLowerCase())
      ).toList();

      setState((){
        _searchSearch = results;
      });
    }
  }


  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    getPlacesList();
  }

  TextEditingController? _textEditngController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Container(
          width: double.infinity,
        height: 40,
        decoration: BoxDecoration(
            color: Colors.white, borderRadius: BorderRadius.circular(30)),
        child: Center(
          child:TextField(
            onChanged: (value) => _runFilter(value),
            controller: _textEditngController,
            decoration: InputDecoration(
              contentPadding: EdgeInsets.all(5),
              prefixIcon: Icon(Icons.search),
              suffix: IconButton(
                icon: Icon(Icons.clear),
                onPressed: null,
          ),
            hintText: 'Searching...',
            border: InputBorder.none,
          ),
          ),
        ),
      ),
      ),
      body: SafeArea(
        child: ListView.builder(
            itemCount: _searchSearch.length,
            itemBuilder: (context, index) {
              return PlacesCard(_searchSearch[index] as Places);
            },
        )
      ),
    );
  }

  Future getPlacesList() async {
    var data = await FirebaseFirestore.instance
        .collection('places')
        .orderBy('city', descending: false)
        .get();

    setState(() {
      _listPlaces = List.from(data.docs.map((doc) => Places.fromSnapshot(doc)));
    });
  }
}

Here is de class Places

class Places {
  String? place;
  String? city;
  String? status;

  Places();


    Map<String, dynamic> toJson() => {

      'city'    : city,
      'status'  : status,
    };

  Places.fromSnapshot(snapshot) :
        place = snapshot.id,
        city = snapshot.data()['city'],
        status = snapshot.data()['status'];
}

CodePudding user response:

Consider to use List<Places> _listPlaces instead of List<Object> _listPlaces, so you can access properties like this:

results = _listPlaces.where((places) => places.place != null && places.place!.toLowerCase().contains(enteredKeyword.toLowerCase())
).toList();

  • Related