I have the suggestions list displayed on the screen by default, and I would like to make the suggestions list shows only when clicking on the text field.
I tried to put the listView in side the setState, but it did not work. I also tried to make a controller listener, but also did not work. Should I wrap the listView with a button?
Any help please!
here is my code
class MySearchBar extends StatefulWidget {
const MySearchBar({super.key});
@override
State<MySearchBar> createState() => _MySearchBarState();
}
class _MySearchBarState extends State<MySearchBar> {
final myController = TextEditingController();
static List<RestaurantProfiles> searchList = mySearchList;
List<RestaurantProfiles> display_list = List.from(searchList);
// this is the function that will update the suggestion list while searching
void searchUpdate(String value) {
setState(() {
display_list = searchList
.where((element) => element.restaurantName
.toLowerCase()
.contains(value.toLowerCase()))
.toList();
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
TextField(
onChanged: (value) => searchUpdate(value),
style: const TextStyle(
color: Colors.black,
),
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
isDense: true,
contentPadding: const EdgeInsets.all(10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide.none,
),
hintText: "Add Restaurants",
hintStyle: const TextStyle(
color: Colors.black26,
),
prefixIcon: const Icon(Icons.search),
prefixIconColor: Colors.black,
),
),
const SizedBox(
height: 5,
),
SizedBox(
height: 250,
child: Expanded(
child: display_list.isEmpty
? const Center(
child: Text(
"oops... No Results Found!",
style: TextStyle(
fontSize: 20,
),
),
)
: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white70),
child: ListView.builder(
itemCount: display_list.length,
itemBuilder: (context, index) => ListTile(
contentPadding: const EdgeInsets.all(8),
title: Text(display_list[index].restaurantName),
leading: Image(
image: AssetImage(display_list[index].img),
fit: BoxFit.cover,
height: 50,
width: 50,
),
trailing: const Icon(Icons.add),
),
),
),
),
),
],
),
);
}
}
2
Answers
I have created a sample based on your code. I hope this will resolve the issue.
First off, I’d like to mention that you’d probably want to use a
SearchDelegate
instead – as it can suggest the results for completion.You can use a
FocusNode
to listen to changes. it detects when the TextField does/desn’t have focus.At your State class, create 3 variables:
Then, create an
initState
method:And in your listview.builder:
Complete runnable snippet:
Relatable