How to color the suggestions when the user is typing in flutter

Issue

I am using typeahead package in flutter to get suggestions to users as they type, what I want is to color the suggestions while the user is typing as its shouwn in the picture Colored suggestions while typing

Here is a simple example that am trying to implement

Main.dart

import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'CitiesService.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Colored suggestions Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Colored suggestions Demo'),
    );
  }
}
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  final myControllerCity = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
          child: Form(
        key: this._formKey,
        child: Padding(
          padding: EdgeInsets.all(32.0),
          child: Column(
            children: <Widget>[
              //SizedBox(height: 50,),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Flexible(
                    child: TypeAheadFormField(
                      textFieldConfiguration: TextFieldConfiguration(
                          controller: myControllerCity,
                          decoration: InputDecoration(labelText: 'City')),
                      suggestionsCallback: (pattern) {
                        return CitiesService.getSuggestionsCities(pattern);
                      },
                      itemBuilder: (context, suggestion) {
                        //
                        List<String> splitted_names_of_cities = suggestion
                            .toString()
                            .toLowerCase()
                            .split(myControllerCity.text);
                        final children = <Widget>[];
                        for (var i = 1;
                            i < splitted_names_of_cities.length;
                            i++) {
                          children.add(new ListTile(
                              title: Text.rich(
                            TextSpan(
                              children: [
                                TextSpan(
                                  text: myControllerCity.text,
                                  style: TextStyle(color: Colors.red),
                                ),
                                TextSpan(text: splitted_names_of_cities[i]),
                              ],
                            ),
                          )));
                        }
                        print("this is the list $splitted_names_of_cities");
                        return new ListView(
                          children: children,
                        );
                      },
                      transitionBuilder: (context, suggestionsBox, controller) {
                        return suggestionsBox;
                      },
                      onSuggestionSelected: (suggestion) {
                        myControllerCity.text = suggestion;
                      },
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      )),
    );
  }
}

And here is the function of the suggestions

static List<String> getSuggestionsCities(String query) {
    List<String> wilayas = [];
    algeria_cites.forEach((element) => wilayas.contains(element['wilaya_name_ascii']) ?
     null : wilayas.add(element['wilaya_name_ascii']) );
    wilayas.retainWhere((s) => s.toLowerCase().contains(query.toLowerCase()));
    return wilayas;
  }

Solution

In the previous code, for each item of the suggested cities name I was creating a full ListTile but I had to create TextSpan instead of that.
But each item has its specific length, for that reason I used List<InlineSpan>.
So here is the itemBuilder after fixing the error.

itemBuilder: (context, suggestion) {
                        List<InlineSpan> temp = [];
                        String suggestion_in_lower_case = suggestion.toString().toLowerCase();
                        List<String> splitted_names_of_cities = suggestion_in_lower_case.split(myControllerCity.text.toLowerCase());
                        for (var i = 0; i < splitted_names_of_cities.length-1; i++) {
                          if(splitted_names_of_cities.contains(myControllerCity.text.toLowerCase()));{
                          temp.add(
                            TextSpan(
                              text: splitted_names_of_cities[i],
                              style: TextStyle(
                                height: 1.0,
                                color: Colors.black,

                              ),
                            ),
                          );
                            temp.add(
                              TextSpan(
                                text: myControllerCity.text.toLowerCase(),
                                style: TextStyle(
                                  color: Colors.red,
                                ),
                              ),
                            );
                          }
                        }
                        temp.add(
                          TextSpan(
                            text: splitted_names_of_cities.last,
                            style: TextStyle(
                              color: Colors.black,
                            ),
                          ),
                        );
                        return ListTile(
                            title: Text.rich(
                              TextSpan(
                                children: temp,
                              ),
                            )
                           );
                      },

So it is working as expected, here is the demo.
https://i.stack.imgur.com/Tfs95.gif

Answered By – Ishak Hari

Answer Checked By – Marie Seifert (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *