You can have a horizontal scroll view (like a ListView or SingleChildScrollView with scrollDirection: Axis.horizontal) inside a vertical one — you just need to make sure Flutter knows how to size things properly so it doesn’t complain about unbounded height or conflicting scroll gestures.
✅ Example: Horizontal Scroll Inside Vertical Scroll
import 'package:flutter/material.dart';
class NestedScrollExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView( // main vertical scroll
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
"Vertical Content",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
),
// --- First horizontal scroll section ---
SizedBox(
height: 150, // important: give a fixed height
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) => Container(
width: 120,
margin: const EdgeInsets.all(8),
color: Colors.blue[(index + 1) * 100],
child: Center(
child: Text(
"Item $index",
style: const TextStyle(color: Colors.white, fontSize: 18),
),
),
),
),
),
const SizedBox(height: 20),
// --- More vertical content ---
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
"More vertical widgets below...",
style: TextStyle(fontSize: 18),
),
),
// Another horizontal scroll
SizedBox(
height: 200,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: List.generate(
5,
(i) => Container(
width: 180,
margin: const EdgeInsets.all(8),
color: Colors.green[(i + 2) * 100],
child: Center(
child: Text(
"Box $i",
style: const TextStyle(color: Colors.white, fontSize: 20),
),
),
),
),
),
),
),
const SizedBox(height: 100),
],
),
),
);
}
}
⚙️ Key Points
- Outer scroll →
SingleChildScrollView(vertical). - Inner scroll →
ListViewor anotherSingleChildScrollViewwithscrollDirection: Axis.horizontal. - Fixed height → For the horizontal section (e.g.
SizedBox(height: 150)) — otherwise, it’ll cause “unbounded height” errors. - Gesture handling → Works fine by default; vertical scroll reacts to vertical swipes, horizontal reacts to horizontal swipes.
💡 Bonus Tip
If you have many horizontal sections inside a vertical list (like a feed), use:
ListView.builder(
itemCount: ...,
itemBuilder: ...
)
with each item containing a horizontal ListView, and set
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
on the vertical ListView — this lets the vertical scroll handle all movement smoothly.
