I am trying to show 3 widgets with 3 different on tap functions, but it is not working. So what I want is the whole widget split in 3 different widgets so I can call widget 1 widget 2 or widget 3. But this is not working and I don't know why exactly. I have this videos collection where users videos are uploaded with 3 hashtags and what I want is that the user can search for one hashtag no matter which one, but it always shows all 3 hashtags instead of the one which the user searched for. And that is what I mean with 3 different widgets.
Here is my code:
class Openalldocs extends StatefulWidget {
final TextEditingController searchinginput;
static const route = '/openalldocs';
const Openalldocs({Key key, this.searchinginput}) : super(key: key);
@override
_OpenalldocsState createState() => _OpenalldocsState();
}
class _OpenalldocsState extends State<Openalldocs> {
List _allResults = [];
List _resultsList = [];
Future resultsLoaded;
bool nosuerfound = false;
String searchresult;
@override
void initState() {
super.initState();
widget.searchinginput.addListener(_onsearchChanged);
setState(() {
nosuerfound = true;
});
}
@override
void dispose() {
widget.searchinginput.removeListener(_onsearchChanged());
super.dispose();
}
@override
void didChangeDependencies() {
widget.searchinginput.text;
resultsLoaded = getusers();
super.didChangeDependencies();
}
_onsearchChanged() {
setState(() {
nosuerfound = false;
});
searchResults();
}
searchResults() {
var showResults = [];
if (widget.searchinginput.text != "") {
for (var tripsnapshot in _allResults) {
var title = DatbaseService.instance
.videosfromsnapshot(tripsnapshot)
.hashtag1
.toLowerCase();
print(title);
var title2 = DatbaseService.instance
.videosfromsnapshot(tripsnapshot)
.hashtag3
.toLowerCase();
print(title);
var title3 = DatbaseService.instance
.videosfromsnapshot(tripsnapshot)
.hashtag2
.toLowerCase();
print(title);
if (title.contains(widget.searchinginput.text.toLowerCase()) ||
title2.contains(widget.searchinginput.text.toLowerCase()) ||
title3.contains(widget.searchinginput.text.toLowerCase())) {
setState(() {
nosuerfound = true;
});
showResults.add(tripsnapshot);
}
}
} else {
setState(() {
nosuerfound = true;
});
showResults = List.from(_allResults);
}
setState(() {
_resultsList = showResults;
});
}
getusers() async {
var firestore = FirebaseFirestore.instance;
QuerySnapshot qn = await firestore.collection('videos').get();
if (!mounted) return;
setState(() {
_allResults = qn.docs;
});
searchResults();
return "Complete";
}
@override
Widget build(BuildContext context) {
final user = Provider.of<Userforid>(context);
if (nosuerfound == true) {
return ListView.builder(
itemCount: _resultsList.length,
itemBuilder: (BuildContext context, int index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: () {
},
child: Column(
children: <Widget>[
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
content: _resultsList[index].data()['hashtag1'],
),
],
),
SizedBox(height: 3),
],
),
),
SizedBox(height: 6),
InkWell(
onTap: () {
},
child: Column(
children: <Widget>[
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
content: _resultsList[index].data()['hashtag2'],
),
],
),
],
),
),
SizedBox(height: 6),
InkWell(
onTap: () {
},
child: Column(
children: <Widget>[
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
content: _resultsList[index].data()['hashtag3'],
),
],
),
SizedBox(height: 3),
],
),
),
SizedBox(height: 6),
]);
},
);
} else {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Center(
child: Container(
child: Text(
"No Hashtag found",
style: TextStyle(fontSize: 16),
)),
),
);
}
}
}
Your onTap
handlers are empty, so nothing will happen actually when tapping.
To achieve what you are trying to, it is better to instead of creating widgets one by one in the Column children, create a for loop, and make the onTap and everything relative to it.
Here is how to achieve it (I took only a subsection of the code, the Column
part):
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// the AMOUNT is how many hashtags you want to show
for (var i = 0; i < AMOUNT; i += 1) ...[
// the SizedBox will only exist between the elements in the list
// as before
if (i != 0) SizedBox(height: 6),
// create a builder to allow declaring a variable
Builder(
builder: (context) {
// declare the hashtag variable
final hashtag = 'hashtag$i';
return InkWell(
onTap: () {
// do something with the hashtag stored in the variable
// this will make it relative to the element in the list
},
child: Column(
children: <Widget>[
// why is there a Column inside another with only one child?
// I would recommend to remove it
Column(
children: [
HighlightedMatchesText(
searchString: widget.searchinginput.text,
// notice how I am using the hashtag variable here
// instead of a constant? ('hashtag1'), by the way
// the for loop will make the hashtag start at 0
// you can change it by increment in the declaration
// `final hashtag = 'hashtag${i+1}'`, if you want
// the existing behavior
content: _resultsList[index].data()[hashtag],
),
],
),
// what is this? if it is to add more space between the items
// in the list, I recommend removing it from here, and add it
// to the first `SizedBox` in the for loop
// in case you do that, the Column that this widget belong
// would also only now contain one widget, so, there is no
// need to have it
SizedBox(height: 3),
],
),
),
},
);
],
],
);
I added a lot of comments, I hope they help you to achieve what you are trying to.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.