Flutter - type 'BoxDecoration' is not a subtype of type 'Widget' - flutter

FutureBuilder(
//UserData from DB
future: getUserData(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
if (snapshot.hasData) {
return new Column(
children: <Widget>[
Container(
height: 200.0,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xFF051622), Color(0xFF1BA098)],
),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(15.0),
bottomRight: Radius.circular(15.0),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(top: 18.0, left: 12.0),
child: GestureDetector(
child: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.white,
child: (_imageFile != null)
? BoxDecoration(///This is where error happens
shape: BoxShape.circle,
image: DecorationImage(
image: FileImage(_imageFile),
fit: BoxFit.fill),
)
: Icon(Icons.add_a_photo),//Replace with Image From DB
),
onTap: () {
_getImage();
},
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 75.0, top: 20.0),
child: TextField(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF1BA098),
),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFFDEB992),
),
),
hintText:
"${snapshot.data.displayName}", //Name comes from db as displayName
hintStyle: TextStyle(
color: Colors.white, fontSize: 18.0),
),
style: TextStyle(
color: Colors.white, fontSize: 18.0),
controller: newName,
),
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 12.0, left: 20.0),
child: Text(
"${snapshot.data.email}", //Email from DB as email
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.only(top: 7.0, left: 18.0),
child: Text(
"${snapshot.data.phoneNumber}", //Number from DB as phoneNumber
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(top: 10.0, left: 18.0),
child: Icon(
Icons.star_border,
size: 30.0,
color: Colors.amber,
),
),
Padding(
padding:
const EdgeInsets.only(top: 15.0, left: 2.0),
child: Text(
"0.0", //Rating from db for user
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic),
),
),
Padding(
padding: const EdgeInsets.only(
top: 8.0,
left:
200.0),
child: ArgonTimerButton(
borderRadius: 50.0,
color: Colors.greenAccent,
height: 35.0,
width: 100.0,
child: Text(
"Update",
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.w700,
color: Colors.black,
),
),
loader: (time) {
return Container(
padding: EdgeInsets.all(10.0),
child: SpinKitRing(
color: Color(0xFF1BA098),
lineWidth: 3.0,
size: 20.0,
),
);
},
onTap: (startTimer, btnState) {
startTimer(6);
verifyDetails();
},
),
),
],
),
],
),
),
],
);
}
},
),
The Whole body is on FutureBuilder(To get data from Firebase into snapShot)
And the error is
════════ Exception caught by widgets library ═══════════════════════════════════
type 'BoxDecoration' is not a subtype of type 'Widget'
The relevant error-causing widget was
FutureBuilder
lib\mainScreens\Profile.dart:37
════════════════════════════════════════════════════════════════════════════

Pranavan BoxDecoration isn't a widget wrap it by a Container as follow:
Container(
decoration: BoxDecoration( ///This is where error happens
shape: BoxShape.circle,
image: DecorationImage(
image: FileImage("_imageFile"), fit: BoxFit.fill),
),
),

Related

Flutter 'child' and 'duration' parameter aren't defined

I don't understand why in Positioned widget, I get an error that child parameter isn't defined as well as in AnimatedContainer the 'duration' parameter isn't defined.
I checked the official documentation first, but don't know why it's not working.
https://api.flutter.dev/flutter/widgets/Positioned-class.html
https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html
class _DetailsPageState extends State<DetailsPage> {
var selectedCard = 'WEIGHT';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF7A9BEE),
appBar: AppBar(
leading: IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(Icons.arrow_back_ios),
color: Colors.white,
),
backgroundColor: Colors.transparent,
elevation: 0.0,
title: Text('Details',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 18.0,
color: Colors.white)),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.more_horiz),
onPressed: () {},
color: Colors.white,
)
],
),
body: ListView(children: [
Stack(children: [
Container(
height: MediaQuery.of(context).size.height - 82.0,
width: MediaQuery.of(context).size.width,
color: Colors.transparent),
Positioned(
top: 75.0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(45.0),
topRight: Radius.circular(45.0),
),
color: Colors.white),
height: MediaQuery.of(context).size.height - 100.0,
width: MediaQuery.of(context).size.width)),
Positioned(
top: 30.0,
left: (MediaQuery.of(context).size.width / 2) - 100.0,
child: Hero(
tag: widget.heroTag,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(widget.heroTag),
fit: BoxFit.cover)),
height: 200.0,
width: 200.0))),
Positioned(
top: 250.0,
left: 25.0,
right: 25.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.foodName,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 22.0,
fontWeight: FontWeight.bold)),
SizedBox(height: 20.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(widget.foodPrice,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20.0,
color: Colors.grey)),
Container(height: 25.0, color: Colors.grey, width: 1.0),
Container(
width: 125.0,
height: 40.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(17.0),
color: Color(0xFF7A9BEE)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
onTap: () {},
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
color: Color(0xFF7A9BEE)),
child: Center(
child: Icon(
Icons.remove,
color: Colors.white,
size: 20.0,
),
),
),
),
Text('2',
style: TextStyle(
color: Colors.white,
fontFamily: 'Montserrat',
fontSize: 15.0)),
InkWell(
onTap: () {},
child: Container(
height: 25.0,
width: 25.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
color: Colors.white),
child: Center(
child: Icon(
Icons.add,
color: Color(0xFF7A9BEE),
size: 20.0,
),
),
),
)
],
),
)
],
),
SizedBox(height: 20.0),
Container(
height: 150.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
_buildInfoCard('WEIGHT', '300', 'G'),
SizedBox(width: 10.0),
_buildInfoCard('CALORIES', '267', 'CAL'),
SizedBox(width: 10.0),
_buildInfoCard('VITAMINS', 'A, B6', 'VIT'),
SizedBox(width: 10.0),
_buildInfoCard('AVAIL', 'NO', 'AV')
],
)
),
SizedBox(height: 20.0),
Padding(
padding: EdgeInsets.only(bottom:5.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10.0), topRight: Radius.circular(10.0), bottomLeft: Radius.circular(25.0), bottomRight: Radius.circular(25.0)),
color: Colors.black
),
height: 50.0,
child: Center(
child: Text(
'\$52.00',
style: TextStyle(
color: Colors.white,
fontFamily: 'Montserrat'
)
),
),
),
)
],
))
])
]));
}
Widget _buildInfoCard(String cardTitle, String info, String unit) {
return InkWell(
onTap: () {
selectCard(cardTitle);
},
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
curve: Curves.easeIn,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: cardTitle == selectedCard ? Color(0xFF7A9BEE) : Colors.white,
border: Border.all(
color: cardTitle == selectedCard ?
Colors.transparent :
Colors.grey.withOpacity(0.3),
style: BorderStyle.solid,
width: 0.75
),
),
height: 100.0,
width: 100.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 8.0, left: 15.0),
child: Text(cardTitle,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 12.0,
color:
cardTitle == selectedCard ? Colors.white : Colors.grey.withOpacity(0.7),
)),
),
Padding(
padding: const EdgeInsets.only(left: 15.0, bottom: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(info,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 14.0,
color: cardTitle == selectedCard
? Colors.white
: Colors.black,
fontWeight: FontWeight.bold)),
Text(unit,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 12.0,
color: cardTitle == selectedCard
? Colors.white
: Colors.black,
))
],
),
)
]
)
)
);
}
selectCard(cardTitle) {
setState(() {
selectedCard = cardTitle;
});
}
}
Solved, for some reason I didn't have my Flutter SDK path specified:
1.) Go to Settings
2.) Search Flutter
3.) Click Flutter under Languages & Frameworks
4.) Add you Flutter directory to path, in my case C:\flutter
5.) Apply & OK, Restart IDE

How to add circular border to dialog in flutter?

How to add circular border for dialog box in a flutter?,I tried the below code but I can't able to get the desired output, I already added circular border but it's not working, I need circular border for dialog,Refer the expected output for details, please guide
My code :
`
class CustomDialog extends StatelessWidget {
#override
Widget build(BuildContext context) {
const double padding = 1.0;
return Dialog(
backgroundColor: Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20.0))),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Container(
margin: EdgeInsets.all(1),
width: double.infinity,
child: Text('title',
style: TextStyle(fontSize: 30, color: Colors.white)),
color: Colors.green,
),
Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: ListView(
shrinkWrap: true,
children: [
Container(
margin: EdgeInsets.only(left: 10, bottom: 10),
height: 30,
child: Text('one',
style: TextStyle(
fontSize: 20,
))),
Container(
margin: EdgeInsets.only(left: 10, bottom: 10),
height: 30,
child: Text('one',
style: TextStyle(
fontSize: 20,
))),
Container(
margin: EdgeInsets.only(left: 10, bottom: 10),
height: 30,
child: Text('one',
style: TextStyle(
fontSize: 20,
))),
],
),
),
Divider(
color: Colors.white,
),
Container(
color: Colors.white,
height: 50,
padding: EdgeInsets.all(5),
alignment: Alignment.centerRight,
child: Text(
'CANCEL',
style: TextStyle(fontSize: 20),
)),
])));
}
}
`
My expectation:
current output:
Just need to add ClipBehavior to Dialog.
import 'package:flutter/material.dart';
class CustomDialog extends StatelessWidget {
#override
Widget build(BuildContext context) {
const double padding = 1.0;
return Dialog(
backgroundColor: Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
clipBehavior: Clip.antiAlias, // add clipBehavior
child: Column(mainAxisSize: MainAxisSize.min, children: [
Container(
margin: EdgeInsets.all(1),
width: double.infinity,
child: Text('title',
style: TextStyle(fontSize: 30, color: Colors.white)),
color: Colors.green,
),
Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: ListView(
shrinkWrap: true,
children: [
Container(
margin: EdgeInsets.only(left: 10, bottom: 10),
height: 30,
child: Text('one',
style: TextStyle(
fontSize: 20,
))),
Container(
margin: EdgeInsets.only(left: 10, bottom: 10),
height: 30,
child: Text('one',
style: TextStyle(
fontSize: 20,
))),
Container(
margin: EdgeInsets.only(left: 10, bottom: 10),
height: 30,
child: Text('one',
style: TextStyle(
fontSize: 20,
))),
],
),
),
Divider(
color: Colors.white,
),
Container(
color: Colors.white,
height: 50,
padding: EdgeInsets.all(5),
alignment: Alignment.centerRight,
child: Text(
'CANCEL',
style: TextStyle(fontSize: 20),
)),
]),
);
}
}
The issue was with the Container you used to wrap the other widgets, you can add specific border radius to each container to fix.
I added a demo and code to get what you wanted your output to look like:
class CustomDialog extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Container(
height: 340,
child: Column(
children: [
Container(
height: 60,
width: double.infinity,
padding: EdgeInsets.all(
15.0,
),
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(
15.0,
),
topRight: Radius.circular(
15.0,
),
),
),
child: Text(
'Baby Names',
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
...List.generate(
5,
(index) => Padding(
padding: const EdgeInsets.all(10.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'List Names',
style: TextStyle(
fontSize: 18,
),
),
),
),
),
Divider(
color: Colors.grey[200],
thickness: 1.5,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Align(
alignment: Alignment.centerRight,
child: Text(
'CANCEL',
style: TextStyle(
fontSize: 18,
color: Colors.green,
),
),
),
),
],
),
),
);
}
}
RESULT:
You added RoundedRectangleBorder(),
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MyWidget(),
),
);
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
child: Container(
padding: EdgeInsets.only(
top: 10.0,
bottom: 5,
left: 5,
right: 5,
),
margin: EdgeInsets.only(top: 5),
decoration: new BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(5),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10.0,
offset: const Offset(0.0, 10.0),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min, // To make the card compact
children: <Widget>[
Text(
"Baby",
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.w700,
),
),
Divider(color: Colors.grey,),
SizedBox(height: 16.0),
Text(
"text",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
),
),
SizedBox(height: 24.0),
Align(
alignment: Alignment.bottomRight,
child: FlatButton(
onPressed: () {
Navigator.of(context).pop(); // To close the dialog
},
child: Text("buttonText"),
),
),
],
),
),
);
}
}

Flutter fetch data from rest with reuse code

I try to reuse this codes:"https://github.com/rajayogan/flutterui-plants" and i will fetch data with a rest api.
I don't know how to.
Someone please help or explain.
Thanks by advance.
Best regards
i try to explain my problem with code:
in flutterui-plants /plantlist.dart we have this code:
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Container(
height: 350.0,
child: ListView(
padding: EdgeInsets.only(left: 25.0),
controller: _scrollController,
scrollDirection: Axis.horizontal,
children: <Widget>[
getPlantCard(
'assets/whiteplant.png', '25', 'OUTDOOR', 'Aloe Vera'),
SizedBox(width: 15.0),
getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
SizedBox(width: 15.0),
getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
SizedBox(width: 15.0),
],
),
),
Padding(
padding: EdgeInsets.only(left: 25.0, top: 10.0),
child: Text(
'Description',
style: TextStyle(
fontFamily: 'Montserrat',
color: Colors.black,
fontSize: 17.0,
fontWeight: FontWeight.w500),
),
),
Padding(
padding: EdgeInsets.only(left: 25.0, top: 10.0),
child: Text(
description,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 12.0,
),
),
)
],
);
}
getPlantCard(
String imgPath, String price, String plantType, String plantName) {
return Stack(
children: <Widget>[
Container(
height: 325.0,
width: 225.0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Color(0xFF399D63)),
height: 250.0,
width: 225.0,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Column(
children: <Widget>[
SizedBox(height: 10.0),
Text(
'FROM',
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 12.0,
fontWeight: FontWeight.w600,
color: Color(0xFF8AC7A4)),
),
Text(
'\$' + price,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20.0,
fontWeight: FontWeight.w400,
color: Colors.white),
)
],
),
SizedBox(width: 10.0)
],
),
Image(
image: AssetImage(imgPath),
height: 165.0,
),
Row(
children: <Widget>[
SizedBox(width: 25.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
plantType,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 12.0,
fontWeight: FontWeight.w600,
color: Color(0xFF8AC7A4)),
),
Text(
plantName,
style: TextStyle(
fontFamily: 'Montserrat',
fontSize: 20.0,
fontWeight: FontWeight.w600,
color: Colors.white),
)
],
),
],
),
SizedBox(height: 10.0),
Row(
children: <Widget>[
SizedBox(width: 25.0),
Container(
height: 30.0,
width: 30.0,
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFF8AC7A4),
style: BorderStyle.solid,
width: 0.5),
borderRadius: BorderRadius.circular(5.0),
color: Color(0xFF399D63)),
child: Icon(Icons.wb_sunny,
color: Colors.white.withOpacity(0.4), size: 20.0),
),
SizedBox(width: 15.0),
Container(
height: 30.0,
width: 30.0,
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFF8AC7A4),
style: BorderStyle.solid,
width: 0.5),
borderRadius: BorderRadius.circular(5.0),
color: Color(0xFF399D63)),
child: Icon(Icons.branding_watermark,
color: Colors.white.withOpacity(0.4), size: 20.0),
),
SizedBox(width: 15.0),
Container(
height: 30.0,
width: 30.0,
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFF8AC7A4),
style: BorderStyle.solid,
width: 0.5),
borderRadius: BorderRadius.circular(5.0),
color: Color(0xFF399D63)),
child: Icon(Icons.hot_tub,
color: Colors.white.withOpacity(0.4), size: 20.0),
),
SizedBox(width: 10.0),
InkWell(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => PlantDetail()
));
},
child: Container(
height: 30.0,
width: 30.0,
decoration: BoxDecoration(color: Color(0xFF399D63)),
child: Icon(Icons.help_outline,
color: Colors.white.withOpacity(0.4), size: 20.0),
),
)
],
)
],
),
),
),
Padding(
padding: EdgeInsets.only(left: 90.0, top: 300.0),
child: Container(
height: 50.0,
width: 50.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0), color: Colors.black),
child:
Center(child: Icon(Icons.shopping_cart, color: Colors.white)),
),
)
],
);
}
}
I tried to fectch data like this:
i add this code
List<Product> parseProducts(String responseBody) {
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Product>((json) =>Product.fromMap(json)).toList();
}
Future<List<Product>> fetchProducts() async {
final response = await http.get('http://192.168.1.12:8000/plants/',headers: {
"Authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1OTYxODM2NjUsImlhdCI6MTU5NjA5NzI2MCwic3ViIjoyfQ.Hz8gbT0bgaj7rNhs4SYl2I8iWxvn5sZ_liqXmHofgSE"
});
if (response.statusCode == 200) {
return parseProducts(response.body);
} else {
throw Exception('Unable to fetch products from the REST API');
}
}
and replace this block
getPlantCard(
'assets/whiteplant.png', '25', 'OUTDOOR', 'Aloe Vera'),
SizedBox(width: 15.0),
getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
SizedBox(width: 15.0),
getPlantCard('assets/smallplant.png', '25', 'INDOOR', 'Ficus'),
SizedBox(width: 15.0),
by this
FutureBuilder<List<Product>>(
future: product,
builder: (context, snapshot) {
if (snapshot.hasData) {
return getPlantCard('assets/'+snapshot.data[0].image,snapshot.data[0].price,snapshot.data[0].outorindoor,snapshot.data[0].name);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default, show a loading spinner.
return CircularProgressIndicator();
}),
its works for one result but how to have all getplant() list .
I hope i was clear this time and thanks by advance

The method 'call' was called on null. Receiver: null Tried calling: call(navegacion_bloques)

give me some of your time please, I have this error "mainMenu().onMenuTap()" and I don't know how to fix it.
The following NoSuchMethodError was thrown while handling a gesture:
The method 'call' was called on null.
Receiver: null
Tried calling: call(navegacion_bloques)
in my StatelessWidget class it worked fine, but I passed everything to a Statefulwidget and I can't use this function.
My code is this:
import 'package:flutter/material.dart';
import 'package:example/bloc/navegacion_bloques/navegacion_bloques.dart';
import 'package:example/ui/pages/productos/categorias.dart';
import 'package:example/ui/pages/productos/productdetails.dart';
class mainMenu extends StatefulWidget with NavigationStates{
final Function onMenuTap;
const mainMenu({Key key, this.onMenuTap}) : super(key: key);
#override
_mainMenu createState() => _mainMenu();
}
class _mainMenu extends State<mainMenu>
{
final categorias= allCategories;
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
physics: ClampingScrollPhysics(),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.deepPurple[300], Colors.deepPurpleAccent]
),
borderRadius:BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
topLeft: Radius.circular(20),
topRight: Radius.circular(20)),
),
padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 40),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children:[
InkWell(child: Icon(Icons.menu,color: Colors.grey[300],),
onTap:(){
mainMenu().onMenuTap();
},),
Text(
"",
style: TextStyle(
color: Colors.white,
fontSize: 22,
fontFamily: 'BalooMedium'),
),
InkWell(child: Icon(Icons.shopping_cart,color: Colors.grey[300],),
onTap:(){
mainMenu().onMenuTap();
},),
],
),
SizedBox(
height: 5,
),
Container(
padding: const EdgeInsets.only(left: 10.0,right: 10.0),
child: Column(
children: <Widget>[
Row(
children:[
Text(
"store",
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontFamily: 'BalooMedium'),
)
],
),
Row(
children:[
Text(
"hi",
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontFamily: 'BalooMedium'),
)
],
),
Row(
children:[
Text(
"There!",
style: TextStyle(
color: Colors.white,
fontSize: 15,
fontFamily: 'BalooMedium'),
)
],
)
],
),
),
SizedBox(
height: 10,
),
Padding(
padding: EdgeInsets.only(left: 10.0,right: 10.0),
child: TextField(
style: TextStyle(
fontFamily: 'BalooMedium',
fontSize: 18.0,
color: Colors.grey[200],
),
decoration: InputDecoration(
prefixIcon: IconButton(icon: Icon(Icons.search,color: Colors.grey[200],),onPressed: null,),
hintText: '¿Qué Necesitas?',
hintStyle:TextStyle(
fontFamily: 'BalooMedium',
fontSize: 18.0,
color: Colors.grey[200],
),
suffixIcon: IconButton(icon: Icon(Icons.filter_list,color: Colors.grey[200],),onPressed: null,),
),
),
),
],
),
),
);
}
buildCategoriasGrid(Categorias categorias){
return GestureDetector(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
//builder: (context) => productdetails(selectedInstructor: categorias)
));
},
child: Padding(
padding: EdgeInsets.all(5.0),
child: Stack(
children: <Widget>[
Container(
height: 150.0, width: 100.0, color: Colors.transparent),
Positioned(
left: 30.0,
top: 65.0,
child: Container(
height: 30.0,
width: 40.0,
decoration: BoxDecoration(boxShadow: [
BoxShadow(
blurRadius: 7.0,
color: Colors.grey.withOpacity(0.75),
offset: Offset(5, 25),
spreadRadius: 12.0)
]))),
Positioned(
left: 12.0,
top: 15.0,
child: Hero(
tag: categorias.productImg,
child: Container(
height: 110.0,
width: 85.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.0),
image: DecorationImage(
image: AssetImage(categorias.productImg),
fit: BoxFit.cover))))),
Positioned(
left: 22.0,
top: 138.0,
child: Column(
children: <Widget>[
Text(categorias.productName,
style: TextStyle(
fontFamily: 'BalooMedium',
fontSize: 10.0,
color: Colors.grey[200],
),),
Row(children: [
Icon(
Icons.star,
color: Colors.grey.withOpacity(0.5),
size: 15.0,
),
SizedBox(width: 3.0),
Text(categorias.productRating,
style: TextStyle(
fontFamily: 'BalooMedium',
fontSize: 10.0,
color: Colors.grey[200],
),)
])
],
))
],
)));
}
}
Replace
mainMenu().onMenuTap()
with
widget.onMenuTap()
Calling mainMenu() just creates a new instance of the mainMenu class without the corresponding information so onMenuTap() is null.
The widget property is the "State object's configuration [which] is the corresponding StatefulWidget instance." Source
So the widget property, when used in the State object, contains the information you need so onMenuTap() would contain the supplied argument.

Flutter - custom toggle buttons selection

I am building a row of toggle buttons (on/off selectors) which is basically a row of containers and each container is a category and is clickable.
Q: How to make it so in a way when one category is selected all the others get deselected?
This is the categories widget I've build:
Widget header(){
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 4.0, left: 0.0, right: 0.0, bottom: 6.0),
child: Container(
child: Center(
child: Column(
children: <Widget>[
SizedBox(height: 4.0,),
Container(
margin: EdgeInsets.only(left: 10.0, right: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
splashColor: Colors.blue[100],
onTap: (){},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.blueAccent[100],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('All',
style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 1',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 2',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 3',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 4',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
],
),
),
SizedBox(height: 6.0,)
],
),
),
),
),
],
);
}`
The best way would be to use ListView.builder to build your items and save the selected indexes but you can also modify your existing code to save selected items in a list and check to see if the item is in the list and if it is then add selection format and refresh the page. You can implement that as shown below,
class MyApp extends StatefulWidget {
#override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<String> selectedCategory = new List<String>();
String all = 'All';
String category1 = 'category 1';
String category2 = 'category 2';
String category3 = 'category 3';
String category4 = 'category 4';
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Container(
padding: const EdgeInsets.all(20.0),
child: header()
)));
}
Widget header(){
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 4.0, left: 0.0, right: 0.0, bottom: 6.0),
child: Container(
child: Center(
child: Column(
children: <Widget>[
SizedBox(height: 4.0,),
Container(
margin: EdgeInsets.only(left: 10.0, right: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
InkWell(
splashColor: Colors.blue[100],
onTap: (){
selectedCategory.add(all);
selectedCategory.add(category1);
selectedCategory.add(category2);
selectedCategory.add(category3);
selectedCategory.add(category4);
setState(() {});
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: selectedCategory.contains(all) ? Colors.blueAccent[100] : Colors.grey[500],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('All',
style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){
selectedCategory = new List<String>();
selectedCategory.add(category1);
setState(() {});
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: selectedCategory.contains(category1) ? Colors.blue[100] : Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 1',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){
selectedCategory = new List<String>();
selectedCategory.add(category2);
setState(() {});
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: selectedCategory.contains(category2) ? Colors.blue[100] : Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 2',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){
selectedCategory = new List<String>();
selectedCategory.add(category3);
setState(() {});
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: selectedCategory.contains(category3) ? Colors.blue[100] : Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 3',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
SizedBox(width: 2.0,),
InkWell(
splashColor: Colors.blue[100],
onTap: (){
selectedCategory = new List<String>();
selectedCategory.add(category4);
setState(() {});
},
child: Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: selectedCategory.contains(category4) ? Colors.blue[100] : Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('category 4',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
),
),
],
),
),
SizedBox(height: 6.0,)
],
),
),
),
),
],
);
}
}
Hope this helps.
Well, this piece of code can be optimized, but so far this worked just fine:
class Header extends StatefulWidget {
#override
_HeaderState createState() => _HeaderState();
}
class _HeaderState extends State<Header> {
List<bool> isSelected;
#override
void initState() {
isSelected = [true, false, false, false, false];
super.initState();
}
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
ToggleButtons(
borderColor: Colors.transparent,
fillColor: Colors.transparent,
borderWidth: null,
selectedBorderColor: Colors.transparent,
selectedColor: Colors.transparent,
splashColor: Colors.transparent,
children: <Widget>[
!isSelected[0] ?
Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
margin: EdgeInsets.only(right: 3.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 1',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
)
:Container(
margin: EdgeInsets.only(right: 3.0),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.blueAccent[100],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 1',
style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w700),),
),
!isSelected[1] ?
Container(
margin: EdgeInsets.only(right: 3.0),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 2',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
)
:Container(
margin: EdgeInsets.only(right: 3.0),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.blueAccent[100],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 2',
style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w700),),
),
!isSelected[2] ?
Container(
margin: EdgeInsets.only(right: 3.0),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 3',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
)
:Container(
margin: EdgeInsets.only(right: 3.0),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.blueAccent[100],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 3',
style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w700),),
),
!isSelected[3] ?
Container(
margin: EdgeInsets.only(right: 3.0),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 4',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
)
:Container(
margin: EdgeInsets.only(right: 3.0),
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.blueAccent[100],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 4',
style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w700),),
),
!isSelected[4] ?
Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 5',
style: TextStyle(color: Colors.grey[900], fontSize: 10.0, fontWeight: FontWeight.w500),),
)
:Container(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 12.0),
decoration: BoxDecoration(
color: Colors.blueAccent[100],
borderRadius: BorderRadius.all(Radius.circular(48.0)),
),
child: Text('cat 5',
style: TextStyle(color: Colors.white, fontSize: 10.0, fontWeight: FontWeight.w700),),
),
],
onPressed: (int index) {
setState(() {
for (int i = 0; i < isSelected.length; i++) {
isSelected[i] = i == index;
}
});
},
isSelected: isSelected,
),
],
);
}
}