I have very simple screen which downloads list of data from internet and shows it via bloc in listview in Flutter. Everything works fine. But I have a problem to add any widget to the top of the listview. If I do it, listview is not shown correctly. I tried to do it as is described here: https://github.com/flutter/flutter/issues/99724 It works if I do not use bloc, but with bloc. Any body did it with bloc ?
CatalogScreen({super.key});
final PartRepository partRepository = PartRepository();
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider(
create: (_) => CatalogBloc(partRepository)..add(CatalogFetched()),
child: const CatalogList(),
),
);
}
}
class CatalogList extends StatefulWidget {
const CatalogList({super.key});
@override
State<CatalogList> createState() => _CatalogListState();
}
class _CatalogListState extends State<CatalogList> {
@override
Widget build(BuildContext context) {
return BlocBuilder<CatalogBloc, FetchCatalogState>(
builder: (context, state) {
switch (state.status) {
case FetchCatalogStatus.failure:
return Center(child: Text(tr('posts_failed')));
case FetchCatalogStatus.success:
if (state.categories.isEmpty) {
return Center(child: Text(tr('no_parts')));
}
return Column(children: [
const Text('test test'),
ListView.builder(
itemBuilder: (BuildContext context, int index) {
return CatalogListItem(category: state.categories[index]);
},
itemCount: state.categories.length,
)
]);
case FetchCatalogStatus.initial:
return const Center(child: CircularProgressIndicator());
}
},
);
}
}
shows this error: RenderBox was not laid out: RenderRepaintBoundary#875f2 relayoutBoundary=up5 NEEDS-PAINT 'package:flutter/src/rendering/box.dart': Failed assertion: line 2009 pos 12: 'hasSize'
The Column above needs a fixed height to render the ListView below with an extra widget on top or bottom. To fix this problem you need to use the Expanded widget at the top of any of the children or all. Like below
class _CatalogListState extends State<CatalogList> {
@override
Widget build(BuildContext context) {
return BlocBuilder<CatalogBloc, FetchCatalogState>(
builder: (context, state) {
switch (state.status) {
case FetchCatalogStatus.failure:
return Center(child: Text(tr('posts_failed')));
case FetchCatalogStatus.success:
if (state.categories.isEmpty) {
return Center(child: Text(tr('no_parts')));
}
return Column(children: [
Expanded(
child: const Text('test test'),
),
Expanded(
child: ListView.builder(
itemBuilder: (BuildContext context, int index) {
return CatalogListItem(category: state.categories[index]);
},
itemCount: state.categories.length,
),
)
]);
case FetchCatalogStatus.initial:
return const Center(child: CircularProgressIndicator());
}
},
);
}
}
You can also provide flex as per the height provided