diff --git a/.gitignore b/.gitignore index 83c44dd..f596460 100644 --- a/.gitignore +++ b/.gitignore @@ -92,4 +92,6 @@ Temporary Items # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) .fvm -**/.fvm \ No newline at end of file +**/.fvm + +/.idea/ diff --git a/CHANGELOG.md b/CHANGELOG.md index d63c01e..f69f257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## [1.0.0] - 2022 May 26 +* Renamed selectedIndex to index, for interoperability with IndexedStack +* Added null safety +* Updated to Dart 2.16 + ## [0.0.7] - 2020 Sep 30 * Remove hardcode grey color diff --git a/example/lib/simple_tab_selector.dart b/example/lib/simple_tab_selector.dart index 9c45372..305b629 100644 --- a/example/lib/simple_tab_selector.dart +++ b/example/lib/simple_tab_selector.dart @@ -23,7 +23,7 @@ class _SimpleTabSelectorState extends State { body: Container( color: Colors.blueGrey[100], child: AnimatedIndexedStack( - selectedIndex: index, + index: index, children: [ ColoredPage( title: "Red", @@ -49,19 +49,19 @@ class _SimpleTabSelectorState extends State { items: [ BottomNavigationBarItem( icon: Icon(Icons.collections), - title: Text('Red'), + label: 'Red', ), BottomNavigationBarItem( icon: Icon(Icons.collections), - title: Text('Green'), + label: 'Green', ), BottomNavigationBarItem( icon: Icon(Icons.collections), - title: Text('Megenta'), + label: 'Megenta', ), BottomNavigationBarItem( icon: Icon(Icons.collections), - title: Text('Grey'), + label: 'Grey', ), ], currentIndex: index, diff --git a/example/pubspec.lock b/example/pubspec.lock index f79d44d..cf21683 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,7 +7,7 @@ packages: path: ".." relative: true source: path - version: "0.0.6" + version: "0.0.7" args: dependency: transitive description: @@ -21,14 +21,14 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.2" + version: "2.8.2" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" browser_launcher: dependency: transitive description: @@ -56,28 +56,28 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.2.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.3.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.13" + version: "1.16.0" convert: dependency: transitive description: @@ -133,7 +133,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.3.0" file: dependency: transitive description: @@ -199,14 +199,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.8" + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.7.0" mime: dependency: transitive description: @@ -234,7 +241,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.1" pedantic: dependency: transitive description: @@ -309,7 +316,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.2" sse: dependency: transitive description: @@ -323,35 +330,35 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.5" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.17" + version: "0.4.9" typed_data: dependency: transitive description: @@ -379,7 +386,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.2" vm_service: dependency: transitive description: @@ -402,4 +409,4 @@ packages: source: hosted version: "0.5.4" sdks: - dart: ">=2.9.0-14.0.dev <3.0.0" + dart: ">=2.17.0-0 <3.0.0" diff --git a/lib/animated_indexed_stack.dart b/lib/animated_indexed_stack.dart index 7a33154..45128f6 100644 --- a/lib/animated_indexed_stack.dart +++ b/lib/animated_indexed_stack.dart @@ -4,19 +4,20 @@ import 'package:flutter/material.dart'; import 'package:animated_indexed_stack/stack_page.dart'; class AnimatedIndexedStack extends StatefulWidget { + @required - final int selectedIndex; - final List children; - final List pageBuilderList; - final Duration duration; - final RouteTransitionsBuilder transitionBuilder; - final SORT_TIME sortTime; + final int? index; + final List? children; + final List? pageBuilderList; + final Duration? duration; + final RouteTransitionsBuilder? transitionBuilder; + final SORT_TIME? sortTime; const AnimatedIndexedStack({ - Key key, + Key? key, this.pageBuilderList, this.children, - this.selectedIndex, + this.index, this.transitionBuilder, this.sortTime, this.duration, @@ -28,10 +29,11 @@ class AnimatedIndexedStack extends StatefulWidget { class _AnimatedIndexedStackState extends State with TickerProviderStateMixin { + Map _pageIndexToKeyMap = new Map(); - List _pages; - List _list; - int _selectedIndex; + List? _pages; + List? _list; + int? _selectedIndex; int _prevPage = 1; Map _animationControllerList = @@ -51,11 +53,11 @@ class _AnimatedIndexedStackState extends State "Only one property is allowed, either children or pageBuilderList"); } if (widget.children != null) { - _list = widget.children; + _list = widget.children!; } else { - _list = widget.pageBuilderList; + _list = widget.pageBuilderList!; } - _pages = _list.asMap().entries.map((entry) { + _pages = _list!.asMap().entries.map((entry) { final _index = entry.key; // Gerate Unique keys @@ -108,15 +110,15 @@ class _AnimatedIndexedStackState extends State @override Widget build(BuildContext context) { - _selectedIndex = widget.selectedIndex ?? 0; + _selectedIndex = widget.index ?? 0; /// Guards - if (_list.length < 2) { + if (_list!.length < 2) { throw Exception("Atleast 2 children must be provided."); } - if (_selectedIndex >= _list.length || _selectedIndex < 0) { + if (_selectedIndex! >= _list!.length || _selectedIndex! < 0) { throw Exception( - "Index out of bounds. Selected index must be between index of length of children i.e 0..${_list.length - 1}"); + "Index out of bounds. Selected index must be between index of length of children i.e 0..${_list!.length - 1}"); } /// @@ -124,7 +126,7 @@ class _AnimatedIndexedStackState extends State if (_prevPage != _selectedIndex) { final currKey = _pageIndexToKeyMap[_selectedIndex]; final prevKey = _pageIndexToKeyMap[_prevPage]; - Function s = (a, b) { + int Function(Widget, Widget) s = (a, b) { if (a.key == currKey) return 2; if (b.key == currKey) return -2; if (a.key == prevKey) return 1; @@ -133,30 +135,27 @@ class _AnimatedIndexedStackState extends State }; final _sortTime = widget.sortTime ?? SORT_TIME.after; - if (_sortTime == SORT_TIME.before) _pages.sort(s); - - // print(_prevPage); - // print(_selectedIndex); + if (_sortTime == SORT_TIME.before) _pages!.sort(s); - _secondaryAnimationControllerList[currKey].reset(); - if (!_animationControllerList[currKey].isAnimating) - _animationControllerList[currKey].reset(); + _secondaryAnimationControllerList[currKey]!.reset(); + if (!_animationControllerList[currKey]!.isAnimating) + _animationControllerList[currKey]!.reset(); - _secondaryAnimationControllerList[prevKey].forward().orCancel; - _animationControllerList[currKey].forward().orCancel.whenComplete(() { + _secondaryAnimationControllerList[prevKey]!.forward().orCancel; + _animationControllerList[currKey]!.forward().orCancel.whenComplete(() { if (_sortTime == SORT_TIME.after) setState(() { - _pages.sort(s); + _pages!.sort(s); }); }); // print(_pages); // print(_map); // print(_selectedIndex); - _prevPage = _selectedIndex; + _prevPage = _selectedIndex!; } return GestureDetector( child: Stack( - children: _pages, + children: _pages!, ), ); } diff --git a/lib/stack_page.dart b/lib/stack_page.dart index 17b7ffb..4ceb150 100644 --- a/lib/stack_page.dart +++ b/lib/stack_page.dart @@ -2,24 +2,27 @@ import 'package:flutter/material.dart'; import 'package:animated_indexed_stack/route_transitions.dart'; class StackPage extends StatefulWidget { - @required + final Widget child; - final RouteTransitionsBuilder transitionsBuilder; - final Animation animation; - final Animation animationSecondary; + final RouteTransitionsBuilder? transitionsBuilder; + final Animation animation; + final Animation animationSecondary; + const StackPage({ - Key key, - this.child, + Key? key, + required this.child, this.transitionsBuilder, - this.animation, - this.animationSecondary, + required this.animation, + required this.animationSecondary, }) : super(key: key); @override _StackPageState createState() => _StackPageState(); + } class _StackPageState extends State { + @override void initState() { super.initState(); @@ -40,6 +43,7 @@ class _StackPageState extends State { widget.child, ); } + } final defaultTransition = materialTabTransition; diff --git a/pubspec.lock b/pubspec.lock index 9477cdd..7d27b51 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,49 +7,49 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.2" + version: "2.8.2" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.2.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" + version: "1.3.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.13" + version: "1.16.0" fake_async: dependency: transitive description: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.3.0" flutter: dependency: "direct main" description: flutter @@ -66,21 +66,28 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.8" + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.7.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.1" sky_engine: dependency: transitive description: flutter @@ -92,55 +99,48 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.2" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.5" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.17" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" + version: "0.4.9" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.2" sdks: - dart: ">=2.9.0-14.0.dev <3.0.0" + dart: ">=2.17.0-0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 96a78c7..bca0922 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,12 +1,12 @@ name: animated_indexed_stack description: AnimatedIndexedStack is alternative of IndexedStack with ability to provide custom transitions on index change; by providing RouteTransitionsBuilder. Each child of stack can also be manually built using named parameter pageBuilderList which is list of RoutePageBuilder. -version: 0.0.7 +version: 1.0.0 homepage: https://jas.bio repository: https://github.com/jascodes/animated_indexed_stack issue_tracker: https://github.com/jascodes/animated_indexed_stack/issues environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.16.2 <3.0.0" dependencies: flutter: