In my app I have a GridView.builder
inside a column
.
Code:
class EserciziPage extends StatefulWidget {
const EserciziPage({super.key});
@override
State<EserciziPage> createState() => _EserciziPageState();
}
class _EserciziPageState extends State<EserciziPage> {
final TextEditingController _searchController = TextEditingController();
late LoadExercisesBloc _loadExercisesBloc;
final ScrollController _scrollController = ScrollController();
Timer? _debounce;
@override
void initState() {
super.initState();
_loadExercisesBloc = context.read<LoadExercisesBloc>();
}
@override
void dispose() {
_debounce?.cancel();
_searchController.dispose();
_scrollController.dispose();
super.dispose();
}
void _onSearchChanged(String query) {
}
void _fetchExercises() {
}
void _filterExercises() {
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/background.webp"),
fit: BoxFit.cover,
),
),
child: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: isMobile ? 5 : 20),
child: Column(
children: [
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 1280),
child: Column(
children: [
TitoloPagina(
title: "Tutti gli esercizi",
postTitle: Row(
children: [
const Spacer(),
IconButton(
tooltip: "Ricarica gli esercizi",
onPressed: () {
_loadExercisesBloc.add(ResetEvent());
},
icon: const HeroIcon(
HeroIcons.arrowPath,
),
),
const FiltersWidget(),
],
),
),
getSearchBarUI(),
BlocBuilder<LoadExercisesBloc, LoadExercisesState>(
builder: (context, state) {
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 22,
vertical: 5,
),
child: Text(
getFraseNumeroEserciziTrovati(state),
),
),
],
),
GridView.builder(
controller: _scrollController,
padding: const EdgeInsets.only(top: 5),
itemBuilder: (context, index) {
return const EsercizioPreviewLoading();
},
itemCount: getItemCount(state),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
mainAxisExtent: 150
),
),
],
),
);
},
),
],
),
),
],
),
),
),
),
);
}
int getItemCount(LoadExercisesState state) {
return state.items.length;
}
String getFraseNumeroEserciziTrovati(LoadExercisesState state) {
int numero = state.size;
return "$numero esercizi trovati";
}
Widget getSearchBarUI() {
return SizedBox(
width: double.infinity, // Occupa tutta la larghezza disponibile
child: Center(
child: LayoutBuilder(
builder: (context, constraints) {
return SizedBox(
width: min(
1280,
constraints.maxWidth,
), // Limite massimo di larghezza
child: Row(
children: [
Expanded(
// Occupa tutto lo spazio disponibile
child: Container(
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: TextField(
controller: _searchController,
),
),
),
],
),
);
},
),
),
);
}
}
but when it runs it gives:
The following assertion was thrown during performLayout():
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
When a column is in a parent that does not provide a finite height constraint, for example if it is
in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
space in the vertical direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
cannot simultaneously expand to fit its parent.
Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
children (using Flexible rather than Expanded). This will allow the flexible children to size
themselves to less than the infinite remaining space they would otherwise be forced to take, and
then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
constraints provided by the parent.
Basically, I would like to have a fixed title, search bar and text with "# exercises found" and scrollable gridview with exercises.
Can you help me?
In my app I have a GridView.builder
inside a column
.
Code:
class EserciziPage extends StatefulWidget {
const EserciziPage({super.key});
@override
State<EserciziPage> createState() => _EserciziPageState();
}
class _EserciziPageState extends State<EserciziPage> {
final TextEditingController _searchController = TextEditingController();
late LoadExercisesBloc _loadExercisesBloc;
final ScrollController _scrollController = ScrollController();
Timer? _debounce;
@override
void initState() {
super.initState();
_loadExercisesBloc = context.read<LoadExercisesBloc>();
}
@override
void dispose() {
_debounce?.cancel();
_searchController.dispose();
_scrollController.dispose();
super.dispose();
}
void _onSearchChanged(String query) {
}
void _fetchExercises() {
}
void _filterExercises() {
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/background.webp"),
fit: BoxFit.cover,
),
),
child: SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: isMobile ? 5 : 20),
child: Column(
children: [
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 1280),
child: Column(
children: [
TitoloPagina(
title: "Tutti gli esercizi",
postTitle: Row(
children: [
const Spacer(),
IconButton(
tooltip: "Ricarica gli esercizi",
onPressed: () {
_loadExercisesBloc.add(ResetEvent());
},
icon: const HeroIcon(
HeroIcons.arrowPath,
),
),
const FiltersWidget(),
],
),
),
getSearchBarUI(),
BlocBuilder<LoadExercisesBloc, LoadExercisesState>(
builder: (context, state) {
return SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: [
Row(
children: [
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 22,
vertical: 5,
),
child: Text(
getFraseNumeroEserciziTrovati(state),
),
),
],
),
GridView.builder(
controller: _scrollController,
padding: const EdgeInsets.only(top: 5),
itemBuilder: (context, index) {
return const EsercizioPreviewLoading();
},
itemCount: getItemCount(state),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
mainAxisExtent: 150
),
),
],
),
);
},
),
],
),
),
],
),
),
),
),
);
}
int getItemCount(LoadExercisesState state) {
return state.items.length;
}
String getFraseNumeroEserciziTrovati(LoadExercisesState state) {
int numero = state.size;
return "$numero esercizi trovati";
}
Widget getSearchBarUI() {
return SizedBox(
width: double.infinity, // Occupa tutta la larghezza disponibile
child: Center(
child: LayoutBuilder(
builder: (context, constraints) {
return SizedBox(
width: min(
1280,
constraints.maxWidth,
), // Limite massimo di larghezza
child: Row(
children: [
Expanded(
// Occupa tutto lo spazio disponibile
child: Container(
height: 50,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: TextField(
controller: _searchController,
),
),
),
],
),
);
},
),
),
);
}
}
but when it runs it gives:
The following assertion was thrown during performLayout():
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
When a column is in a parent that does not provide a finite height constraint, for example if it is
in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
space in the vertical direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
cannot simultaneously expand to fit its parent.
Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
children (using Flexible rather than Expanded). This will allow the flexible children to size
themselves to less than the infinite remaining space they would otherwise be forced to take, and
then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
constraints provided by the parent.
Basically, I would like to have a fixed title, search bar and text with "# exercises found" and scrollable gridview with exercises.
Can you help me?
Share Improve this question edited Mar 19 at 12:15 Ravindra S. Patil 15k5 gold badges19 silver badges51 bronze badges asked Mar 19 at 11:46 loreeemartiiiloreeemartiii 4177 silver badges15 bronze badges1 Answer
Reset to default 1Try below code hope its help to you. I have create some UI as take of your provided code and add grid view inside that, and add shrinkWrap param is true, and if you want to scroll only grid then I have added grid inside Expanded widget, if you want scroll whole page then remove Expanded
and wrap your Column
inside SingleChildScrollView
Scaffold(
body: Column(
children: [
Container(height: 200, color: Colors.green),
TextField(),
Expanded(
child: GridView.builder(
shrinkWrap: true,
padding: const EdgeInsets.only(top: 5),
itemBuilder: (context, index) {
return Text(index.toString());
},
itemCount: 1000,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
mainAxisExtent: 150,
),
),
),
],
),
)