Change height of row in GridView builder to fixed height - flutter

I've noticed that GridView makes each child a square.. Is there any way to adjust height of each child which means entire row of GridView row in GridView.builder?
In this example I want to have each input next to each other.
List<Map<String, dynamic>> list = [
{'description': 'des1'},
{'description': 'des2'},
{'description': 'des3'},
{'description': 'des4'},
{'description': 'des5'},
{'description': 'des6'}
];
class _MaterialScreenState extends State<MaterialScreen> {
String text = '';
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Text(text),
GridView.builder(
shrinkWrap: true,
itemCount: list.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5),
itemBuilder: (BuildContext context, int index) {
return TextFormField(
textAlign: TextAlign.center,
onTap: () => setState(() {
text = list[index]['description'];
}),
decoration: InputDecoration(border: OutlineInputBorder()),
);
}),
],
));
Problem:
Reason:

How about this?
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 3,
),

Yoy can use "childAspectRatio".
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
childAspectRatio: 2,
),

Related

flutter GridView.builder won't let rest of screen scroll

I have GridView.builder middle of my screen but it does not let my screen to scroll! I must find some white space in screen in order to be able to scroll rest of my screen.
Here is how my screen structure looks like:
Widget build(BuildContext context) {
return Scaffold(
appBar: const TopBarFile(),
drawer: const DrawerFile(),
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: FutureBuilder(
future: myCards,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// some widgets...
const SizedBox(height: 15),
// here middle of screen is GridView
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),
const SizedBox(height: 15),
// some more widgets...
]
);
} else {...}
return container();
}
),
),
),
),
),
}
Note: this grid view only has 6 items so I don't need it to be scrollable actually I just use it for design purpose but its causing scrolling issue, so I just need to be able to scroll my page even if I'm touching on top of this grid view items.
Any suggestions?
you can define a physics property with NeverScrollableScrollPhysics() value inside GridView, this will solve the issue. Always use physics property When you have nested scrollable widget.
You can give physics: NeverScrollableScrollPhysics() to GridView() or use Wrap() widget instead of GridView().
Use physics and shrinkWrap property as below:
SizedBox(
child: GridView.builder(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data['cards'].length,
itemBuilder: (BuildContext context, int index) {
return InkWell(...);
}
)
),

Implementing flutter ui

I have been trying to recreate this ui where the gridview
This is what I have tried so far
GridView.builder(
shrinkWrap: true,
primary: true,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
mainAxisExtent: 300,
),
itemCount: snapshot.data!.length,
padding: const EdgeInsets.all(8.0),
itemBuilder: (BuildContext context, int index) {
final model = result[index];
return MyContainer(
loanProductModel: model,
);
},
)
This is the screenshot of what I have tried.
You can achieve it by using flutter_staggered_grid_view package and the below code
import 'package:flutter/material.dart';
class ScrollView extends StatelessWidget {
const ScrollView({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 12),
sliver: SliverStaggeredGrid.countBuilder(
crossAxisCount: 2,
mainAxisSpacing: 9.0,
crossAxisSpacing: 9.0,
staggeredTileBuilder: (int index) =>
StaggeredTile.count(1, index % 5 == 0 ? 1.5 : 1.2),
itemCount: snapshot.data!.length,
itemBuilder: (ctx, i) {
final model = result[index];
return MyContainer(
loanProductModel: model,
);
}),
),
],
),
);
}
}

Unable to remove the padding in Expanded Widget

I can't seem to find why after the first Text Widget, there is a big gap of space. I didn't put any Padding or SizedBox but somehow, the Expanded seem to have its own padding. Please help on how can I adjust that space in between the text and numbers. Thanks!
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Text'),
Expanded(
child: GridView.builder(
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, childAspectRatio: 5 / 1),
itemCount: 6,
itemBuilder: (BuildContext ctx, index) {
return Text('$index');
}),
),
],
);
}
Output:
Text
0 1 2
3 4 5
Expected output:
Text
0 1 2
3 4 5
Note: This is the minimized code in order to show the essential.
Change your GridView.builder to this:
Expanded(
child: GridView.builder(
padding: const EdgeInsets.only(top: 0),
physics: const NeverScrollableScrollPhysics(),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, childAspectRatio: 5 / 1),
itemCount: 6,
itemBuilder: (BuildContext ctx, index) {
return Text('$index');
}),
)

Create Gridview with user input(Row and Column) in flutter

