Horizontal ListView

When we think of lists in mobile applications, our first thought is usually vertical scrolling lists — a feed of posts, a chat history, or a list of contacts. But horizontal lists are just as important and often provide better UX for specific cases. Think about scrolling through product images, selecting categories in an e-commerce app, or browsing stories in a social media app.

In Flutter, horizontal scrolling lists are created using ListView with its scrollDirection property set to Axis.horizontal. This allows you to create clean, intuitive, and scrollable rows of items.

In this post, we will explore:

  1. Creating side-scrolling lists with Horizontal ListView.
  2. Practical use cases such as product carousels, category selectors, and galleries.

By the end, you will be comfortable creating professional horizontal scroll lists in your Flutter apps.


Understanding Horizontal ListView

The ListView widget in Flutter is inherently scrollable, and its default direction is vertical. But by changing the scrollDirection property, we can turn the list into a horizontal one.

The core structure looks like this:

ListView(
  scrollDirection: Axis.horizontal,
  children: [
Container(width: 150, color: Colors.red),
Container(width: 150, color: Colors.green),
Container(width: 150, color: Colors.blue),
], );

Here, instead of scrolling up and down, the user scrolls left and right.


Difference Between Vertical and Horizontal Lists

  • Vertical ListView: Items stack top to bottom, scroll direction is up and down.
  • Horizontal ListView: Items stack left to right, scroll direction is sideways.

Both share the same underlying widget, which makes horizontal lists very easy to implement.


Creating Side-Scrolling Lists

Let us explore how to build a horizontal ListView step by step.


Step 1: Basic Horizontal ListView

The simplest implementation involves using a ListView with scrollDirection: Axis.horizontal.

ListView(
  scrollDirection: Axis.horizontal,
  children: [
Container(
  width: 120,
  color: Colors.red,
  child: Center(child: Text("Item 1")),
),
Container(
  width: 120,
  color: Colors.green,
  child: Center(child: Text("Item 2")),
),
Container(
  width: 120,
  color: Colors.blue,
  child: Center(child: Text("Item 3")),
),
], );

Here:

  • Each container has a fixed width to ensure horizontal scrolling.
  • You can swipe left and right to see all items.

Step 2: Adding Padding and Spacing

By default, items sit right next to each other. To improve readability, use padding or margin.

ListView(
  scrollDirection: Axis.horizontal,
  padding: EdgeInsets.all(8),
  children: [
Container(width: 150, margin: EdgeInsets.only(right: 8), color: Colors.red),
Container(width: 150, margin: EdgeInsets.only(right: 8), color: Colors.green),
Container(width: 150, margin: EdgeInsets.only(right: 8), color: Colors.blue),
], );

This creates gaps between items, making the design cleaner.


Step 3: Using ListView.builder

When the list is long or dynamic, using the children property is inefficient because all items are built at once. Instead, use ListView.builder for better performance.

ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: 20,
  itemBuilder: (context, index) {
return Container(
  width: 120,
  margin: EdgeInsets.all(8),
  color: Colors.primaries[index % Colors.primaries.length],
  child: Center(child: Text("Item $index")),
);
}, );

With this:

  • Items are built lazily (only when visible).
  • Perfect for large datasets or lists populated from APIs.

Step 4: Using Cards in Horizontal Lists

Cards provide a structured and material-design-friendly look.

ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: 10,
  itemBuilder: (context, index) {
return Card(
  margin: EdgeInsets.symmetric(horizontal: 8),
  child: Container(
    width: 160,
    padding: EdgeInsets.all(16),
    child: Text("Card $index"),
  ),
);
}, );

Cards in a horizontal list look elegant, especially for UI like news headlines, product previews, or feature highlights.


Use Cases of Horizontal ListView

Horizontal ListViews are very versatile. Let’s discuss some real-world use cases.


1. Product Carousels in E-Commerce

E-commerce apps often display items in carousels:

  • Featured products.
  • Recommended items.
  • Related products.

Example:

ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: products.length,
  itemBuilder: (context, index) {
return Container(
  width: 160,
  margin: EdgeInsets.all(8),
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(12),
    color: Colors.white,
    boxShadow: [BoxShadow(blurRadius: 4, color: Colors.grey.shade300)],
  ),
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Image.network(products[index].image, height: 100),
      SizedBox(height: 8),
      Text(products[index].title),
      Text("\$${products[index].price}"),
    ],
  ),
);
}, );

This layout mimics common e-commerce product carousels, where users swipe horizontally to browse products.


2. Category Selector

Many apps provide horizontal scrolling categories at the top (like food delivery apps).

ListView(
  scrollDirection: Axis.horizontal,
  children: [
Chip(label: Text("All")),
SizedBox(width: 8),
Chip(label: Text("Electronics")),
SizedBox(width: 8),
Chip(label: Text("Fashion")),
SizedBox(width: 8),
Chip(label: Text("Home")),
], );

Horizontal chips are excellent for category filters and quick actions.


3. Story-Like UI (Social Media Apps)

Social media apps like Instagram or WhatsApp use horizontal lists for “stories.”

ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: users.length,
  itemBuilder: (context, index) {
return Column(
  children: [
    CircleAvatar(
      radius: 30,
      backgroundImage: NetworkImage(users[index].profilePicture),
    ),
    SizedBox(height: 4),
    Text(users[index].name),
  ],
);
}, );

This layout is widely recognized and expected by users.


4. Image Galleries

Horizontal lists are perfect for showing sets of images, either thumbnails or previews.

ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: images.length,
  itemBuilder: (context, index) {
return Container(
  margin: EdgeInsets.all(8),
  child: Image.network(images[index], width: 120),
);
}, );

This is common for media apps and profile galleries.


5. Page-Like Horizontal Scroll (PageView Alternative)

If each item fills the screen width, a horizontal ListView can simulate a PageView.

ListView.builder(
  scrollDirection: Axis.horizontal,
  itemCount: 5,
  itemBuilder: (context, index) {
return Container(
  width: MediaQuery.of(context).size.width,
  color: Colors.primaries[index % Colors.primaries.length],
  child: Center(child: Text("Page $index", style: TextStyle(fontSize: 24))),
);
}, );

This creates full-width scrollable screens — like swiping between onboarding screens.


Performance Considerations for Horizontal Lists

  1. Use ListView.builder for long lists to avoid memory issues.
  2. Use fixed item sizes (width for horizontal lists) for smoother scrolling.
  3. Cache images when displaying many thumbnails or product photos.
  4. Avoid rebuilding the entire list when updating one item — use keys and efficient state management.

UX Best Practices for Horizontal Lists

  • Show part of the next item: Indicating that more items can be scrolled increases discoverability.
  • Use clear labels: In product carousels or categories, label items clearly.
  • Limit the number of visible items: Don’t overwhelm the user with too many items in one row.
  • Consider snapping or paging: For carousels, users expect items to snap neatly into position.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *