Flutter pass variable to SearchDelegate class gives error - search

I am a newbie to flutter, I am having a problem with passing the data to my search delegate class. The problem is that I have two tabs and I want to search within the active tab. So I am trying to send a variable that tells which tab is it and which table to look for value.
Here is what my code looks like:
class HomePage extends StatefulWidget {
static final String routeName = 'home';
#override
State<StatefulWidget> createState() {
return new _HomePageState();
}
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
var activeTab = "activity";
var _authToken, _id, _name, _emails, _userImage;
#override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: 2)..addListener(() {
setState(() {
switch (tabController.index) {
case 0:
activeTab = "activity";
break;
case 1:
activeTab = "subparticipants";
break;
}
});
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
// appBar: new AppBar(
// title: Text('Dashboard'),
// ),
body: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
labelColor: Color(0xFFFFFFFF),
indicatorSize: TabBarIndicatorSize.tab,
tabs: [
//Tab(icon: Icon(Icons.directions_car)),
Tab(
text: "Activity Zone",
),
Tab(
text: "Sub Participant",
)
],
controller: tabController,
),
title: Text(
'Dashboard',
style: new TextStyle(
color: const Color(0xFFFFFFFF),
fontSize: 20.0,
fontWeight: FontWeight.w600,
letterSpacing: 0.3,
),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: DataSearch(activeTab));
},
)
],
),
body: TabBarView(
controller: tabController,
children: [
TabActivity(),
TabSubparticipant(),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
print(
'Current Index: $activeTab');
},
),
drawer: _buildDrawer(context),
),
),
);
}
}
class DataSearch extends SearchDelegate{
final String activeTab;
DataSearch(this.activeTab);
#override
List<Widget> buildActions(BuildContext context){
return [
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: (){
query=activeTab;
},
)
];
}
#override
Widget buildLeading(BuildContext context) => IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.of(context).pop(),
);
#override
Widget buildResults(BuildContext context) => Text('Result');
#override
Widget buildSuggestions(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Search by job id, asset name, client name $query',
style: new TextStyle(
color: Colors.black, fontWeight: FontWeight.bold, fontSize: 22.0),
),
);
}
}
When I try to get $activeTab and show it in query or somewhere else, It just gives out the error:
flutter: The following assertion was thrown building _SearchPage<dynamic>(dirty, dependencies:
flutter: [_LocalizationsScope-[GlobalKey#a02e3], _InheritedTheme], state: _SearchPageState<dynamic>#eceaa):
flutter: 'package:flutter/src/widgets/basic.dart': Failed assertion: line 6173 pos 15: 'child != null': is
I am a bit confused how should I pass value to it. I have seen some of similar questions but they are no help. Like this or this question. None of these have any of these errors. Can you please let me know what am I doing wrong. Whats the issue? Please help.

Well, For someone who dumb as me and is having the same problem as I am, Here is how you can fix the issue,
So I was not passing the correct value to Search delegate and was not picking it up properly. Here is the fixed part of code
class DataSearch extends SearchDelegate {
DataSearch({
#required this.activeTab,
});
final activeTab;
#override
Widget buildResults(BuildContext context) {
if (activeTab == "subparticipants") {
...... .
....
..

Related

How to return flip cards to their original position from a widget in another dart file?

I'm relatively new to Flutter and have tried to find similar postings to help me but haven't had any luck in getting them to work for me unfortunately. I have an Android Studio program that's basically a game which involves a grid of flip cards. I have the flip cards in one dart file and the app bar in another. I have an iconbutton on the app bar which currently reduces the point count to zero, but I would also like for it to flip all of the flip cards back to their original positions when pressed. I have a global variable called resetBool that I've been trying to use, something like if resetBool == true then toggleCard() maybe. I think I might need to use a key but am having trouble implementing one properly.
Here is the code in the file which contains my appbar:
import 'package:flip_card/flip_card.dart';
import 'package:flutter/material.dart';
import 'gridone.dart' as gridone;
import 'globalVariables.dart';
import 'statenames.dart';
int count;
StateNames stateObject = new StateNames();
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home>with SingleTickerProviderStateMixin {
TabController controller;
#override
void initState() {
controller = new TabController(length: 1, vsync: this);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
void changeCount() {
setState(() {
counter += 1;
});
}
void decreaseCount() {
setState(() {
counter -= 1;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title:new Text("License plate game"),
backgroundColor: Colors.greenAccent,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.autorenew,
color: Colors.white,
),
onPressed: () {
setState(() {
counter = 0;
resetBool = true;
});
},
),
Center(
child: Container(
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
child: Text('points: $counter', textAlign: TextAlign.center, style: TextStyle(fontSize: 15),
)
),
),
],
bottom: new TabBar(
controller: controller,
indicatorWeight: 5.0,
indicatorColor: Colors.green,
tabs: <Widget> [
new Tab(icon: new Icon(Icons.image),),
],
),
),
body: new TabBarView(
controller: controller,
children: <Widget>[
new gridone.GridOne(changeCount, decreaseCount),
],
)
);
}
}
And here is the code in the file which contains my flip cards:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flip_card/flip_card.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'statenames.dart';
import 'globalVariables.dart';
import 'Home.dart';
import 'gridtwo.dart' as gridTwo;
StateNames stateObject = new StateNames();
Home homeObject = new Home();
class GridOne extends StatefulWidget {
final Function updateCounter;
final Function decreaseCount;
GridOne(this.updateCounter, this.decreaseCount);
#override
_GridOneState createState() => _GridOneState();
}
class _GridOneState extends State<GridOne>
with AutomaticKeepAliveClientMixin {
#override
bool get wantKeepAlive => true;
int points = 0;
#override
Widget build(BuildContext context) {
super.build(context);
return new Scaffold(
body: new Column(
children: <Widget> [
new Expanded(
child: GridView.count(
crossAxisCount: 5,
children: List.generate(52, (index){
return Card(
elevation: 0.0,
margin: EdgeInsets.only(left: 3.0, right: 3.0, top: 9.0, bottom: 0.0),
color: Color(0x00000000),
child: FlipCard(
direction: FlipDirection.HORIZONTAL,
speed: 1000,
//(resetBool == true) ? cardKey.currentState.toggleCard() : null,
onFlipDone: (status) {
setState(() {
(status)
? widget.decreaseCount()
: widget.updateCounter();
});
if (counter == 25) {
Fluttertoast.showToast(
msg: "You've got 25 states! Wow!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM_LEFT,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
};
print(counter);
},
front: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FittedBox(fit:BoxFit.fitWidth,
child: Text(stateObject.stateNames[index], style: TextStyle(fontFamily: 'Architects Daughter', color: Colors.white), )
//Theme.of(context).textTheme.headline
),
Text('',
style: Theme.of(context).textTheme.body1),
],
),
),
back: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image(image: AssetImage(stateObject.licensePlatePaths[index])),
//Text('',
//style: Theme.of(context).textTheme.body1),
],
),
),
),
);
})
)
)
]
),
);
}
}
The solution is to use currentState.toggleCard(); for the cards that are facing Back when the IconButton is clicked.
Basically, what I did is I gave keys to each card at initState method.
List<GlobalKey<FlipCardState>> cardKeys = [];
#override
void initState() {
List.generate(52, (index) {
cardKeys.add(GlobalKey<FlipCardState>());
});
super.initState();
}
Don't forget to put the key to widget
FlipCard(key: cardKeys[index], ... )
Then, call resetCards method below when the button is clicked. If the card is facing back then toggle logic.
void resetCards() {
cardKeys.forEach((element) {
if (!element.currentState.isFront) {
element.currentState.toggleCard();
}
});
setState(() {});
}
You need to call a method on the parent widget, that would be triggered in the child widget. For that, please check this stackoverflow link
Full working code:
import 'package:flutter/material.dart';
import 'package:flip_card/flip_card.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
// This makes the visual density adapt to the platform that you run
// the app on. For desktop platforms, the controls will be smaller and
// closer together (more dense) than on mobile platforms.
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(),
);
}
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
TabController controller;
int counter = 0;
final GridOneController myController = GridOneController();
#override
void initState() {
controller = new TabController(length: 1, vsync: this);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
void changeCount() {
setState(() {
counter += 1;
});
}
void decreaseCount() {
setState(() {
counter -= 1;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("License plate game"),
backgroundColor: Colors.greenAccent,
actions: <Widget>[
IconButton(
icon: Icon(
Icons.autorenew,
color: Colors.white,
),
onPressed: () {
setState(() {
counter = 0;
myController.resetCards();
});
},
),
Center(
child: Container(
padding: EdgeInsets.fromLTRB(20, 20, 20, 20),
child: Text(
'points: $counter',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 15),
)),
),
],
bottom: new TabBar(
controller: controller,
indicatorWeight: 5.0,
indicatorColor: Colors.green,
tabs: <Widget>[
new Tab(
icon: new Icon(Icons.image),
),
],
),
),
body: new TabBarView(
controller: controller,
children: <Widget>[
new GridOne(counter, myController),
],
));
}
}
class GridOneController {
void Function() resetCards;
}
class GridOne extends StatefulWidget {
int counter;
final GridOneController controller;
GridOne(this.counter, this.controller);
#override
_GridOneState createState() => _GridOneState(controller);
}
class _GridOneState extends State<GridOne> {
_GridOneState(GridOneController _controller) {
_controller.resetCards = resetCards;
}
int points = 0;
void increaseCounter() {
widget.counter += 1;
}
void decreaseCounter() {
widget.counter -= 1;
}
void resetCards() {
cardKeys.forEach((element) {
if (!element.currentState.isFront) {
element.currentState.toggleCard();
}
});
setState(() {});
}
List<GlobalKey<FlipCardState>> cardKeys = [];
#override
void initState() {
List.generate(52, (index) {
cardKeys.add(GlobalKey<FlipCardState>());
});
super.initState();
}
#override
Widget build(BuildContext context) {
print(cardKeys.length);
return new Scaffold(
body: new Column(children: <Widget>[
new Expanded(
child: GridView.count(
crossAxisCount: 5,
children: List.generate(52, (index) {
return Card(
elevation: 0.0,
margin: EdgeInsets.only(
left: 3.0, right: 3.0, top: 9.0, bottom: 0.0),
color: Color(0x00000000),
child: new FlipCard(
key: cardKeys[index],
direction: FlipDirection.HORIZONTAL,
speed: 1000,
onFlipDone: (status) {
setState(() {
(status) ? decreaseCounter() : increaseCounter();
});
if (widget.counter == 25) {
Fluttertoast.showToast(
msg: "You've got 25 states! Wow!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM_LEFT,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0);
}
;
print(widget.counter);
},
front: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
FittedBox(
fit: BoxFit.fitWidth,
child: Text(
'FRONT',
style: TextStyle(color: Colors.white),
)
//Theme.of(context).textTheme.headline
),
Text(
'',
),
],
),
),
back: Container(
decoration: BoxDecoration(
color: Color(0xFF006666),
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Text('BACK')],
),
),
),
);
})))
]),
);
}
}

