I keep trying to display a simple ListView, which I will fill with data that I get as a response from my backend. First of all I wanted to display that simple ListView inside my MainPage widget but i keep receiving the following error. I couldn't find anything related to that error besides this solution, which mentions about wrapping up the ListView.builder in Expanded widget and adding shrinkWrap: true
property. However, I keep getting the following error:
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by scheduler library ═════════════════════════════════ Updated layout information required for RenderFlex#c30cf relayoutBoundary=up11 NEEDS-LAYOUT NEEDS-PAINT to calculate semantics. 'package:flutter/src/rendering/object.dart': Failed assertion: line 3620 pos 12: '!_needsLayout' ════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by gestures library ══════════════════════════════════ Cannot hit test a render box that has never been laid out. ════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by gestures library ══════════════════════════════════ Cannot hit test a render box that has never been laid out. ════════════════════════════════════════════════════════════════════════════════
Here is the code of my ListView.builder, further down I will put the whole code of the MainPage widget: ListView
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 15,
itemBuilder: (BuildContext context, int index) => Card(
child: Center(child: Text('Dummy Card Text')),
),
),
),
whole widget
class MainPage extends ConsumerWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context, ref) {
// provider
// final _data = ref.watch(roomDataProvider);
final roomIDController = TextEditingController();
// UI screen size
Size size = MediaQuery.of(context).size;
double deviceWidth = size.width;
double deviceHeight = size.height;
return Scaffold(
backgroundColor: bluePrimary,
body: SafeArea(
child: SingleChildScrollView(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 36, vertical: 16),
child: Column(
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
iconSize: deviceWidth * 0.09,
icon: const Icon(Icons.person_outline,
color: orangePrimary),
onPressed: () {},
),
IconButton(
icon: const Icon(
Icons.add,
color: orangePrimary,
),
iconSize: deviceWidth * 0.09,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const CreateRoomScreen()),
);
},
)
],
),
SizedBox(height: deviceHeight * 0.04),
Align(
alignment: Alignment.centerLeft,
child: Text("W",
style: TextStyle(
fontFamily: 'Chalet',
fontSize: deviceWidth * 0.12,
color: orangePrimary,
fontWeight: FontWeight.w300,
height: deviceHeight * 0.001)),
),
Align(
alignment: Alignment.centerLeft,
child: Text("W",
style: TextStyle(
fontFamily: 'Chalet',
fontSize: deviceWidth * 0.12,
color: whitePrimary,
fontWeight: FontWeight.w300,
height: deviceHeight * 0.001)),
),
Align(
alignment: Alignment.centerLeft,
child: Text("M",
style: TextStyle(
fontFamily: 'Chalet',
fontSize: deviceWidth * 0.12,
color: orangePrimary,
fontWeight: FontWeight.w300,
height: deviceHeight * 0.001)),
),
SizedBox(height: deviceHeight * 0.04),
Align(
alignment: Alignment.centerLeft,
child: Text("Join room",
style: TextStyle(
fontFamily: 'Chalet',
fontSize: deviceWidth * 0.07,
color: whitePrimary,
fontWeight: FontWeight.w100,
height: deviceHeight * 0.001)),
),
SizedBox(height: deviceHeight * 0.008),
// email textField
SizedBox(
width: MediaQuery.of(context).size.width * 0.85,
child: TextField(
controller: roomIDController,
decoration: InputDecoration(
filled: true,
fillColor: whitePrimary,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none),
hintText: 'Enter room ID to join it',
hintStyle: const TextStyle(
color: Color.fromARGB(255, 174, 173, 173))),
),
),
SizedBox(height: deviceHeight * 0.016),
Align(
alignment: Alignment.bottomRight,
child: FloatingActionButton(
backgroundColor: orangePrimary,
child: const Icon(Icons.arrow_forward_ios_rounded,
color: whitePrimary),
onPressed: () {},
),
),
SizedBox(height: deviceHeight * 0.020),
Align(
alignment: Alignment.centerLeft,
child: Text("My rooms",
style: TextStyle(
fontFamily: 'Chalet',
fontSize: deviceWidth * 0.07,
color: whitePrimary,
fontWeight: FontWeight.w100,
height: deviceHeight * 0.001)),
),
SizedBox(height: deviceHeight * 0.014),
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: 15,
itemBuilder: (BuildContext context, int index) => Card(
child: Center(child: Text('Dummy Card Text')),
),
),
),
]),
),
)),
);
}
}
The problem is that you wrapped the ListView
with an Expanded
that is inside a Column
, but the Column
does not have constrained height since it's inside a SingleChildScrollView
. The Expanded
widget will try to fill the remaining height, but since it's inside a scrollable that run horizontally, there's no limit to the height. If you want to keep the scrolling behavior, you should give the ListView
a fixed height instead of using Expanded
:
SizedBox(
height: 100,
child: ListView.builder(
// ...
),
),
Or if you want to make the ListView
to actually fill the remaining height in the screen, remove the SingleChildScrollView
widget.
See also: