import 'package:flutter/material.dart'; class ScrollToId { final ScrollController scrollController; List scrollContentsList = []; Axis scrollDirection; ScrollToId({this.scrollController}); String idPosition() { double sumSize = 0; for (ScrollContentWithKey scrollContents in scrollContentsList) { if (scrollDirection == Axis.vertical) { sumSize += scrollContents.key.currentContext.size.height; } else { sumSize += scrollContents.key.currentContext.size.width; } if (scrollController.offset < sumSize) { return scrollContents.id; } } return null; } Future animateTo(String id, {@required Duration duration, @required Curve curve}) async { Function _function = (double offset) { scrollController.animateTo(offset, duration: duration, curve: curve); }; _scroll(id: id, scrollFunction: _function); } Future jumpTo(String id) async { Function _function = (double offset) { scrollController.jumpTo(offset); }; _scroll(id: id, scrollFunction: _function); } Future animateToNext({@required Duration duration, @required Curve curve}) async { Function _function = (double offset) { scrollController.animateTo(offset, duration: duration, curve: curve); }; _scroll(id: _getNextId(number: 1), scrollFunction: _function); } Future jumpToNext() async { Function _function = (double offset) { scrollController.jumpTo(offset); }; _scroll(id: _getNextId(number: 1), scrollFunction: _function); } Future animateToBefore({@required Duration duration, @required Curve curve}) async { Function _function = (double offset) { scrollController.animateTo(offset, duration: duration, curve: curve); }; _scroll(id: _getNextId(number: -1), scrollFunction: _function); } Future jumpToBefore() async { Function _function = (double offset) { scrollController.jumpTo(offset); }; _scroll(id: _getNextId(number: -1), scrollFunction: _function); } String _getNextId({int number}) { double sumSize = 0; for (int i = 0; i < scrollContentsList.length; i++) { if (scrollDirection == Axis.vertical) { sumSize += scrollContentsList[i].key.currentContext.size.height; } else { sumSize += scrollContentsList[i].key.currentContext.size.width; } if (scrollController.offset < sumSize) { if (number == 1 && i == scrollContentsList.length - 1) return null; if (number == -1 && i == 0) return null; return scrollContentsList[i + number].id; } } return null; } void _scroll({String id, Function scrollFunction}) { double sumSize = 0; for (ScrollContentWithKey scrollContents in scrollContentsList) { if (scrollContents.id == id) { try { if (sumSize < scrollController.position.maxScrollExtent) { scrollFunction(sumSize); break; } else { scrollFunction(scrollController.position.maxScrollExtent); break; } } catch (e) { print('$e'); break; } } else { try { if (scrollDirection == Axis.vertical) { sumSize += scrollContents.key.currentContext.size.height; } else { sumSize += scrollContents.key.currentContext.size.width; } } catch (e) { print('$e'); } } } } } class ScrollContent { final String id; final Widget child; ScrollContent({@required this.id, @required this.child}); } class ScrollContentWithKey { final Widget child; final String id; final GlobalKey key; ScrollContentWithKey({this.child, this.key, this.id}); factory ScrollContentWithKey.fromWithout(ScrollContent scrollContent) { return ScrollContentWithKey(child: scrollContent.child, id: scrollContent.id, key: GlobalKey()); } }