How to hide/show a button with another button | Flutter?

New to programming and dart/flutter .
Thank You.
So 2 buttons Me! and You! , I have to hide and show me! button clicking on You! button .
So can any one help me to find solution of my question.
and what if i have more numbers of buttons and show/hide all of them using a single button.
My code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
),
MaterialButton(
onPressed: () {},
child: Text('You!'),
color: Colors.red,
)
],
),
),
);
}
}
use a Visibility Widget.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool isVisible = true; //will be visible for the first frame
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
Visibility(
visible: isVisible,
child: MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
),
),
MaterialButton(
onPressed: () {
setState(() {
isVisible = !isVisible;
});
},
child: Text('You!'),
color: Colors.red,
)
],
),
),
);
}
}
Here are 3 examples.
1
class _MyHomePageState extends State<MyHomePage> {
bool hide = false;
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
if(!hide)MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
),
MaterialButton(
onPressed: () {
setState((){
hide = !hide;
});
},
child: Text('${hide ? "Show" : "Hide"}'),
color: Colors.red,
)
],
),
),
);
}
}
2
class _MyHomePageState extends State<MyHomePage> {
bool hide = false;
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
Opacity(
opacity: hide ? 0 : 1,
child: MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
)
),
MaterialButton(
onPressed: () {
setState((){
hide = !hide;
});
},
child: Text('${hide ? "Show" : "Hide"}'),
color: Colors.red,
)
],
),
),
);
}
}
3 (Adding animation)
class _MyHomePageState extends State<MyHomePage> {
bool hide = false;
#override
Widget build(BuildContext context) {
return Container(
child: SafeArea(
child: Column(
children: [
AnimatedOpacity(
opacity: hide ? 0 : 1,
duration: Duration(seconds: 2),
child: MaterialButton(
onPressed: () {},
child: Text('Me!'),
color: Colors.green,
)
),
MaterialButton(
onPressed: () {
setState((){
hide = !hide;
});
},
child: Text('${hide ? "Show" : "Hide"}'),
color: Colors.red,
)
],
),
),
);
}
}
Note: The first example will remove the button from the widget tree. For the second and third, the button will be in the widget tree but won't be visible.
So you can see it as:
First example: The button is GONE.
Second example: The button is INVISIBLE.

