I was wondering how to make the search function works according to the index of my ListView
? So for instance if I input a z
according to my case, I should not display anything in the List
. I have also updated and posted the function _getTicketDeatils()
here.
var userDetails = {}; var i; List returnTicketDetails = [] ; body: new Column( children: <Widget>[ new Container( color: Theme.of(context).primaryColor, child: new Padding( padding: const EdgeInsets.all(8.0), child: new Card( child: new ListTile( leading: new Icon(Icons.search), title: new TextField( controller: controller, decoration: new InputDecoration( hintText: 'Search', border: InputBorder.none), // onChanged: onSearchTextChanged, ), trailing: new IconButton(icon: new Icon(Icons.cancel), onPressed: () { controller.clear(); // onSearchTextChanged(''); },), ), new Expanded( child: userDetails.length != 0 || controller.text.isNotEmpty ? new ListView.builder( itemCount: userDetails.length, itemBuilder: (context, i) { return new Card( child: new Column (mainAxisSize: MainAxisSize.min, children: <Widget>[ new Row(children: <Widget>[ new Container( width: 80.0, height: 80.0, decoration: new BoxDecoration( shape: BoxShape.circle, image: new DecorationImage( fit: BoxFit.fill, image: new NetworkImage( "https:..") ) )), new Text(userDetails[returnTicketDetails[i]["user_id"]]["first_name"] ),), ,), new Text(userDetails[returnTicketDetails[i]["user_id"]]["last_name"]), ); }, ) : new ListView.builder( itemCount: userDetails.length, itemBuilder: (context, i) { return new Card( child: new ListTile( //title: new Text(userDetails[returnTicketDetails[i]["user_id"]]["first_name"]), ), margin: const EdgeInsets.all(0.0), ); ); } _getTicketDetails() async { final response = await http.get( "https..", headers: { HttpHeaders.AUTHORIZATION: access_token }); returnTicketDetails = json.decode(response.body); for ( i = 0; i < (returnTicketDetails?.length ?? 0); i++) { final ticketresponse = await http.get( "https...", headers: { HttpHeaders.AUTHORIZATION: access_token }); userDetails[returnTicketDetails[i]["user_id"]] = json.decode(ticketresponse.body); } }
I've replaced hardcoded model input with getting data from URL as you needed.
import 'dart:async'; import 'package:flutter/material.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; void main() => runApp(new MaterialApp( home: new HomePage(), debugShowCheckedModeBanner: false, )); class HomePage extends StatefulWidget { @override _HomePageState createState() => new _HomePageState(); } class _HomePageState extends State<HomePage> { TextEditingController controller = new TextEditingController(); // Get json result and convert it to model. Then add Future<Null> getUserDetails() async { final response = await http.get(url); final responseJson = json.decode(response.body); setState(() { for (Map user in responseJson) { _userDetails.add(UserDetails.fromJson(user)); } }); } @override void initState() { super.initState(); getUserDetails(); } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('Home'), elevation: 0.0, ), body: new Column( children: <Widget>[ new Container( color: Theme.of(context).primaryColor, child: new Padding( padding: const EdgeInsets.all(8.0), child: new Card( child: new ListTile( leading: new Icon(Icons.search), title: new TextField( controller: controller, decoration: new InputDecoration( hintText: 'Search', border: InputBorder.none), onChanged: onSearchTextChanged, ), trailing: new IconButton(icon: new Icon(Icons.cancel), onPressed: () { controller.clear(); onSearchTextChanged(''); },), ), ), ), ), new Expanded( child: _searchResult.length != 0 || controller.text.isNotEmpty ? new ListView.builder( itemCount: _searchResult.length, itemBuilder: (context, i) { return new Card( child: new ListTile( leading: new CircleAvatar(backgroundImage: new NetworkImage(_searchResult[i].profileUrl,),), title: new Text(_searchResult[i].firstName + ' ' + _searchResult[i].lastName), ), margin: const EdgeInsets.all(0.0), ); }, ) : new ListView.builder( itemCount: _userDetails.length, itemBuilder: (context, index) { return new Card( child: new ListTile( leading: new CircleAvatar(backgroundImage: new NetworkImage(_userDetails[index].profileUrl,),), title: new Text(_userDetails[index].firstName + ' ' + _userDetails[index].lastName), ), margin: const EdgeInsets.all(0.0), ); }, ), ), ], ), ); } onSearchTextChanged(String text) async { _searchResult.clear(); if (text.isEmpty) { setState(() {}); return; } _userDetails.forEach((userDetail) { if (userDetail.firstName.contains(text) || userDetail.lastName.contains(text)) _searchResult.add(userDetail); }); setState(() {}); } } List<UserDetails> _searchResult = []; List<UserDetails> _userDetails = []; final String url = 'https://jsonplaceholder.typicode.com/users'; class UserDetails { final int id; final String firstName, lastName, profileUrl; UserDetails({this.id, this.firstName, this.lastName, this.profileUrl = 'https://i.amz.mshcdn.com/3NbrfEiECotKyhcUhgPJHbrL7zM=/950x534/filters:quality(90)/2014%2F06%2F02%2Fc0%2Fzuckheadsho.a33d0.jpg'}); factory UserDetails.fromJson(Map<String, dynamic> json) { return new UserDetails( id: json['id'], firstName: json['name'], lastName: json['username'], ); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With