scroll_snap_list

Creator: coderz1093

Last updated:

Add to Cart

Description:

scroll snap list

scroll_snap_list #
A wrapper for ListView.builder widget that allows "snaping" event to an item at the end of user-scroll.
This widget allows unrestricted scrolling (unlike other widget that only able to "snap" to left/right neighbor at a time).

Support horizontal & vertical list
Use ListView.Builder, means no Animation

You can use this widget to achieve:

Unrestricted scrollable Jumbotron
Show daily entry for Health App and shows its detail directly below the list (reduce number of click)
Scrollable InputSelect, like datetime picker in cupertino













Horizontal Jumbotron List
Horizontal List with infinite-loading
Vertical list with InkWell ListItems
Horizontal with dynamic item size
Horizontal with custom dynamic item size



Getting Started #
In your flutter project pubspec.yaml add the dependency:
dependencies:
...
scroll_snap_list: ^[version]
copied to clipboard
Usage example #
This library doesn't use other library, so it should work out of the box.
Import scroll_snap_list.dart.
import 'package:scroll_snap_list/scroll_snap_list.dart';
copied to clipboard
Add ScrollSnapList in your build method. Make sure to enter correct itemSize (helps with "snapping" process).
Expanded(
child: ScrollSnapList(
onItemFocus: _onItemFocus,
itemSize: 35,
itemBuilder: _buildListItem,
itemCount: data.length,
reverse: true,
),
),
copied to clipboard
Full example:
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:scroll_snap_list/scroll_snap_list.dart';

void main() => runApp(HorizontalListDemo());

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.lightBlueAccent,
child: Text("i:$index\n${data[index]}"),
)
],
),
);
}

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Horizontal List Demo',
home: Scaffold(
appBar: AppBar(
title: Text("Horizontal List"),
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
child: ScrollSnapList(
onItemFocus: _onItemFocus,
itemSize: 35,
itemBuilder: _buildListItem,
itemCount: data.length,
reverse: true,
),
),
_buildItemDetail(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
child: Text("Add Item"),
onPressed: () {
setState(() {
data.add(Random().nextInt(100) + 1);
});
},
),
RaisedButton(
child: Text("Remove Item"),
onPressed: () {
int index = data.length > 1
? Random().nextInt(data.length - 1)
: 0;
setState(() {
data.removeAt(index);
});
},
),
],
)
],
),
),
),
);
}
}
copied to clipboard
Usage with dynamic item size #
This feature is added since version 0.4.0.
We can customize item size with respect to distance between item and center of ScrollSnapList.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Horizontal List Demo',
home: Scaffold(
appBar: AppBar(
title: Text("Horizontal List"),
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
child: ScrollSnapList(
onItemFocus: _onItemFocus,
itemSize: 150,
itemBuilder: _buildListItem,
itemCount: data.length,
dynamicItemSize: true,
// dynamicSizeEquation: customEquation, //optional
),
),
_buildItemDetail(),
],
),
),
),
);
}
copied to clipboard
Important parameters and explanation #



Parameter
Explanation




key
Key for ScrollSnapList, used to call ScrollSnapListState


listViewKey
Key for ListView inside ScrollSnapListState, often used to preserve scroll location


itemBuilder
Same as ListView's itemBuilder


curve
Animation curve when snapping


duration
Animation duration


endOfListTolerance
Pixel tolerance to trigger onReachEnd


focusOnItemTap
Focus to an item when user tap on it. Inactive if the list-item have its own onTap detector (use state-key to help focusing instead).


focusToItem
Method to manually trigger focus to an item. Call with help of GlobalKey<ScrollSnapListState>


margin
Container's margin


itemCount
Number of item in this list


itemSize
Size used is width if scrollDirection is Axis.horizontal, height if Axis.vertical. Composed of the size of each item + its margin/padding.


onItemFocus
Callback function when list snaps/focuses to an item


onReachEnd
Callback function when user reach end of list. E.g. load more data from db


reverse
Same as ListView's reverse to reverse scrollDirection


updateOnScroll
Calls onItemFocus (if it exists) when ScrollUpdateNotification fires


initialIndex
Optional initial position which will not snap until after the first drag


scrollDirection
ListView's scrollDirection


listController
External ScrollController


dynamicItemSize
Scale item's size depending on distance to center


dynamicSizeEquation
Custom equation to determine dynamic item scaling calculation


dynamicItemOpacity
Custom opacity for offset item (single value)


selectedItemAnchor
Anchor location for selected item in the list (Start, Middle, End)


shrinkWrap
ListView's shrinkWrap


scrollPhysics
ListView's scrollPhysics


clipBehavior
ListView's clipBehavior


keyboardDismissBehavior
ListView's keyboardDismissBehavior


allowAnotherDirection
Allow List items to be scrolled using other direction


dispatchScrollNotifications
Control if ScrollNotifications should be dispatched to further ancestors. Default: false



Other Notice #
By default, SnapScrollList set focusOnItemTap as true. Means any tap event on items will trigger snap/focus event to that item.
This behavior use GestureDetector, so if the list's items have their own detector (e.g. InkWell, Button), SnapScrollList unable to trigger snap event on its own. To handle this, we may use GlobalKey<ScrollSnapListState> to trigger the event manually.
Add GlobalKey<ScrollSnapListState> in your widget
GlobalKey<ScrollSnapListState> sslKey = GlobalKey();
copied to clipboard
Add key parameter to SnapScrollList.
ScrollSnapList(
onItemFocus: _onItemFocus,
itemSize: 50,
itemBuilder: _buildListItem,
itemCount: data.length,
key: sslKey,
scrollDirection: Axis.vertical,
)
copied to clipboard
In your buildItem method, call focusToItem method.
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("Do anything here");

//trigger focus manually
sslKey.currentState.focusToItem(index);
},
),
),
);
}
copied to clipboard
Full example for this part can be found in example/vertical_list.dart.
About #
Created by Vincent (MSVCode)
Email: msvcode@gmail.com

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.