Im creating a game board that is 4x3. The board should conist of diffrent images. At the start Im just trying to load the same image for all pieces, however I get a error message in the app it self:
"A build function returned null. The..."
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("Cat Attack"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: GridView.builder(
padding: const EdgeInsets.all(10.0),
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // 4 columns of board buttons
childAspectRatio: 1.0,
crossAxisSpacing: 9.0,
mainAxisSpacing: 9.0),
itemCount: buttonsList.length,
itemBuilder: (context, i) => new SizedBox(
width: 100.0,
height: 100.0,
child: Material(
elevation: 4.0,
color: Colors.green,
child: Ink.image(image: AssetImage('assets/animals/cat_64_blue.png')),
),
),
),
),
RaisedButton(
child: new Text(
"Reset",
style: new TextStyle(color: Colors.white, fontSize: 20.0),
),
color: Colors.red,
padding: const EdgeInsets.all(20.0),
onPressed: resetGame,
)
],
));
}
due to of Ink.image(image: AssetImage('assets/animals/cat_64_blue.png')), it will generate the null GridView builder error,
So use Image.asset('assets/animals/cat_64_blue.png'), instead of Ink.image(image: AssetImage('assets/animals/cat_64_blue.png')),
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: new Text("Cat Attack"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
child: GridView.builder(
padding: const EdgeInsets.all(10.0),
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // 4 columns of board buttons
childAspectRatio: 1.0,
crossAxisSpacing: 9.0,
mainAxisSpacing: 9.0),
itemCount: buttonsList.length,
itemBuilder: (context, i) => new SizedBox(
width: 100.0,
height: 100.0,
child: Material(
elevation: 4.0,
color: Colors.green,
child: Image.asset('assets/animals/cat_64_blue.png'),
),
),
),
),
RaisedButton(
child: new Text(
"Reset",
style: new TextStyle(color: Colors.white, fontSize: 20.0),
),
color: Colors.red,
padding: const EdgeInsets.all(20.0),
onPressed: resetGame,
)
],
));
}
There are 2 solutions for this.
I. Replace your Ink.image with Image.asset('...'))
II. Provide a child to Ink.image(), you can simply return a Container().
Ink.image(
image: AssetImage('assets/animals/cat_64_blue.png'),
child: Container(), // you need this
),
I'm trying to make a bottomsheet that has a text field and autofocus is set to true so that the keyboard pops up. But, bottomsheet is overlapped by the keyboard. Is there a way to move bottomsheet above the keyboard?
Padding(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(children: <Widget>[
TextField(
autofocus: true,
decoration: InputDecoration(hintText: 'Title'),
),
TextField(
decoration: InputDecoration(hintText: 'Details!'),
keyboardType: TextInputType.multiline,
maxLines: 4,
),
TextField(
decoration: InputDecoration(hintText: 'Additional details!'),
keyboardType: TextInputType.multiline,
maxLines: 4,
),]);
To fix this issue
All you need is to use Keyboard padding using MediaQuery.of(context).viewInsets.bottom
For more insurance, set isScrollControlled = true of the BottomSheetDialog this will allow the bottom sheet to take the full required height.
Note
If your BottomSheetModel is Column make sure you add mainAxisSize: MainAxisSize.min, otherwise the sheet will cover the whole screen.
Works with multiple TextField or TextFormField
Example
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))),
backgroundColor: Colors.black,
context: context,
isScrollControlled: true,
builder: (context) => Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Text('Enter your address',
style: TextStyles.textBody2),
),
SizedBox(
height: 8.0,
),
TextField(
decoration: InputDecoration(
hintText: 'adddrss'
),
autofocus: true,
controller: _newMediaLinkAddressController,
),
SizedBox(height: 10),
],
),
));
Please note that:
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0))),
It's not required. It's just that I'm creating a rounded bottom sheet.
UPDATED
Flutter 2.2 breaks the changes again!” Now you need to give bottom padding once again so the keyboard doesn't overlap the bottomsheet.
Just add:
isScrollControlled: true to showModalBottomSheet
padding: MediaQuery.of(context).viewInsets to widget in builder
column/wrap both works
showModalBottomSheet<void>(
isScrollControlled: true,
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0)),
),
builder: (BuildContext context) {
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
child: Wrap(
children: <Widget>[
TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter a search term'),
),
TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter a search term'),
),
TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter a search term'),
),
TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Enter a search term'),
)
],
)));
},
);
Update Feb 25 2020 better solution
showModalBottomSheet(
isScrollControlled: true,
builder: (BuildContext context) {
return SingleChildScrollView(
child: Container(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Padding(
padding: const EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 0.0), // content padding
child: Form(...)) // From with TextField inside
});
In Order to focus on the Keyboard in BottomSheet - Wrap TextField in Padding Widget as like Below e.g Code:
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: TextField(
autofocus: true,
),
),
);
});
In the latest version of flutter, you can move your bottomSheet using isScrollControlled property/named parameter. Suppose i have a function(_showModal) which will invoke when a button is pressed. And i define the bottom sheet functionality on that function.
void _showModal() {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Column(
children: <Widget>[
TextField(// your other code),
SizedBox(height: 5.0),
TextField(// your other code),
SizedBox(height: 5.0),
TextField(// your other code),
]
);
},
);
}
Here a ModalBottomSheet will appear but with fullscreen of height. And you don't need that height. So, you need to Column's mainAxisSize to min.
Column(
mainAxisSize: MainAxisSize.min,
// your other code
)
Fullscreen of height problem is solved, but ModalBottomSheet doesn't move to top when keyboard is appeared. Ok, to solve this issue you need to set viewInsets bottom padding to your ModalBottomSheet. So to set padding we need to wrap our Column with Container or Padding and then set the padding. The final code will look like this
void _showModal() {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
// You can wrap this Column with Padding of 8.0 for better design
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(// your other code),
SizedBox(height: 5.0),
TextField(// your other code),
SizedBox(height: 5.0),
TextField(// your other code),
]
),
);
},
);
}
Hope your issue is fixed. Thank's 🙏
Package: https://pub.dev/packages/modal_bottom_sheet
Wrap your widget into Padding and set padding like this ==>
padding: MediaQuery.of(context).viewInsets // viewInsets will decorate your screen
You can use
showMaterialModalBottomSheet or showModalBottomSheet or showCupertinoModalBottomSheet
showModalBottomSheet(
context: context,
barrierColor: popupBackground,
isScrollControlled: true, // only work on showModalBottomSheet function
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(borderRadiusMedium),
topRight: Radius.circular(borderRadiusMedium))),
builder: (context) => Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
height: 400, //height or you can use Get.width-100 to set height
child: <Your Widget here>
),)),)
Try this
My Solution is
Use isScrollControlled: true
Add Padding
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom)
Wrap your layout in SingleChildScrollView
SAMPLE CODE
Future<void> future = showModalBottomSheet(
context: context,
isDismissible: true,
isScrollControlled: true,
backgroundColor: Colors.white.withOpacity(0.2),
builder: (context) => SingleChildScrollView(
child: GestureDetector(
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom
),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
// add your widget here
],
),
),
)
),
)
);
I got it fixed by increasing the height of the child widget when the keyboard gets opened.
initially value of MediaQuery.of(context).viewInsets.bottom will be 0 it will change when the keyboard gets focused.
showModalBottomSheet<void>(
enableDrag: true,
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Card(
color: Colors.white,
child: Container(
height: MediaQuery.of(context).size.height / 2 +
MediaQuery.of(context).viewInsets.bottom,
child: Column(
children: <Widget>[
TextField(),
TextField(),
],
),
),
);
},
);
UPDATED 2021 May flutter 2.2!
Now you need to give bottom padding. The below written was a bug.
UPDATED 2020!
This answer is true, but you don't have to give bottom padding now!
Find and delete this line:
padding: MediaQuery.of(context).viewInsets
For people who can't solve their problem trying all the answers. These answers are correct but not so clear.
When using
MediaQuery.of(context).viewInsets.bottom)
make sure your context variable is using the one provided by bottom sheet builder property.
builder :(**c**)=>MediaQuery.of(**c**)
Try this.
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return AnimatedPadding(
padding: MediaQuery.of(context).viewInsets,
duration: const Duration(milliseconds: 100),
curve: Curves.decelerate,
child: Container(
child: Wrap(
children: [
TextField(
decoration: InputDecoration(labelText: "1"),
),
TextField(
decoration: InputDecoration(labelText: "2"),
),
TextField(
decoration: InputDecoration(labelText: "3"),
),
],
)));
},
)
Add this after the last widget of your bottom sheet
Padding(padding: EdgeInsets.only(bottom:MediaQuery.of(context).viewInsets.bottom))
You should to use this then,
showModalBottomSheet(
isScrollControlled: true,
context: context,
shape: RoundedRectangleBorder(
// <-- for border radius
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
),
builder: (BuildContext context) {
return SingleChildScrollView(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: drunkenWidget()...
//BTW, Never ever Drink
If you have full screen or fixed size showModalBottomSheet don't use padding it will not solve your problem. Use margin instead of padding like this :
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
marign: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: TextField()
);
});
Instead of using builder: (BuildContext context) { } in the builder, use builder: (context) { }
With this solution my modal bottom sheet sticks to the statusbar (acts like Scaffold with resizeToAvoidBottomInset: false) and allows to view all the form fields and scroll through the form if it is still needed to view bottom text fields.
For more details, here's the link from where I found the solution- https://github.com/flutter/flutter/issues/18564#issuecomment-602604778
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
context: context,
isScrollControlled: true,
builder: (builder) {
return Container(
height: MediaQuery.of(context).size.height - 40,
padding: MediaQuery.of(context).viewInsets,
child: <Your Widget Here>,
);
},
);
After combining different solutions I got this:
if you don't want it to be Full screen and don't want to use the Padding workaround use
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
enableDrag: true,
isDismissible: true,
useRootNavigator: true,
builder: (BuildContext ctx) {
return Scaffold( // use CupertinoPageScaffold for iOS
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: true, // important
body: SingleChildScrollView(
child: Form(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormField(),
TextFormField(),
],
),
),
),
),
);
},
);
on Flutter (Channel master, v1.15.3-pre.37, on Mac OS X 10.15.2 19C57, locale en-US)
Fount this on github
Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: TextField()
)
If you still have not found your issue. So I think you have missed in your BuilderContext. Sometimes when you implement modalBottomSheet it will give you only the context parameter. So add context with BuildContext.
builder: (BuildContext context) { //-Here is your issue add BuilderContext class name as it as
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: new Container(
Wrap the Form with a Scaffold widget, and then wrap the TextFormField with a SingleChildScrollView :
return Container(
height: screenHeight * .66,
child: Scaffold(
body: Form(
key: _form,
child: SingleChildScrollView(
child:TextFormField()
)
)
)
)
showModalBottomSheet(
isScrollControlled: true,
builder: (BuildContext context) {
return SingleChildScrollView(
child: Container(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Padding(
padding: const EdgeInsets.all(15.0), // content padding
child: Container())});
Note : This line does all the magic
Add this in your router link modal bottom sheet
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (BuildContext context) {
return Messagescr();
}
);
And remove this line also in your Scaffold :
resizeToAvoidBottomInset : false,
Simple Solution, you can customize this :
Container(
margin: EdgeInsets.only(left: 15),
child: InkWell(
onTap: () {
showModalBottomSheet(
isScrollControlled : true,
context: context,
backgroundColor: Colors.transparent,
builder: (context) {
return Container(
padding: EdgeInsets.only(top: 15, left: 15, right: 15, bottom: 10),
width: double.infinity,
decoration: BoxDecoration(
color: AppTheme.leadItemColor1,
borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)),
),
child: Column(
children: [
_assignTo(widget.viewModel, context),
SizedBox(height: 12,),
txtComment(widget.viewModel),
SizedBox(height: 12,),
CRMButton(
title: 'Select',
onTap: () async {
Navigator.pop(context);
await widget.viewModel.updateStatus(7, why: "${ConstantData.lostOptions[_selectedNumber]}");
},
)
],
),
);
},
);
},
child: CustomTabBarItem1(
image: widget.viewModel.leadDetail.success.lStatus == 7 ? 'assets/appimages/LeadDetail/icons-03-01.png' : 'assets/appimages/LeadDetail/icons-04-01.png',
bottomTitle: 'Lost',
topTitle: widget.viewModel.leadDetail.success.lStatus > 7 ? 'assets/appimages/LeadDetail/Ellipse 61#2x.png' : widget.viewModel.leadDetail.success.lStatus == 7 ? 'assets/appimages/LeadDetail/Group 486-1.png' : 'assets/appimages/LeadDetail/Ellipse-61#3x.png',
height : widget.viewModel.leadDetail.success.lStatus == 7 ? "0" : "1",
)),
),
import 'dart:async';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import '../weight/boostrap/flutter_bootstrap.dart';
import '../weight/boostrap/bootstrap_widgets.dart';
/*
TextEditingController txtname = TextEditingController();
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
builder: (context) => SingleChildScrollView(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom),
child: new AddItem(
tektk: 'Category',
tektd: 'Add',
txtname: txtname,
ismultik:false,
onPressed: () {}),
),
);
*/
class AddItem extends StatelessWidget {
const AddItem(
{Key? key,
required this.ismultik,
required this.tektd,
required this.tektk,
required this.txtname,
required this.onPressed})
: super(key: key);
final bool ismultik;
final String tektk;
final String tektd;
final VoidCallback? onPressed;
final TextEditingController txtname;
#override
Widget build(BuildContext context) {
final MediaQueryData mediaQueryData = MediaQuery.of(context);
bootstrapGridParameters(gutterSize: 10);
return Padding(
padding: mediaQueryData.viewInsets,
child: Container(
padding: EdgeInsets.only(bottom: 90.0, left: 10.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ListTile(
trailing: SizedBox.fromSize(
size: Size(35, 35),
child: ClipOval(
child: Material(
color: Colors.indigo,
child: InkWell(
splashColor: Colors.white,
onTap: () {
Navigator.pop(context);
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.close, color: Colors.white),
],
),
),
),
),
),
),
BootstrapRow(height: 0, children: [
BootstrapCol(
sizes: 'col-md-12',
child: TextField(
style: TextStyle(color: Colors.black),
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderSide: new BorderSide(color: Colors.white)),
labelText: tektk,
),
keyboardType: ismultik == true
? TextInputType.multiline
: TextInputType.text,
maxLines: null,
minLines: 1,
controller: txtname,
),
),
BootstrapCol(
sizes: 'col-md-12',
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green, // background
onPrimary: Colors.white, // foreground
),
onPressed: onPressed,
child: Text(tektd)),
),
]),
],
),
),
);
}
}
Just add
if (_isEditing) SizedBox(height: MediaQuery.of(context).viewInsets.bottom),
under the keyboard and hide all other content below the textfield with
if (!_isEditing) Widget(...),
How to solve the scrolling issue in flutter layout when adding gridview inside listview. in android studio java we use NestedScrollView to solve this type of issue What is the solution for flutter?
I need to scrolling continues with out any problem with listview with custom view and gridview.Now then gridview is only allowing to scroll gridview if i scroll grid view then top imageview is not scrolling .How to solve this issue?
body:
ListView(
children: <Widget>[
new Image.network("https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg"),
Container(
height: 300.0,
child: GridView.count(
crossAxisCount: 3,
childAspectRatio: .6,
children: _list.map((p) => ProductManagment(p)).toList(),
),
)
],
)
After adding #deniss answer
SOLVED
Instead of use ListView you should use Column Widget Like below.
body:
Column(
children: <Widget>[
Container (
height: 150.0, // Set as you want
child: Image.network("https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg")),
Container(
height: 300.0,
child: GridView.count(
crossAxisCount: 3,
childAspectRatio: .6,
children: _list.map((p) => ProductManagment(p)).toList(),
),
)
],
)
Because of `GridView` itself has scroll effect.
EDITED:
Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
Container(
height: 200,
child: Image.network(
"https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg"),
),
ConstrainedBox(
constraints: BoxConstraints(
minHeight: 80, // Set as you want or you can remove it also.
maxHeight: double.infinity,
),
child: Container(
child: GridView.count(
crossAxisCount: 3,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: NeverScrollableScrollPhysics(),
childAspectRatio: .6,
children: _list.map((p) => ProductManagment(p)).toList(),
),
),
)
],
),
],
),
));
You have to use ConstrainedBox with set maxHeight: double.infinity and GridView.count set shrinkWrap: true,. and remove container height 300.
Also if you want to change
Container(
height: 200,
child: Image.network(
"https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg"),
),
To Just
Image.network("https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg")
Than you can change it.
I had the same issue. However, I did not want the issue of Overflowed by... that comes with a Column/Row and instead added physics: ScrollPhysics() to my GridView.count to resolve this issue. Found my answer from this response to a similar issue.
use this
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 2.0,
mainAxisSpacing: 2.0,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: NeverScrollableScrollPhysics(),
children: List.generate(choices.length, (index) {
return Center(
child: new Column(
children: [
new Expanded(
child: SelectCard(choice: choices[index]),
),
],
),
);
}),
));
and full code for better explanation
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
var url = "https://miro.medium.com/max/2160/1*9JzKFil-Xsip742fdxDqZw.jpeg";
class Dashboard extends StatefulWidget {
_Dashboard createState() => _Dashboard();
}
Widget _buildAvatar(BuildContext context, Orientation orientation) {
return Container(
height: 300.0,
color: Colors.blue,
child: Center(
child: CircleAvatar(
backgroundColor: Colors.white,
child: Text('RR'),
),
),
);
}
Widget _buildFields(BuildContext context) {
return Container(
color: Colors.white,
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 2.0,
mainAxisSpacing: 2.0,
shrinkWrap: true,
scrollDirection: Axis.vertical,
physics: NeverScrollableScrollPhysics(),
children: List.generate(choices.length, (index) {
return Center(
child: new Column(
children: [
new Expanded(
child: SelectCard(choice: choices[index]),
),
],
),
);
}),
));
}
class _Dashboard extends State<Dashboard> {
#override
Widget build(BuildContext context) {
return OrientationBuilder(builder: (context, orientation) {
return ListView(
children: <Widget>[
Container(
height: 200,
child: Image.network(
"https://www.gizbot.com/img/2013/11/23-weekend-deals-top-10-latest-smartphones.jpg"),
),
_buildFields(context),
],
);
});
}
}
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'Home', icon: Icons.home),
const Choice(title: 'Contact', icon: Icons.contacts),
const Choice(title: 'Map', icon: Icons.map),
const Choice(title: 'Phone', icon: Icons.phone),
const Choice(title: 'Camera', icon: Icons.camera_alt),
const Choice(title: 'Setting', icon: Icons.settings),
const Choice(title: 'Album', icon: Icons.photo_album),
const Choice(title: 'WiFi', icon: Icons.wifi),
];
class SelectCard extends StatelessWidget {
const SelectCard({Key key, this.choice}) : super(key: key);
final Choice choice;
#override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.display1;
return Container(
child: GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: 1,
),
itemBuilder: (contxt, indx) {
return Card(
elevation: 4,
margin: EdgeInsets.all(8),
color: Colors.white70,
child: Padding(
padding: const EdgeInsets.only(top: 25),
child: Container(
width: 4,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
new Expanded(
child: new Container(
child: new Icon(
choice.icon,
color: Colors.black,
size: 50.0,
),
),
flex: 2,
),
new Expanded(
child: new Container(
margin: EdgeInsets.only(top: 12),
child: new Text(
choice.title,
style:
TextStyle(fontSize: 16, color: Colors.black),
)),
flex: 1,
),
]),
),
),
);
},
),
);
}
}
I am trying with the following code
class NewItemCreate extends StatefulWidget{
#override
NewItemCreateState createState() => new NewItemCreateState();
}
class NewItemCreateState extends State<NewItemCreate>
{
File _image;
Future getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image = image;
});
print(_image.path);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.yellow,
appBar: new AppBar(
title: new Text("Report"),
elevation: 5.0,
),
body:
Center (
child: ListView(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
shrinkWrap: true,
children: <Widget>[
itemImage,
SizedBox(height: 18.0),
itemName,
SizedBox(height: 18.0),
itemLocation,
SizedBox(height: 18.0),
itemLocation,
SizedBox(height: 18.0),
itemTime,
SizedBox(height: 18.0),
Report,
SizedBox(height: 38.0),
],
)
)
);
}
final itemImage = Padding(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 300.0,
onPressed: (){
getImage();
},
color: Colors.lightGreenAccent,
child:
new Icon(Icons.add_a_photo, size: 150.0,color: Colors.blue,),
),
),
);
There is already a question here,
Error: Only static members can be accessed in initializers what does this mean?
regarding this very issue, but, should I really be using "SingleTickerProviderStateMixin" for this? Also, is this something to do with singletons? (I am still learning programming)
Error after trying out the below answer:
final itemImage = ...
initializes a class-level field. This code is executed before the constructor is completed and the object fully initialized, therefore accessing this. (implicit or explicit) is forbidden because it can't be guaranteed that what you attempt to access is already initialized.
Creating and caching widgets this way is a bad idea in general anyway.
Instead make it a method:
Widget buildItemImage(BuildContext context) => Padding(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 300.0,
onPressed: () {
getImage();
},
color: Colors.lightGreenAccent,
child: new Icon(Icons.add_a_photo, size: 150.0,color: Colors.blue,
),
),
),
);
This way the code is first executed when buildItemImage(context) is called, not when the object instance is created. At this time it is guaranteed to be save to access this..
Try to cut the
Padding(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 300.0,
onPressed: (){
getImage();
},
color: Colors.lightGreenAccent,
child:
new Icon(Icons.add_a_photo, size: 150.0,color: Colors.blue,),
),
),
);
And paste it in children<Widget>[//here] and add a new
body:
Center (
child: ListView(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
shrinkWrap: true,
children: <Widget>[
------------/*there it is*/---------------------------
new Padding(
padding: EdgeInsets.symmetric(vertical: 25.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 300.0,
onPressed: (){
getImage();
},
color: Colors.lightGreenAccent,
child:
new Icon(Icons.add_a_photo, size: 150.0,color:
Colors.blue,),
),
),
-----------------------------------------------------
SizedBox(height: 18.0),
itemName,
SizedBox(height: 18.0),
itemLocation,
SizedBox(height: 18.0),
itemLocation,
SizedBox(height: 18.0),
itemTime,
SizedBox(height: 18.0),
Report,
SizedBox(height: 38.0),
],
)
)
Hope it's work :)