Flutter Navigator.pop won't send data back

This is my code so far. I dont know whats wrong, I tried a lots of youtube turolial and other things as well, but its looks like the pop wont give back the correct data. I really need help, i spend 2 days already
void main() {
List<String> names = [];
List<String> mgs = [];
runApp(MaterialApp(
title: 'Returning Data',
home: HomeScreen(names, mgs),
));
}
class HomeScreen extends StatelessWidget {
List<String> names = [];
List<String> mgs = [];
HomeScreen(this.names, this.mgs);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("Project_Drink"),
),
body: Container(
child: Column(
children: <Widget>[
new Expanded(
child: ListView.builder
(
itemCount: mgs.length,
itemBuilder: (context, Index) {
return Text("Name: " + names[Index]
+" "+ "Mg: " + mgs[Index]);
}
)
)
],
),
),
bottomNavigationBar :BottomAppBar (
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const Expanded(child: Text("TOTAL : 200")),
FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddProduct()),
);
},
child: Icon(Icons.add),
),
],
),
),
),
);
}
}
This is the AddProduct i want this to send back the data and then i should be able to put in into a list.Lika a not pad
class AddProduct extends StatefulWidget {
#override
State createState() => new _AddProductState();
}
class _AddProductState extends State<AddProduct> {
List<String> names = [];
List<String> mgs = [];
//final TextEditingController eCtrl = new TextEditingController();
final nameController = TextEditingController();
final mgController = TextEditingController();
#override
Widget build (BuildContext ctxt) {
return new Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("New Drink"),
),
body: new Column(
children: <Widget>[
new TextField(
decoration: InputDecoration(
hintText: "Name",
),
controller: nameController,
),
new TextField(
decoration: InputDecoration(
hintText: "Mg",
suffixText: "Mg",
),
controller: mgController,
),
RaisedButton(
onPressed: (){
names.add(nameController.text);
mgs.add(mgController.text);
setState(() {});
nameController.clear();
mgController.clear();
Navigator.pop(context, names + mgs);
},
child: Text("ADD"),
),
],
)
);
}
}
I moved your lists to HomeScreen widget instead of main function. Your main function should just run the app
void main() {
runApp(
MaterialApp(
title: 'Returning Data',
home: HomeScreen(),
),
);
}
And I convert your HomeScreen widget to StatefulWidget insted of StatelessWidget because when you add new items and display it screen your state will change and StatelessWidget is not able to do that. It will be something like that
Navigator.push returns a future value so if you want to declare a variable with the data comes from that, you need to await for it. After you get the data you can add them into your lists but it needs to be inside setState function to update UI
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<String> names = [];
List<String> mgs = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("Project_Drink"),
),
body: Container(
child: Column(
children: <Widget>[
new Expanded(
child: ListView.builder(
itemCount: mgs.length,
itemBuilder: (context, index) {
return Text("Name: " + names[index] + " " + "Mg: " + mgs[index]);
}
),
),
],
),
),
bottomNavigationBar: BottomAppBar(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Expanded(child: Text("TOTAL : 200")),
FloatingActionButton(
onPressed: () async {
// Navigator.push returns a future value so you need to await for it
var data = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddProduct()),
);
// After you get the data from the other page you need to add them into your lists inside setState function to update UI
setState(() {
names.add(data[0]);
mgs.add(data[1]);
});
},
child: Icon(Icons.add),
),
],
),
),
),
);
}
}
I didn't change anything in your AddProduct widget.
class AddProduct extends StatefulWidget {
#override
State createState() => new _AddProductState();
}
class _AddProductState extends State<AddProduct> {
List<String> names = [];
List<String> mgs = [];
//final TextEditingController eCtrl = new TextEditingController();
final nameController = TextEditingController();
final mgController = TextEditingController();
#override
Widget build (BuildContext ctxt) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue,
title: Text("New Drink"),
),
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: "Name",
),
controller: nameController,
),
TextField(
decoration: InputDecoration(
hintText: "Mg",
suffixText: "Mg",
),
controller: mgController,
),
RaisedButton(
onPressed: (){
names.add(nameController.text);
mgs.add(mgController.text);
setState(() {});
nameController.clear();
mgController.clear();
Navigator.pop(context, names + mgs);
},
child: Text("ADD"),
),
],
)
);
}
}
Although this code should work as you want, I would suggest you to have a look at some State Management methods such as Provider, Bloc and etc. It will be more effective to create what you want to do.
try this one with simple way , when press then call this method
goToView() async {
bool data=await Navigator.push(context, new CupertinoPageRoute(builder: (BuildContext context) {
return new CoolForgot();
}));
print(data);
}
My Next View is Forgot Screen so i have used CoolForgot(), you can use as per your requirement.
then when press on back button in Next View(In my case CoolForgot()) called this
Navigator.pop(context,true);
I have pass bool value and get bool value , you can pass any type of object and get from it.

How do I make it so that all filters don't change color when tapped on flutter

I'm trying to make a template for a filter that takes in one parameter (the tag name) and gets highlighted when tapped. But the problem with this is when one filter is tapped all of them change color because they all use the same boolean value. Sorry, I'm a beginner and I think I'm going about this the wrong way
class _HomeState extends State<Home> {
bool filterTap = true;
GestureDetector filterTemplate(String tag) {
return GestureDetector(
onTap: () {
setState(() {
filterTap = !filterTap;
});
},
child: Center(
child: Container(
margin: const EdgeInsets.only(right: 20.0),
padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.all(Radius.circular(4.0)),
color: filterTap ? Colors.grey : Colors.transparent,
),
child: Text(
tag,
style: TextStyle(
color: filterTap ? Colors.grey[900] : Colors.grey,
letterSpacing: 2.0,
),
),
),
),
);
}
first of all define a StructFilter class with its properties, For example here is an option:
class StructFilter {
StructFilter(this.tag,this.filterTap);
String tag;
bool filterTap;
}
Then collect all of your filter information into a list of StructFilter(i.e List<StructFilter> filterList).
For example you can try:
Listview(
children: filterList.map((item){
return filterTemplate(item);
}).toList();
)
GestureDetector filterTemplate(StructFilter structFilter) {
return GestureDetector(
onTap: () {
setState(() {
structFilter.filterTap = !structFilter.filterTap;
});
},
),
);
}
Use List or Map or List<YourClass> to maintain status of each button.
And try ChoiceChip,
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: Home()));
}
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
Map<String, bool> tagsList = {
"Tag1": false,
"Tag2": false,
"Tag3": false,
"Tag4": false,
};
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Row(
children: tagsList.entries.map((entry) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ChoiceChip(
label: Text(entry.key),
selected: entry.value,
onSelected: (value) {
setState(() {
tagsList[entry.key] = value;
});
},
),
);
}).toList(),
),
),
);
}
}

How to fix "Content showing below Searchbar" in Flutter?

I wanted to show the result or content in Full Screen after clicking on Suggested List from the Search bar, not below the Search bar as shown in the provided Screenshot below...
Tried to follow up with the flutter boring show, but not able to understand how they achieve it 😅.
Thanks in Advance !!!
import 'package:flutter/material.dart';
import 'urls_index.dart';
import 'ContentPage.dart';
class DataSearch extends SearchDelegate<String> {
var names = new urlsindexs();
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
},
),
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {
return ContentPage();
}
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
var abc = query.isEmpty
? names.websitename
: names.websitename
.where((p) => p.toUpperCase().startsWith(query.toUpperCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context);
},
title: RichText(
text: TextSpan(
text: abc[index].substring(0, query.length),
style: TextStyle(
color: Colors.black54, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: abc[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
),
),
itemCount: abc.length,
);
}
}
Getting This : https://ibb.co/vYW4G3x
Wanted to achieve This : https://ibb.co/pzBpNPK (without searchbar)
SOLVED !
What i changed...
import 'package:flutter/material.dart';
import 'urls_index.dart';
class DataSearch extends SearchDelegate<String> {
var names = new urlsindexs();
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
},
),
];
}
#override
Widget buildLeading(BuildContext context) {
// TODO: implement buildLeading
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {
// TODO: implement buildResults
var abc = query.isEmpty
? names.websitename
: names.websitename
.where((p) => p.toUpperCase().startsWith(query.toUpperCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
showResults(context);
},
title: RichText(
text: TextSpan(
text: abc[index].substring(0, query.length),
style: TextStyle(
color: Colors.black54, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: abc[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
),
),
itemCount: abc.length,
);
}
#override
Widget buildSuggestions(BuildContext context) {
// TODO: implement buildSuggestions
var abc = query.isEmpty
? names.websitename
: names.websitename
.where((p) => p.toUpperCase().startsWith(query.toUpperCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
// showResults(context);
Navigator.of(context).pushNamed("/Store1");
},
title: RichText(
text: TextSpan(
text: abc[index].substring(0, query.length),
style: TextStyle(
color: Colors.black54, fontWeight: FontWeight.bold),
children: [
TextSpan(
text: abc[index].substring(query.length),
style: TextStyle(color: Colors.grey))
]),
),
),
itemCount: abc.length,
);
}
}

Resources