https://github.com/paul-thommithazhe/scroll-restore
A lightweight Flutter plugin that automatically saves and restores scroll positions for any scrollable widget—across rebuilds, navigation, hot reloads, and app restarts.
https://github.com/paul-thommithazhe/scroll-restore
android dart flutter flutterpackage ios sharedpreferences state-management web
Last synced: 5 days ago
JSON representation
A lightweight Flutter plugin that automatically saves and restores scroll positions for any scrollable widget—across rebuilds, navigation, hot reloads, and app restarts.
- Host: GitHub
- URL: https://github.com/paul-thommithazhe/scroll-restore
- Owner: paul-thommithazhe
- License: mit
- Created: 2025-05-30T12:44:44.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-05-30T15:51:15.000Z (9 months ago)
- Last Synced: 2025-10-23T00:39:21.145Z (4 months ago)
- Topics: android, dart, flutter, flutterpackage, ios, sharedpreferences, state-management, web
- Language: C++
- Homepage:
- Size: 289 KB
- Stars: 2
- Watchers: 0
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# scroll_restore
[](https://pub.dev/packages/scroll_restore)
[](https://github.com/paul-thommithazhe/scroll-restore/actions)
[](LICENSE)
`scroll_restore` is a tiny Flutter package that **automatically saves and restores** the scroll position of any scrollable widget—across rebuilds, hot reloads, navigation pops/pushes, and even app restarts. No boilerplate, no manual state management: just wrap your `ListView`, `GridView`, or any scrollable, and it “just works.”
---
## 🎯 Features
- ✅ Persist scroll offset using `SharedPreferences`
- ✅ Restore position on init (clamps if content is shorter)
- ✅ Simple, one-widget API
- ✅ Zero external dependencies (except `shared_preferences`)
- ✅ Compatible with mobile, web, and desktop Flutter apps
---
## 📦 Installation
```yaml
dependencies:
flutter:
sdk: flutter
scroll_restore: ^0.1.0
Then run:
flutter pub get
🚀 Quick Start
Wrap your scrollable in ScrollRestore, giving it a unique id:
import 'package:flutter/material.dart';
import 'package:scroll_restore/scroll_restore.dart';
class ChatScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Chat')),
body: ScrollRestore(
id: 'chat_screen_list', // unique key per scrollable
builder: (context, controller) {
return ListView.builder(
controller: controller,
itemCount: messages.length,
itemBuilder: (_, index) {
return ListTile(
title: Text(messages[index].text),
);
},
);
},
),
);
}
}
id: persisted key in SharedPreferences. Use a different id for each scrollable you want to remember.
The package takes care of saving .offset on every scroll and jumping to it on next build.
📖 Example
A full example app lives in the example/ folder:
cd example
flutter pub get
flutter run
Try scrolling halfway, hot-reloading, navigating away/back, or restarting the app—you’ll stay at the same scroll position!
🧪 Testing
To run the package’s unit & widget tests:
flutter test
⚙️ CI
We use GitHub Actions to:
flutter analyze
flutter test (package & example)
Workflow file: .github/workflows/dart.yml
🛠️ Caveats & Tips
If the saved offset exceeds the new content’s max scroll, it’s clamped to the end.
Works with any ScrollController-driven widget: ListView, GridView, CustomScrollView, etc.
You can nest multiple ScrollRestore widgets on one screen by using different ids.
📜 Changelog
0.1.0
Initial release with basic save & restore logic
Supports clamp-to-boundary and async init
📝 License
MIT © Paul Thommithazhe
## 👤 Author
Paul Thommithazhe
🔗 GitHub: [https://github.com/paul-thommithazhe](https://github.com/paul-thommithazhe)