flutter_chain_scroll 0.0.1
flutter_chain_scroll: ^0.0.1 copied to clipboard
A Flutter package for creating beautiful chain-like stacked scroll views where items stack sequentially with momentum scrolling
Flutter Chain Scroll #
A Flutter package for creating beautiful chain-like stacked scroll views where items stack sequentially with momentum scrolling.
Features #
- 🔗 Chain-like Stacking: Items follow each other in a chain, where each item fully stacks before the next one starts moving
- ⚡ Momentum Scrolling: Physics-based momentum scrolling with smooth deceleration
- 📏 Automatic Height Measurement: Automatically measures item heights - no need to specify them
- 📱 Responsive Height: List height adjusts smoothly as items stack
- 🎨 Flexible API: Use with
itemslist oritemCount- works with any widgets - 🎯 Customizable Gap: Gap multiplier (default 10px × multiplier)
- 🎮 Programmatic Control: Jump or animate to specific scroll positions via controller
- ♿ Accessibility: Built-in Semantics support for screen readers
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_chain_scroll: ^0.0.1
Then run:
flutter pub get
Quick Start #
Basic Usage #
import 'package:flutter_chain_scroll/flutter_chain_scroll.dart';
ChainScrollView(
items: myItems,
itemBuilder: (context, index, [item]) {
return MyCard(item!);
},
gap: 1.0, // 10px (gap is multiplier of 10)
)
With itemCount #
ChainScrollView<void>(
itemCount: 8,
itemBuilder: (context, index, [item]) {
return Container(
height: 120,
child: Center(child: Text('Item ${index + 1}')),
);
},
gap: 1.0,
)
With Programmatic Control #
final controller = ChainScrollController();
ChainScrollView<String>(
controller: controller,
items: myItems,
itemBuilder: (context, index, [item]) {
return MyCard(item!);
},
)
// Later, programmatically control scroll
controller.jumpTo(100.0); // Jump immediately
controller.animateTo(200.0, duration: Duration(milliseconds: 500)); // Animate
API Reference #
ChainScrollView #
Main widget for creating chain-like stacked scroll views:
ChainScrollView<T>({
List<T>? items, // Optional: list of items
int? itemCount, // Optional: number of items (required if items is null)
required Widget Function(BuildContext context, int index, [T? item]) itemBuilder,
Duration animationDuration = const Duration(milliseconds: 250),
double scrollVelocityThreshold = 900.0,
ChainScrollController? controller,
double gap = 1.0, // Gap multiplier (1.0 = 10px, 2.0 = 20px, 0.0 = 0px)
})
ChainScrollController #
Controller for managing scroll state and programmatic control:
final controller = ChainScrollController();
// Access scroll state
controller.scrollOffset;
controller.isScrolling;
controller.scrollVelocity;
// Programmatic control
controller.jumpTo(100.0); // Jump to offset immediately
controller.animateTo(200.0, duration: Duration(milliseconds: 500)); // Animate to offset
// Reset state
controller.reset();
Methods
jumpTo(double offset)- Immediately jump to the given scroll offsetanimateTo(double offset, {Duration? duration, Curve? curve})- Animate to the given scroll offsetreset()- Reset all state to initial values
Behavior #
- Item 0 is always fully visible at the top
- Items 1+ start stacked below item 0
- When scrolling, items move in a chain: each item fully stacks before the next one starts moving
- Last item (itemCount - 1) does not move
- Momentum scrolling continues with physics-based deceleration after drag ends
- Height adjusts responsively as items stack
Gap Multiplier #
The gap parameter is a multiplier of the default 10px:
gap: 0.0→ 0px (no gap)gap: 1.0→ 10px (default)gap: 2.0→ 20pxgap: 9.0→ 90px
Example #
import 'package:flutter/material.dart';
import 'package:flutter_chain_scroll/flutter_chain_scroll.dart';
class MyApp extends StatelessWidget {
final List<String> items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5'];
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
Container(height: 400, color: Colors.blue),
ChainScrollView<String>(
items: items,
itemBuilder: (context, index, [item]) {
return Container(
height: 120,
margin: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.primaries[index % Colors.primaries.length],
borderRadius: BorderRadius.circular(12),
),
child: Center(
child: Text(
item!,
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
);
},
gap: 1.0,
),
],
),
),
);
}
}
License #
This project is licensed under the MIT License.