Skip to content
FlutterDocs

How to Create Horizontal ListView in Flutter

Verified Solution Tested on Flutter 3.47.7 • Dart 3.13.5
Jump to Updated Flutter Example ↓

In this example, we are going to show you how to create a Horizontal scroll view or List view in Flutter App. We will set Scroll direction to Horizontal on ListView or SingleChildScrollView() widgets to make a Horizontal scroll view. See the example below:

How to Create Horizontal ListView in Flutter screenshot

How to Change Scroll Direction of ListView?

ListView(
  scrollDirection: Axis.horizontal,
  children:[]
)

By default, the scroll direction of ListView is vertical, you can use scrollDirection property to change scroll direction to Horizontal. You have to pass Axis value on this property.

Now, we will use this property to make Horizontal ListView:

How to Add ListView with Horizontal Scrolling?

List<String> countries = ["Brazil", "Nepal", "India", "China", "USA", "Canada"];
ListView(
  scrollDirection: Axis.horizontal,
  children: countries.map((country){
        return Container(
           color: Colors.orangeAccent,
           height: 100, width:150,
           alignment: Alignment.center
           child: Text(country)
        );
  }).toList(),
)

Here, we have made the list of Countries on ListView and set the scroll direction to Horizontal. We can achieve this feature using SingleChildScrollView() and Row() widgets as well.

List<String> countries = ["Brazil", "Nepal", "India", "China", "USA", "Canada"];
SingleChildScrollView(
    scrollDirection: Axis.horizontal,
    child:Row(
    children: countries.map((country){
        return Container(
           color: Colors.orangeAccent,
           height: 100, width:150,
           alignment: Alignment.center
           child: Text(country)
        );
    }).toList(),
  )
)

Here, we have wrapped infinite Row() with SingleChildScrollView() to add scrolling on overflowed Row width. And we have changed the scroll direction to Horizontal.

Full Dart/Flutter App Example:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
     return MaterialApp(
         home: Home()
      );
  }
}

class Home extends  StatefulWidget {
  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  List<String> countries = ["Brazil", "Nepal", "India", "China", "USA", "Canada"];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
         appBar: AppBar(
            title: Text("Horizonatl ListView"),
            backgroundColor: Colors.redAccent,
         ),

         body: Container(
                padding: EdgeInsets.all(20),
                child: Column( 
                  children: [

                      Container(
                        height: 100,
                        child:ListView(
                          scrollDirection: Axis.horizontal,
                          children: countries.map((country){
                               return box(country, Colors.deepPurpleAccent);
                          }).toList(),
                        )
                      ),

                      Container(
                        height: 100,
                        child:SingleChildScrollView(
                            scrollDirection: Axis.horizontal,
                            child:Row(
                            children: countries.map((country){
                                return box(country, Colors.deepOrangeAccent);
                            }).toList(),
                          )
                        )
                      )
   
                  ],
                ) 
            )   
          
    );
  } 

  Widget box(String title, Color backgroundcolor){
     return Container(
        margin: EdgeInsets.all(10),
        width: 80,
        color: backgroundcolor,
        alignment: Alignment.center,
        child: Text(title, style:TextStyle(
                     color: Colors.white,
                     fontSize: 20))
     );
  }
}

In this example, we have made two Scroll Views, one is using ListView() and one is using SingleChildScrollView(). Both have scroll direction to the Horizontal axis.

Output Screenshot:

How to Create Horizontal ListView in Flutter screenshot

In this way, you can make Horizontal Scroll View using ListView() and SingleChildScrollView() widget in Flutter. For structured tabular alternatives, explore creating tables with rows and columns and review array list basics in Dart.

Updated Flutter Example
SDK: Flutter 3.47.7 • Dart 3.13.5 Verified on Flutter 3.47.7 (Stable)

Updated Flutter Example

Horizontal Scrolling with Material 3 Virtualized Cards

Key Implementation Details & Modern Differences:

  • Explicit Cross-Axis Height Bounds: Horizontal list views require an explicit vertical constraint (via SizedBox or AspectRatio) to prevent parent Column collapse.
  • Virtualized Item Separation: Replaces manual row mapping with ListView.separated(scrollDirection: Axis.horizontal), delivering high-performance lazy viewport virtualization with uniform item spacing.
  • Modern Material 3 Token Styling: Uses modern M3 Card surfaces and Color.withValues(alpha: ...) to avoid precision loss from deprecated withOpacity().
Updated Flutter Example Code
import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(home: ModernHorizontalListDemo()));
}

class ModernHorizontalListDemo extends StatelessWidget {
  const ModernHorizontalListDemo({super.key});

  static const _categories = [
    ('Flutter Basics', Icons.flutter_dash, Colors.blue),
    ('State Management', Icons.memory, Colors.purple),
    ('Animations', Icons.auto_awesome, Colors.amber),
    ('Networking', Icons.cloud_sync, Colors.teal),
    ('SQLite Storage', Icons.storage, Colors.indigo),
    ('Material 3', Icons.palette, Colors.pink),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Horizontal ListView Demo')),
      body: Padding(
        padding: const EdgeInsets.symmetric(vertical: 24.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Padding(
              padding: EdgeInsets.symmetric(horizontal: 20.0),
              child: Text(
                'Explore Topics (Scroll Horizontally):',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
            ),
            const SizedBox(height: 16),
            // Explicit height container prevents unbounded vertical constraint crashes
            SizedBox(
              height: 175,
              child: ListView.separated(
                scrollDirection: Axis.horizontal,
                padding: const EdgeInsets.symmetric(horizontal: 20.0),
                itemCount: _categories.length,
                separatorBuilder: (context, index) => const SizedBox(width: 14),
                itemBuilder: (context, index) {
                  final (title, icon, color) = _categories[index];
                  return SizedBox(
                    width: 140,
                    child: Card(
                      elevation: 2,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(16),
                      ),
                      child: InkWell(
                        borderRadius: BorderRadius.circular(16),
                        onTap: () {
                          ScaffoldMessenger.of(context).showSnackBar(
                            SnackBar(content: Text('Selected: $title')),
                          );
                        },
                        child: Padding(
                          padding: const EdgeInsets.all(12.0),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              CircleAvatar(
                                backgroundColor: color.withValues(alpha: 0.15),
                                foregroundColor: color,
                                radius: 24,
                                child: Icon(icon, size: 26),
                              ),
                              const SizedBox(height: 8),
                              Text(
                                title,
                                textAlign: TextAlign.center,
                                style: const TextStyle(
                                  fontWeight: FontWeight.w600,
                                  fontSize: 13,
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Document History & Archival Record

Original reference snapshot archived March 22, 2023. Updated working solution verified on modern Flutter & Dart SDKs.