Skip to content
Related Articles

Related Articles

Improve Article

Flutter – Scroll Snap List

  • Difficulty Level : Expert
  • Last Updated : 15 Feb, 2021

The scroll_snap_list package provides a wrapper that wraps around the ListView.builder widget to enable snapping event on List items. It can be modified to horizontal or vertical snapping based on the requirements. It is also important to note that it doesn’t make use of less or no animation.

In this article, we will look into the properties of the Scroll Snap List and its implementation through a simple application.

Want a more fast-paced & competitive environment to learn the fundamentals of Android?
Click here to head to a guide uniquely curated by our experts with the aim to make you industry ready in no time!

Key Properties of Scroll Snap List:

  • key: It is used to call ScrollSnapListState
  • listViewKey: It holds the keys to the ListView inside the ScrollSnapListState
  • curve: Use to set curve animation during the snap event
  • duration: Sets the duration for the animation
  • margin: Sets the container margin
  • itemCount: It represents the number of items in the list
  • onItemFocus: It sends a callback when an item is snapped or in focous
  • reverse: It is used to reverse the ListView
  • scrollDirection: Sets the direction of the scroll for the ListView
  • dynamicItemOpacity: Sets the opacity for items that are no in focus

Now, Let’s implement the Scroll Snap List through a simple application. To build the app, follow the below steps:

  • Add the dependency to the pubspec.yaml file
  • Import the dependency to the main.dart file
  • Create the root of the application
  • Extend the root to a Mainpage of sort
  • Implement the Scroll Snap List
  • Add items to the ListView

Now let’s look into the steps in detail.



Adding the Dependency:

To add the scroll_snap_list dependency to the pubspec.yaml file, follow the below image:

Importing the Dependency:

Use the below line of code to import the dependency to the main.dart file:

import 'package:scroll_snap_list/scroll_snap_list.dart';

Creating the Application Root:

The root of the application can be created by creating a Class (say, HorizontalListDemo) that extends to a StatelessWidget as shown below:

Dart




class HorizontalListDemo extends StatefulWidget {
  @override
  _HorizontalListDemoState createState() => _HorizontalListDemoState();
}

Extending the Root:

Now that the root of the application established, we can now create another Class (say,  _HorizontalListDemoState) that extends to the State of the list item:

Dart




class _HorizontalListDemoState extends State<HorizontalListDemo> {
  List<int> data = [];
  int _focusedIndex = 0;
  
  @override
  void initState() {
    super.initState();
  
    for (int i = 0; i < 30; i++) {
      data.add(Random().nextInt(100) + 1);
    }
  }
  
  void _onItemFocus(int index) {
    setState(() {
      _focusedIndex = index;
    });
  }
  }

Implementing the Scroll Snap List:

To implement the Scroll Snap List, use the below line of codes and modify it as per your need:

Dart




ScrollSnapList(
  onItemFocus: _onItemFocus,
  itemSize: 50,
  itemBuilder: _buildListItem,
  itemCount: data.length,
  key: sslKey,
  scrollDirection: Axis.vertical,
)

Adding the Items:

In your buildItem method, call the focusToItem method as shown below :

Dart




Widget _buildListItem(BuildContext context, int index) {
  //horizontal
  return Container(
    height: 50,
    child: Material(
      color: _focusedIndex == index ? Colors.lightBlueAccent : Colors.white,
      child: InkWell(
        child: Text("Index: $index | Value: ${data[index]}"),
        onTap: () {
          print("Add a statement here");
  
          //trigger
          sslKey.currentState.focusToItem(index);
        },
      ),
    ),
  );
}

Complete Source  Code:

Dart




import 'dart:math';
  
import 'package:flutter/material.dart';
import 'package:scroll_snap_list/scroll_snap_list.dart';
  
void main() => runApp(HorizontalListDemo());
  
// root of the application
class HorizontalListDemo extends StatefulWidget {
  @override
  _HorizontalListDemoState createState() => _HorizontalListDemoState();
}
  
class _HorizontalListDemoState extends State<HorizontalListDemo> {
  List<int> data = [];
  int _focusedIndex = 0;
  
  @override
  void initState() {
    super.initState();
  
    for (int i = 0; i < 30; i++) {
      data.add(Random().nextInt(100) + 1);
    }
  }
  
  void _onItemFocus(int index) {
    setState(() {
      _focusedIndex = index;
    });
  }
  
  Widget _buildItemDetail() {
    if (data.length > _focusedIndex)
      return Container(
        height: 150,
        child: Text("index $_focusedIndex: ${data[_focusedIndex]}"),
      );
  
    return Container(
      height: 150,
      child: Text("No Data"),
    );
  }
  
  Widget _buildListItem(BuildContext context, int index) {
    //horizontal
    return Container(
      width: 35,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Container(
            height: data[index].toDouble()*2,
            width: 25,
            color: Colors.green,
            child: Text("$index\n${data[index]}"),
          )
        ],
      ),
    );
  }
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Horizontal List',
      home: Scaffold(
        appBar: AppBar(
          title: Text("GeeksForGeeks"),
          backgroundColor: Colors.green,
        ),
        body: Container(
          child: Column(
            children: <Widget>[
              Expanded(
                child: ScrollSnapList(
                  onItemFocus: _onItemFocus,
                  itemSize: 35,
                  itemBuilder: _buildListItem,
                  itemCount: data.length,
                  reverse: true,
                ),
              ),
              _buildItemDetail(),
            ],
          ),
        ),
      ),
    );
  }
}

Output:




My Personal Notes arrow_drop_up
Recommended Articles
Page :