How can we create Gridview with the user input? the user is allowed to enter the no of rows and columns.
class Class extends StatefulWidget {
#override
_ClassState createState() => _ClassState();
}
class _ClassState extends State<Class> {
TextEditingController row = TextEditingController();
TextEditingController column = TextEditingController();
int rowC = 2;
int colC = 2;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
height: 500,
child: GridView.builder(
itemCount: colC * rowC,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: rowC,childAspectRatio: colC*rowC/2 ,crossAxisSpacing: 10,mainAxisSpacing: 10),
shrinkWrap: true,
itemBuilder: (context, index) => Container(
color: Colors.greenAccent,
),
),
),
Text("Row"),
TextField(
controller: row,
),
SizedBox(height: 20,),
Text("Column"),
TextField(
controller: column,
),
SizedBox(height: 20,),
FlatButton(onPressed: (){
rowC = int.parse(row.text);
colC = int.parse(column.text);
setState(() {
});
}, child: Container(
color: Colors.purple,
padding: EdgeInsets.all(20),
child: Text("Add")))
],
),
);
}
}
You can achieve your requirement by using the GridView.builder.
GridView.builder(
shrinkWrap: true,
itemCount: (rowCount * ColumnCount),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: ColumnCount),
itemBuilder: (context, index) {
return Container(
child: Text(index.toString()),
);
}, );
Every user input you must to refresh the widget.

Flutter: How can I use DraggableScrollableActuator.reset AND the ScrollController from DraggableScrollableSheet for a nested list?

I am getting this error.
The following assertion was thrown building _InheritedResetNotifier(dirty):
flutter: ScrollController attached to multiple scroll views.
flutter: 'package:flutter/src/widgets/scroll_controller.dart':
flutter: Failed assertion: line 111 pos 12: '_positions.length == 1'
It seems I can either attach DraggableScrollableSheet's ScrollController to the nested list OR use DraggableScrollableActuator.reset(context) to reset the extent. I don't see why I can't do both. Is this a bug? Is there a work around or another way?
Here is my code:
class InterfaceSelector extends StatefulWidget {
#override
InterfaceSelectorState createState() => InterfaceSelectorState();
}
class InterfaceSelectorState extends State<InterfaceSelector> {
double initialChildSize = 0.5;
double minChildSize = 0.5;
double maxChildSize = 0.7;
#override
Widget build(BuildContext context) {
return DraggableScrollableActuator(
child: DraggableScrollableSheet(
initialChildSize: initialChildSize,
minChildSize: minChildSize,
maxChildSize: maxChildSize,
builder: (BuildContext ctx, ScrollController scrollController) {
return SingleChildScrollView(
controller: scrollController,
child: Container(
height: MediaQuery.of(context).size.longestSide * .7,
color: Theme.of(ctx).primaryColor,
child: DefaultTabController(
length: 4,
child: Column(
children: <Widget>[
Material(
color: Theme.of(ctx).accentColor,
child: TabBar(
tabs: [
Tab(text: "One"),
Tab(text: "Two"),
Tab(text: "Three"),
Tab(text: "Four"),
],
),
),
Expanded(
child: TabBarView(
children: [
One(),
Two(),
Three(scrollController),
Four(),
],
),
),
],
),
),
),
);
},
),
);
}
}
class Three extends StatefulWidget {
ScrollController scrollController;
Three(this.scrollController);
#override
_ThreeState createState() => _ThreeState();
}
class _ThreeState extends State<Three> with AutomaticKeepAliveClientMixin {
#override
bool get wantKeepAlive => true;
#override
Widget build(BuildContext context) {
Stuff stuff = Provider.of<Stuff>(context);
return Column(
children: <Widget>[
MaterialButton(onPressed: () {
DraggableScrollableActuator.reset(context);
}),
Expanded(
child: GridView.builder(
controller: widget.scrollController,
padding: const EdgeInsets.all(10),
itemCount: stuff.all.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
value: stuff.all[i],
key: UniqueKey(),
child: StuffCard(i, stuff.all[i], stuff),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
),
),
],
);
}
}
Your GridView doesn't need scrolling - scrolling is provided by your SingleChildScrollView. Don't pass the scrollController to GridView, set physics: NeverScrollableScrollPhysics(), in your grid builder instead:
GridView.builder(
physics: NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(10),
itemCount: stuff.all.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
value: stuff.all[i],
key: UniqueKey(),
child: StuffCard(i, stuff.all[i], stuff),
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
),