Flutter ListView search and click
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
import 'package:stack_demo/models/FruitModel.dart';
class GlossarScreen extends StatefulWidget {
@override
_GlossarScreenState createState() => _GlossarScreenState();
}
class _GlossarScreenState extends State<GlossarScreen> {
TextEditingController _textEditingController = TextEditingController();
List<FruitModel> glossarListOnSearch = [];
List<FruitModel> glossarList = [];
@override
void initState() {
glossarList.add(FruitModel(id: 0, name: 'Apple', facts: 'Good for health'));
glossarList.add(
FruitModel(id: 1, name: 'Banana', facts: 'Banana is also for health'));
glossarList.add(
FruitModel(id: 2, name: 'Orange', facts: 'Orange good for health'));
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Glossar'),
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xffFBD23E), Color(0xffF6BE03)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
),
bottom: PreferredSize(
preferredSize: Size(0, 60),
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 10),
child: Container(
//height: 50,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.white60, Colors.white70],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
borderRadius: BorderRadius.circular(50),
),
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: TextField(
textAlign: TextAlign.left,
onChanged: (value) {
setState(() {
glossarListOnSearch = glossarList
.where((element) => element.name!
.toLowerCase()
.contains(value.toLowerCase()))
.toList();
});
},
controller: _textEditingController,
decoration: InputDecoration(
border: InputBorder.none,
errorBorder: InputBorder.none,
enabledBorder: InputBorder.none,
contentPadding: EdgeInsets.all(0),
hintText: 'Search'),
),
),
),
),
),
),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xffFEFDFD), Color(0xffBDBDB2)],
begin: Alignment.topLeft,
end: Alignment.bottomRight),
),
child: _textEditingController.text.isNotEmpty &&
glossarListOnSearch.isEmpty
? Column(
children: [
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.fromLTRB(0, 50, 0, 0),
child: Text(
'No results',
style: TextStyle(
fontFamily: 'Avenir',
fontSize: 22,
color: Color(0xff848484)),
),
),
)
],
)
: ListView.builder(
itemCount: _textEditingController.text.isNotEmpty
? glossarListOnSearch.length
: glossarList.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_textEditingController.text.isNotEmpty
? _testFuction(context, glossarListOnSearch[index])
: _testFuction(context, glossarList[index]);
},
child: Padding(
padding: const EdgeInsets.fromLTRB(12, 15, 12, 15),
child: Text(
_textEditingController.text.isNotEmpty
? glossarListOnSearch[index].name!
: glossarList[index].name!,
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontFamily: 'Avenir'),
),
),
);
},
),
),
);
}
}
void _testFuction(context, FruitModel model) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return Scaffold(
body: Text('${model.facts}'),
);
},
);
}
Berkin
Updated on January 01, 2023Comments
-
Berkin over 1 year
So I'm currently trying to implement some searching functionality to my ListView and this does work great actually. When I type in some letters it automatically shows me the right things (-> See Screenshot_Listview_1.png and Screenshot_Listview_2.png).
There is only one problem. I want the different texts from my listview to be clickable, so when I click on them a new ModalBottomSheet should appear. For example: I'm searching for "Apple" and when I click on the text "Apple" a ModalBottomSheet opens and I can read some facts about apples. I tried the onTap method and it works so far but I only managed to open the same BottomSheet.. But I need different BottomSheets depending on what I have tapped on.
This is what I got so far. Can you please help me out? I really don't know how to solve this problem. Thank you so much!!
import 'package:flutter/material.dart'; import 'dart:ui' as ui; class GlossarScreen extends StatefulWidget { @override _GlossarScreenState createState() => _GlossarScreenState(); } class _GlossarScreenState extends State<GlossarScreen> { TextEditingController _textEditingController = TextEditingController(); List<String> glossarListOnSearch = []; List<String> glossarList = [ 'Apple', 'Orange', 'Banana', 'Grapefruit', 'Mango', 'Kiwi', 'Grapes', ]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Glossar'), flexibleSpace: Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [Color(0xffFBD23E), Color(0xffF6BE03)], begin: Alignment.topCenter, end: Alignment.bottomCenter), ), ), bottom: PreferredSize( preferredSize: Size(0, 60), child: Padding( padding: const EdgeInsets.fromLTRB(12, 0, 12, 10), child: Container( //height: 50, decoration: BoxDecoration( gradient: LinearGradient( colors: [Colors.white60, Colors.white70], begin: Alignment.topCenter, end: Alignment.bottomCenter), borderRadius: BorderRadius.circular(50), ), child: Padding( padding: const EdgeInsets.fromLTRB(20, 0, 0, 0), child: TextField( textAlign: TextAlign.left, onChanged: (value) { setState(() { glossarListOnSearch = glossarList .where((element) => element .toLowerCase() .contains(value.toLowerCase())) .toList(); }); }, controller: _textEditingController, decoration: InputDecoration( border: InputBorder.none, errorBorder: InputBorder.none, enabledBorder: InputBorder.none, contentPadding: EdgeInsets.all(0), hintText: 'Search'), ), ), ), ), ), ), body: Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [Color(0xffFEFDFD), Color(0xffBDBDB2)], begin: Alignment.topLeft, end: Alignment.bottomRight), ), child: _textEditingController.text.isNotEmpty && glossarListOnSearch.isEmpty ? Column( children: [ Align( alignment: Alignment.center, child: Padding( padding: const EdgeInsets.fromLTRB(0, 50, 0, 0), child: Text( 'No results', style: TextStyle( fontFamily: 'Avenir', fontSize: 22, color: Color(0xff848484)), ), ), ) ], ) : ListView.builder( itemCount: _textEditingController.text.isNotEmpty ? glossarListOnSearch.length : glossarList.length, itemBuilder: (context, index) { return GestureDetector( onTap: () { _testFuction(context); }, child: Padding( padding: const EdgeInsets.fromLTRB(12, 15, 12, 15), child: Text( _textEditingController.text.isNotEmpty ? glossarListOnSearch[index] : glossarList[index], style: TextStyle( color: Colors.black, fontSize: 20, fontFamily: 'Avenir'), ), ), ); }, ), ), ); } } void _testFuction(context) { showModalBottomSheet( context: context, builder: (BuildContext bc) { return Scaffold( body: Text('This text should be dependent on what I have tapped on. If I tap on "Apple" a different ModalBottomSheep shall appear then when I press on "Banana".'), ); }, ); }
-
Berkin over 2 yearsThank you very much but how do I go on? How can I make it possible to open a new page when I press on "Apple" or when I press on "Banana"? So how to differentiate?
-
Berkin over 2 yearsThank you very much for your answer! But this doesn't work and I don't know why. This code is not working: fruitsList.add(FruitModel( id: 1, name: 'Banana', facts: 'Very good for bones and digestion')); Can you please tell me what to do or how to implement it to my code?
-
Afaq Ahmed over 2 years1. Create a separate dart file for Fruit Model. 2. Create List in your desired class and import the FruitModel. 3. You have to use FruitModel everywhere for fruits. Can you show me the exact error or problem you're facing?
-
Berkin over 2 yearsSo the problem is that fruitsList.add is underlined in red color. Also _testFuction(context,glossarListonSearch[index]); is underlined. Somehow Flutter doesn't know what this code is.
-
Afaq Ahmed over 2 yearsActually , you can check the error by hovering over the red line or by simply going to the Dart Analysis tab at bottom. You have to use the add functionality in init() method of your screen.
-
Berkin over 2 yearsIt says: "The name 'fruitsList' is already defined. Try renaming one of the declarations." but I don't really understand what to do now. And I also don't really understand where to put your code inside of mine. I'm so sorry to bother you that much but I'm relatively new to flutter.
-
Afaq Ahmed over 2 yearsI edited my response. Now you can easily understand. I used your code.
-
Berkin over 2 yearsThank you so so much!! It worked!