I need to add a search bar that can search in my list. I don't know how to do it. I'm new to flutter. Thank you.

import 'package:flutter/material.dart';
import 'package:http/http.dart'as http;
import 'dart:async';
import 'dart:convert';
import './details.dart';

  class WelcomePage extends StatefulWidget {
  @override
  _WelcomePageState createState() => _WelcomePageState();
  }

class _WelcomePageState extends State<WelcomePage> {
  Future<List> getData() async{
    final response=await http.get("http://192.168.1.112/flutter/listview.php");
    return json.decode(response.body);
  }
Icon sr=Icon(Icons.search);
     Widget build(BuildContext context) {

    return Scaffold(
      appBar:AppBar(     
  actions: <Widget>[
    IconButton(icon: sr, onPressed: (){})]
    ),

      body: FutureBuilder<List>(
        future: getData(),
        builder: (ctx,ss){
          if(ss.hasError)
          {
            print("Error");
          }
          if(ss.hasData)
          {
            return Items(list:ss.data);
          }
          else{
            return CircularProgressIndicator();
          }
        }
        ),
    );

}
}

class Items extends StatelessWidget{
  List list;
  Items({this.list});
  @override
  Widget build (BuildContext context)
  {
    return ListView.builder(
      itemCount: list==null?0:list.length,
      itemBuilder: (ctx,i){
        return new Container(
          padding : const EdgeInsets.all(10),
          child : new Card(
          child :ListTile(
          leading: Icon(Icons.widgets),
          title: Text(list[i]['nom'],style: TextStyle(fontSize:20),),
          subtitle: Text(list[i]['etat']) ,
          onTap: ()=>Navigator.of(context).push(
            MaterialPageRoute(builder: (BuildContext context) =>Details( list,i),
          ),
        )
        )
        )
        );

      },
    );
  }

}


Solution 1: Guillaume Roux

Here is a basic way of doing what you want. You just have to convert your Items widget into a StatefulWidget then create a TextField with a TextEditingController. You will be able to use the TextField.onChanged property to call setState and rebuild your list filtered with the text controller current value.

class Items extends StatefulWidget {
  final List list;

  Items({@required this.list});

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

class _ItemsState extends State<Items> {
  final _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    List filteredList = [];
    if (_controller.text != null && _controller.text.isNotEmpty) {
      widget.list.forEach((item) {
        if (item.toString().toLowerCase().contains(_controller.text.toLowerCase()))
          filteredList.add(item);
      });
    } else
      filteredList = widget.list;
    return Column(children: <Widget>[
      TextField(controller: _controller, onChanged: (text) => setState(() {})),
      Expanded(
        child: ListView.builder(
            itemCount: filteredList.length,
            itemBuilder: (context, index) {
              return ListTile(title: Text(filteredList[index].toString()));
            }),
      ),
    ]);
  }
}