Open In App

Flutter – Scroll Snap List

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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.

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 focus
  • 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:



Last Updated : 05 Aug, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads