Inkwell for dummies - animation

(...and with dummies I mean myself)
what am I doing wrong here?
I don't see any animation,
I tried to change the order of container/inkwell
because I saw somewhere that it creates some issue,
but I'm stuck. Can anyone help?
class CardButton extends StatelessWidget {
final String input;
CardButton({this.input});
Widget build(BuildContext context) {
return Container(
color: Colors.grey[100],
width: 50.0,
height: 50.0,
alignment: Alignment.center,
child: Material(
child: InkWell(
splashColor: Colors.amber,
onTap: draw(),
child: Text(input),
),
),
);
}
}
draw() {
//todo
}
thanks in advance
[edit 25/10]
I tried out some of the solutions proposed,
but doing so the widget where this one is 'nested' throw me an error,
writing the widget where I use the "CardButton" below:
class CardGrid extends StatelessWidget {
final List<String> cardList = [
'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
#override
Widget build(BuildContext context) {
return Container(
width: 300.0,
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CardButton(input: cardList[0]),
CardButton(input: cardList[1]),
CardButton(input: cardList[2])
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CardButton(input: cardList[3]),
CardButton(input: cardList[4]),
CardButton(input: cardList[5])
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CardButton(input: cardList[6]),
CardButton(input: cardList[7]),
CardButton(input: cardList[8])
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CardButton(input: cardList[9]),
CardButton(input: cardList[10]),
CardButton(input: cardList[11]),
CardButton(input: cardList[12])
],
),
],
),
);
}
}
I'm adding here the screenshot of the app, the first is with my original code,
the second (with the error) is with the "proposed" solution

You need to pass the onTap function without the braces:
child: InkWell(
splashColor: Colors.amber,
onTap: draw, // don't use braces here (except your function returns
// a reference to the actual onTap function.
child: Text(input),
),
Note that with the current layout only the inner Text element is animated. If you want the InkWell to cover the entire button area you'll have to reorder the widget tree to:
Material > InkWell > Container > Text
Widget build(BuildContext context) {
return Material(
color: Colors.grey[100],
child: InkWell(
splashColor: Colors.amber,
onTap: draw,
child: Container(
width: 100.0,
height: 100.0,
alignment: Alignment.center,
child: Text(input),
),
),
);
}

Related

How to create a custom dialogue with image parameter in flutter

I'm trying to create a custom dialogue box, where i'm passing title, text and image parameter, when i call the dialogue box, it is not display image, here is the code
this is the code of Dialogue box.
class LoginSucessDailog extends StatefulWidget {
final String title, text;
final Image img;
const LoginSucessDailog({ required this.title, required this.text,required this.img });
#override
_LoginSucessDailogState createState() => _LoginSucessDailogState();
}
class _LoginSucessDailogState extends State<LoginSucessDailog> {
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(Constants.padding),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: contentBox(context),
);
}
contentBox(context) {
return Stack(
children: <Widget>[
Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Image.asset(
widget.img.toString(),
width: 100,
),
Text(
widget.title,
style:GoogleFonts.montserrat(fontSize: 22, fontWeight: FontWeight.w600),
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(
color: Colors.black,
),
children: <TextSpan>[
TextSpan(
text:widget.text,
style: GoogleFonts.montserrat(fontSize: 16, color: Colors.grey)),
],
),
),
),
SizedBox50(),
okay()
],
),
),
],
);
}
}
and here i'm calling it as like this
showDialog(
context: context,
builder: (BuildContext context) {
return LoginSucessDailog( text: 'Phone number doesnt exists!',
title: 'Error',
img:Image.asset("assets/img/alert.png"));
});
but it send me this error
Unable to load asset: Image(image: AssetImage(bundle: null, name: "assets/img/alert.png"), frameBuilder: null, loadingBuilder: null, alignment: Alignment.center, this.excludeFromSemantics: false, filterQuality: low)
widget.img.toString(), if i'm not converting it into string then it gives me this error
The argument type 'Image' can't be assigned to the parameter type 'String'.
please help how to solve it .
I changed the passed value and adapt the constructor dialog.
showDialog(
context: context,
builder: (BuildContext context) {
return LoginSucessDailog( text: 'Phone number doesnt exists!',
title: 'Error',
img:'assets/img/alert.png');
});
class LoginSucessDailog extends StatefulWidget {
final String title, text, img;
const LoginSucessDailog({ required this.title, required this.text,required this.img });
#override
_LoginSucessDailogState createState() => _LoginSucessDailogState();
}
class _LoginSucessDailogState extends State<LoginSucessDailog> {
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(Constants.padding),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: contentBox(context),
);
}
contentBox(context) {
return Stack(
children: <Widget>[
Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Image.asset(
widget.img,
width: 100,
),
Text(
widget.title,
style:GoogleFonts.montserrat(fontSize: 22, fontWeight: FontWeight.w600),
),
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
style: TextStyle(
color: Colors.black,
),
children: <TextSpan>[
TextSpan(
text:widget.text,
style: GoogleFonts.montserrat(fontSize: 16, color: Colors.grey)),
],
),
),
),
SizedBox50(),
okay()
],
),
),
],
);
}
}

How to display array of image from firestore in listview flutter?

I want to display of image in listview which read data from firestore. I declare attribure image as array type.Here is my collection.
When i run the code, the image only display the first index of array and the second will read the first index of array like this. supposedly the second slide of image, it will display the second index of array from firestore.
Here is my code.
import 'package:carousel_pro/carousel_pro.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:fyp/shared/Loading.dart';
import 'package:google_fonts/google_fonts.dart';
class ListTask extends StatefulWidget {
#override
_ListTaskState createState() => _ListTaskState();
}
final FirebaseAuth auth = FirebaseAuth.instance;
Stream<QuerySnapshot> getUserRd(BuildContext context) async* {
final FirebaseUser rd = await auth.currentUser();
yield* Firestore.instance.collection("Task").where('uid',isEqualTo: rd.uid).snapshots();
}
class _ListTaskState extends State<ListTask> {
List<NetworkImage> _listOfImages = <NetworkImage>[];
#override
Widget build(BuildContext context) {
return Container(
child: StreamBuilder(
stream: getUserRd(context),
builder: (context, snapshot){
if (snapshot.hasError || !snapshot.hasData) {
return Loading();
} else{
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index){
DocumentSnapshot ba = snapshot.data.documents[index];
_listOfImages =[];
for(int i =0; i < snapshot.data.documents[index].data['url'].length; i++){
_listOfImages.add(NetworkImage(snapshot.data.documents[index].data['url'][i]));
}
return Card(
child:ListTile(
title: Container(
alignment: Alignment.centerLeft,
child: Column(
children: <Widget>[
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Row(
children: [
Text("Sumber Aduan: ", style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
Text(ba['sumberAduan'], style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
],
),
),
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Row(
children: [
Text("Nombor Aduan: ", style: GoogleFonts.lato(fontWeight: FontWeight.bold)),
Text(ba['noAduan'], style: GoogleFonts.lato(fontWeight: FontWeight.bold)),
],
),
),
SizedBox(height: 5.0),
Container(alignment: Alignment.centerLeft,
child: Row(
children: [
Text("Status: ", style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
Text(ba['verified'], style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
],
),
),
Column(
children: [
Container(
margin: EdgeInsets.all(10.0),
height: 200,
decoration: BoxDecoration(
color: Colors.white
),
width: MediaQuery.of(context).size.width,
child: Carousel(
boxFit: BoxFit.cover,
images: _listOfImages,
autoplay: false,
indicatorBgPadding: 5.0,
dotPosition: DotPosition.bottomCenter,
animationCurve: Curves.fastLinearToSlowEaseIn,
animationDuration: Duration(milliseconds: 2000),
),
)
],
)
],
),
),
onTap: () {listAddress(ba['id']);}
)
);
});
}
}),
);
}
void listAddress(String id) {
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(10.0),
topRight: const Radius.circular(10.0)
)
),
context: context,
builder: (builder){
return StreamBuilder(
stream:Firestore.instance.collection("Task").document(id).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Loading();
} else {
return Container(
height: 150,
child: Container(
padding: EdgeInsets.fromLTRB(20.0, 3, 30.0, 5.0),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Align(
alignment: Alignment.topLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
alignment: Alignment.topLeft,
width: 220,
margin: EdgeInsets.only(top:26, left: 14),
child: Row(
children: [
Text("Kawasan: ", textAlign: TextAlign.left,style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
Text( snapshot.data['kawasan'], textAlign: TextAlign.left,style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
],
),
),
Container(
width: 220,
margin: EdgeInsets.only(top:4, left: 15),
child: Row(
children: [
Text("Nama Jalan :", textAlign: TextAlign.left,style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
Text(snapshot.data['naJalan'], textAlign: TextAlign.left,style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
],
),
),
Container(
width: 220,
margin: EdgeInsets.only(top:4, left: 15),
child: Row(
children: [
Text("Kategori : ", textAlign: TextAlign.left,style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
Text(snapshot.data['kategori'], textAlign: TextAlign.left,style: GoogleFonts.asap(fontWeight: FontWeight.bold)),
],
),
),
],
),
)
],
),
],
),
),
);
}
}
);
}
);
}
}
can someone explain to me about this problem? is there anything that I missed out? someone help me please?
The code is correct. You have exactly the same links in your list url, that's why you're getting the same picture.

Error when insert Textfield into column Flutter

This is my code
SafeArea(
child: Scaffold(
body: Container(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
Flexible(
child: Container(
width: 100,
child:
TextFormField(decoration: const InputDecoration()),
),
)
],
),
Column(
children: <Widget>[
Flexible(
child: Container(
width: 100,
child:
TextFormField(decoration: const InputDecoration()),
),
)
],
),
Column(
children: <Widget>[
Flexible(
child: Container(
width: 100,
child:
TextFormField(decoration: const InputDecoration()),
),
)
],
)
],
)
],
),
),
),
);
But when I run that code it shows error like following
═══════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderFlex#1b387 relayoutBoundary=up3 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'
The relevant error-causing widget was
Row
lib\GPA1.dart:24
════════════════════════════════════════════════════════════════════════════════
I can't build my project. Can anyone help me??
I used flutter 1.17.0
I use my mobile device to preview this
I use Samsung Galaxy A5 2016
I use Flexible to wrap TextFormField but it shows the same error again.
You need to wrap Row Widget with Expanded widget.
SafeArea(
child: Scaffold(
body: Container(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[],
),
Expanded( // added
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
Flexible(
child: Container(
width: 100,
child: TextFormField(
decoration: const InputDecoration()),
),
)
],
),
Column(
children: <Widget>[
Flexible(
child: Container(
width: 100,
child: TextFormField(
decoration: const InputDecoration()),
),
)
],
),
Column(
children: <Widget>[
Flexible(
child: Container(
width: 100,
child: TextFormField(
decoration: const InputDecoration()),
),
)
],
)
],
),
)
],
),
),
));
I think you should get rid of the "Flexible".
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Column(
children: <Widget>[
Container(
width: 100,
child: TextFormField(decoration: const InputDecoration()),
),
],
),
Column(
children: <Widget>[
Container(
width: 100,
child: TextFormField(decoration: const InputDecoration()),
),
],
),
Column(
children: <Widget>[
Container(
width: 100,
child: TextFormField(decoration: const InputDecoration()),
),
],
),
],
),
This code will do the job.
SafeArea(
child: Scaffold(
body: Container(
margin: EdgeInsets.all(5),
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: EdgeInsets.only(
left: 5, right: 5),
child: TextFormField(
decoration:
const InputDecoration()))),
Expanded(
child: Padding(
padding: EdgeInsets.only(
left: 5, right: 5),
child: TextFormField(
decoration:
const InputDecoration()))),
Expanded(
child: Padding(
padding: EdgeInsets.only(
left: 5, right: 5),
child: TextFormField(
decoration:
const InputDecoration())))
],
),
],
),
),
));
Result

Flutter FormBuilder Dropdown validation is not working

Here, I am trying flutter_form_builder for the dropdown. but there is some problem when I check the validation of all fields while button clicks on the Next button. it will check the form state is valid or not. if I click on the next button it will show all the required filed it will show me dropdown also but id I am not the select value from drop-down then it needs do not redirect any other page without selecting dropdown value because there is required validation. so the issue is drop-down validation is showing but not working.
Here is code of my screen :
class _AddWalkinServiceScheduleScreenState
extends State<AddWalkinServiceScheduleScreen>
with TickerProviderStateMixin {
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
AddWalkinModel model;
bool autovalidate = false;
final TextEditingController _bspBusinessLegalAddress =
TextEditingController();
LocationResult _pickedLocation;
Map<String, dynamic> _typeValue;
AnimationController controller;
Animation<double> animation;
final TextEditingController _serviceDate = TextEditingController();
TextEditingController _serviceTime = new TextEditingController();
String _isoDate;
String addresschoice;
List<String> _imageFilesList2 = [];
List<File> _licenseImages2 = [];
bool _isFlexible = false;
String _serviceType;
List<dynamic> _type = <dynamic>[];
#override
void initState() {
super.initState();
}
Widget _builddate() {
return Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 11),
child: Text(
"Date",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
_buildservicedate(),
],
),
);
}
Widget _buildselectAddress() {
return Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 11),
child: Text(
"Select Address",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
_buildaddresschoice(),
addresschoice == "Current Location"
? _addressTextfield()
: (addresschoice == "Select from address book" ||
model.address != null)
? _addressTextfield()
: SizedBox(),
_buildServicetype()
],
),
);
}
Widget _addressTextfield() {
return TudoTextWidget(
prefixIcon: Icon(FontAwesomeIcons.mapMarkedAlt),
labelText: "Address",
hintText: "Address",
controller: _bspBusinessLegalAddress,
validator: (val) =>
Validators.validateRequired(val, "Address"),
);
}
Widget _buildServicetype() {
return FormBuilder(
autovalidate: autovalidate,
child: FormBuilderCustomField(
attribute: "Select Address",
validators: [FormBuilderValidators.required()],
formField: FormField(
builder: (FormFieldState<dynamic> field) {
return InputDecorator(
decoration: InputDecoration(
prefixIcon: Icon(Icons.business_center),
errorText: field.errorText,
),
isEmpty: _typeValue == [],
child: new DropdownButtonHideUnderline(
child: DropdownButton(
hint: Text("Service Type"),
isExpanded: true,
items: [
"Normal",
"Urgent",
"Emergency",
].map((option) {
return DropdownMenuItem(
child: Text("$option"),
value: option,
);
}).toList(),
value: field.value,
onChanged: (value) {
field.didChange(value);
_serviceType = value;
},
),
),
);
},
)),
);
}
Widget content(BuildContext context, AddWalkinServiceDetailViewModel awsdVm) {
var colorStyles = Theming.colorstyle(context);
Orientation orientation = MediaQuery.of(context).orientation;
return Scaffold(
backgroundColor: colorStyles['primary'],
appBar: AppBar(
elevation: 0,
title: Text("Service Details"),
centerTitle: true,
),
bottomNavigationBar: Container(
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new FlatButton.icon(
icon: Icon(FontAwesomeIcons.arrowCircleRight),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 30),
label: Text('Search'),
color: colorStyles["primary"],
textColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(7),
),
onPressed: () {
setState(() {
autovalidate = true;
});
if (_formkey.currentState.validate()) {
List<ServicePicture> id1Images = [];
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ServiceProviderMapScreen(
addWalkinModel: model,
),
),
);
}
}
),
],
),
),
body: FadeTransition(
opacity: animation,
child: Container(
child: Form(
autovalidate: autovalidate,
key: _formkey,
child: Stack(
children: <Widget>[
SingleChildScrollView(
padding: EdgeInsets.all(16.0),
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_builddate(),
_buildflexible(),
],
),
),
)
],
),
),
),
),
);
}
#override
Widget build(BuildContext context) {
return new StoreConnector<AppState, AddWalkinServiceDetailViewModel>(
converter: (Store<AppState> store) =>
AddWalkinServiceDetailViewModel.fromStore(store),
builder: (BuildContext context, AddWalkinServiceDetailViewModel awsdVm) =>
content(context, awsdVm),
);
}
}
You should be using FormBuilderDropdown instead. This is included in flutter_form_builder.
DropdownButtonHideUnderline(
child: FormBuilderDropdown(
name: 'dropdown'
hint: Text("Service Type"),
isExpanded: true,
items: [
"Normal",
"Urgent",
"Emergency",
].map((option) {
return DropdownMenuItem(
child: Text("$option"),
value: option,
);
}).toList(),,
),
),
Using this, the dropdown value can be extracted by calling it from the Map GlobalKey<FormState>.currentState.value using the name set earlier as the key.
_formKey.currentState.value['dropdown']

How do I make my gridView scroll take up the whole page in Flutter?

I have a gridView which on scrolling must take up the whole page. It currently only scrolls in the bottom half of the page and looks like shown below.
When I scroll the Grid View containing the elements only the bottom part of the page is scrolling
#override
Widget build(BuildContext context) {
return Material(
child: Container(
color: DesignCourseAppTheme.nearlyWhite,
child: PageView(
scrollDirection: Axis.vertical,
children: [
Scaffold(
backgroundColor: DesignCourseAppTheme.nearlyWhite,
body: Container(
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).padding.top,
),
getAppBarUI(),
Expanded(
child: Container(
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
getCategoryUI(),
Flexible(
child: getPopularCourseUI(),
),
],
),
),
),
],
),
),
),
],
),
),
);
}
Here the gridView is called as:
Widget getPopularCourseUI() {
return Padding(
padding: const EdgeInsets.only(top: 8.0, left: 18, right: 16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Featured Games',
textAlign: TextAlign.left,
style: TextStyle(
fontFamily: "Netflix",
fontWeight: FontWeight.w800,
fontSize: 24,
letterSpacing: 0.27,
color: HexColor('FF8C3B'),
),
),
Flexible(
child: GamesGridView(
callBack: () {},
),
)
],
),
);
}
Thank you for your help!
You can wrap your widget which is inside Scaffold body with ListView.
Then you should remove all flex widgets from your Column.
Your GridView should include
shrinkWrap: truephysics: const ClampingScrollPhysics()
Refer this,
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
return Material(
color: Colors.white, //DesignCourseAppTheme.nearlyWhite,
child: PageView(
scrollDirection: Axis.vertical,
children: [
Scaffold(
body: SafeArea(
child: ListView(
padding: EdgeInsets.symmetric(horizontal: 30),
children: <Widget>[
getAppBarUI(),
getCategoryUI(),
getPopularCourseUI(),
],
),
),
),
],
),
);
}
Widget getCategoryUI(){
return SizedBox(
height: 300,
child: PageView(
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 40.0,horizontal: 30.0),
child: Material(
color: Colors.blue,
elevation: 3.0,
borderRadius: BorderRadius.circular(20.0),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 40.0,horizontal: 30.0),
child: Material(
color: Colors.green,
elevation: 3.0,
borderRadius: BorderRadius.circular(20.0),
),
),
],
),
);
}
Widget getAppBarUI(){
return Text(
'Games for Fun!',
style: TextStyle(
fontFamily: "Netflix",
fontWeight: FontWeight.w800,
fontSize: 32.0,
letterSpacing: 0.27,
color: Colors.red, //HexColor('FF8C3B'),
),
);
}
Widget getPopularCourseUI() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Featured Games',
style: TextStyle(
fontFamily: "Netflix",
fontWeight: FontWeight.w800,
fontSize: 24.0,
letterSpacing: 0.27,
color: Colors.red, //HexColor('FF8C3B'),
),
),
const SizedBox(height: 8.0),
GamesGridView(
callBack: () {},
)
],
);
}
}
class GamesGridView extends StatelessWidget {
final VoidCallback callBack;
const GamesGridView({Key key, this.callBack}) : super(key: key);
#override
Widget build(BuildContext context) {
return GridView.count(
shrinkWrap: true, //TODO: must be included
physics: const ClampingScrollPhysics(), //TODO: must be included
crossAxisCount: 2,
mainAxisSpacing: 50.0,
crossAxisSpacing: 50.0,
children: <Widget>[
RaisedButton(child: Text("Button"), onPressed: () {}),
RaisedButton(child: Text("Button"), onPressed: () {}),
RaisedButton(child: Text("Button"), onPressed: () {}),
RaisedButton(child: Text("Button"), onPressed: () {}),
RaisedButton(child: Text("Button"), onPressed: () {}),
RaisedButton(child: Text("Button"), onPressed: () {}),
RaisedButton(child: Text("Button"), onPressed: () {}),
],
);
}
}
Here getCategoryUI can scroll horizontally too.
If I understood your issue correctly, using a CustomScrollView with SliverAppBar and a SliverGrid should do what you want:
class GridViewIssue extends StatelessWidget {
#override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: Center(child: Text('Banner')),
expandedHeight: 250.0,
),
SliverGrid(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 8
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2
)
)
],
);
}
}

Resources