Flutter Horizontal List with A Snap Effect
Last updated Mar 16, 2025This implementation demonstrates a horizontal list in Flutter with an elegant snap effect, showing how to create smooth, attractive horizontal scrolling UI components. The code features:
Key Features
- PageView with Snap Effect - Automatically snaps to the nearest item when scrolling ends
- Visual Feedback - Items scale up when centered and down when not, providing clear visual cues
- Smooth Animations - Uses TweenAnimationBuilder for fluid transitions between states
- Page Indicators - Shows the current position with interactive dot indicators
- Multiple Implementation Options - Includes both PageView and ListView.builder approaches
Implementation Details
The solution uses PageView.builder
with a custom PageController
that has a viewportFraction
of 0.8, allowing users to see partial items on either side while focusing on the current one. The snap effect is built into PageView by default.
For enhanced user experience, the current item scales to 1.0 while others scale to 0.9, creating a subtle but effective focus effect. The transition between these states is smoothly animated using TweenAnimationBuilder
.
This implementation is perfect for product carousels, image galleries, feature showcases, or any horizontal scrolling content that benefits from clear item separation and focus
#1 Flutter Horizontal List with Snap Effect: A Complete Guide
import 'package:flutter/material.dart'; class SnapHorizontalList extends StatefulWidget { @override class _SnapHorizontalListState extends State { @override @override void _onScroll() { @override // Example of how to use this widget in a main app class MyApp extends StatelessWidget { @override |
#2 Horizontal List with Snap Effect
Flutter offers various widgets in which Listview is the most used widget in the application and in today's tutorial we will see how you can get a snapping effect to listview i.e "snaping" event to an item at the end of user-scroll.
Let's start
Step 1: Create a new Flutter Application
Step 2: Add a line like this to your package's pubspec.yaml
|
Step 3: You can create a list that you want in which there is an item view for example we have a list of ten numbers that we will display in a container.
List data = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; |
Now Once the Package is installed we will get access to a widget called ScrollSnapList it has required properties
-
itemBuilder: where you will give your list item view.
-
itemCount: where you will give the list item count just like normal listview.
-
itemSize: Composed of the size of each item + its margin/padding. Size used is width if
scrollDirection
isAxis.horizontal
, height ifAxis.vertical.
-
onItemFocus: Callback function when list snaps to list index.
when the item reaches to last it has a property called onReachEnd which will help you launch any function
for example:
Expanded( child: ScrollSnapList( onItemFocus: _onItemFocus, itemBuilder: _buildItemList, itemSize: 150, dynamicItemSize: true, onReachEnd: () { print('Done!'); }, itemCount: data.length, )), |
this is the simple example where you will see "Done!" printed in your terminal when the list reaches to end using onReachEnd Function.
Full Source Code to try
import 'package:flutter/material.dart'; import 'package:scroll_snap_list/scroll_snap_list.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: DemoApp(), theme: ThemeData( brightness: Brightness.dark, ), ); } }
class DemoApp extends StatefulWidget { @override _DemoAppState createState() => _DemoAppState(); }
class _DemoAppState extends State { int _focusedIndex = 0; List data = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; void _onItemFocus(int index) { setState(() { _focusedIndex = index; }); }
Widget _buildItemList(BuildContext context, int index) { if (index == data.length) return Center( child: CircularProgressIndicator(), ); return Container( width: 150, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( color: Colors.yellow, width: 150, height: 200, child: Center( child: Text( '${data[index]}', style: TextStyle(fontSize: 50.0, color: Colors.black), ), ), ), ], ), ); }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( 'Horizontal list', style: TextStyle(color: Colors.white), ), centerTitle: true, ), body: Container( child: Column( children: [ Expanded( child: ScrollSnapList( onItemFocus: _onItemFocus, itemBuilder: _buildItemList, itemSize: 150, dynamicItemSize: true, onReachEnd: () { print('Done!'); }, itemCount: data.length, )), ], ), ), ); } }
|
Output:
![]() |
![]() |
Conclusion: In this way, we have learned how you can get a snapping effect for a horizontal list in Flutter.
Article Contributed By :
|
|
|
|
1324 Views |