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".'),
);
},
);
}
CodePudding user response:
You can wrap the your Padding with a GestureDetector and add actions into the onTap method.
return GestureDetector(
onTap: () {
// TODO: Add actions onTap
},
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: 24, fontFamily: 'Avenir'),
),
);
);
CodePudding user response:
You need give your _testFuction
some content what depends on you tap to let the bottomsheet know what it should to show.Just likes:
return GestureDetector(
onTap:(){
_testFuction(context,glossarListOnSearch[index]);
}
...
)
void _testFuction(context, someContent) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return Scaffold(
body: Text('This is $someContent bottomsheet'),
);
},
);
}
CodePudding user response:
1. Create a Model class for FruitModel You can add as many parameters as you wanted like image URL , quantity , price , nutritional values etc.
class FruitModel {
int? id;
String? name;
String? facts;
FruitModel({this.id, this.name, this.facts});
}
2. Create List of Fruit and initialize it. Add as many items of fruits in the list as you wanted or you can get the data from Rest API.
List<FruitModel> fruitsList = [];
fruitsList.add(FruitModel(
id: 1, name: 'Banana', facts: 'Very good for bones and digestion'));
3. Change your test function parameters like this.
void testFuction(context, FruitModel model) {
showModalBottomSheet(
context: context,
builder: (BuildContext bc) {
return Scaffold(
body: Text('${model.facts}'),
);
},
);
}
Now , you can call the test function as following. It'll pass the whole object for you to the next screen or bottom sheet. You can change it according to your needs :
_testFuction(context,glossarListonSearch[index]);