diff --git a/.gitignore b/.gitignore index 47e0b4d..62a5b66 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ build/ **/ios/Flutter/Generated.xcconfig **/ios/Flutter/app.flx **/ios/Flutter/app.zip +**/ios/Flutter/flutter_export_environment.sh **/ios/Flutter/flutter_assets/ **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* diff --git a/CHANGELOG.md b/CHANGELOG.md index 40e4714..b5849cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.4.1] - 11 April 2021. +* Addresses Issue [#111](https://github.com/hanshengchiu/reorderables/issues/111). Resolves ReorderableSliverList ScrollController conflict (thanks [qAison](https://github.com/qAison)). + +## [0.4.0] - 24 March 2021. + +* Initial Null-Safety release. + ## [0.3.2] - 10 March 2020. * Fix health suggestions. @@ -5,7 +12,7 @@ * Supports making individual child non-reorderable. See ReorderableColumn example 1. ## [0.3.0] - 10 Jan 2020. -* Fix: Bad type in onLeave +* Fix: Bad type in onLeave ## [0.2.12] - 22 June 2019. * Removed dependency of FlutterErrorDetails and other ErrorXXX classes. diff --git a/README.md b/README.md index 0bc4e77..26c6bce 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -** Kindly submit PR if you encounter issues and please make sure you're using stable channel releases. Updates might be slow... +** Kindly submit PR if you encounter issues and please make sure you're using stable channel releases.
+** Maintaining open source software ain't easy. If you've commercially used this software, please consider [support](https://www.buymeacoffee.com/q5gkeA4t2). # reorderables [![pub package](https://img.shields.io/pub/v/reorderables.svg)](https://pub.dartlang.org/packages/reorderables) [![Awesome Flutter](https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square)](https://github.com/Solido/awesome-flutter) [![Buy Me A Coffee](https://img.shields.io/badge/Donate-Buy%20Me%20A%20Coffee-yellow.svg)](https://www.buymeacoffee.com/q5gkeA4t2) -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2L56VGH228QJE) Various reorderable, a.k.a. drag and drop, Flutter widgets, including reorderable table, row, column, wrap, and sliver list, that make their children draggable and diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index ca7fe59..3703fd4 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 30 lintOptions { disable 'InvalidPackage' @@ -34,11 +34,11 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.reorderablesexample" - minSdkVersion 16 - targetSdkVersion 28 + minSdkVersion 23 + targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } buildTypes { @@ -56,6 +56,6 @@ flutter { dependencies { testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' } diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 7d46aa3..e19ed50 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -7,15 +7,13 @@ --> - + android:icon="@mipmap/ic_launcher" + android:allowBackup="false"> + - - diff --git a/example/android/app/src/main/java/com/example/reorderablesexample/MainActivity.java b/example/android/app/src/main/java/com/example/reorderablesexample/MainActivity.java index dd9ced6..ada12b8 100644 --- a/example/android/app/src/main/java/com/example/reorderablesexample/MainActivity.java +++ b/example/android/app/src/main/java/com/example/reorderablesexample/MainActivity.java @@ -1,13 +1,5 @@ package com.example.reorderablesexample; -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; +import io.flutter.embedding.android.FlutterActivity; -public class MainActivity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } -} +public class MainActivity extends FlutterActivity { } diff --git a/example/android/build.gradle b/example/android/build.gradle index bb8a303..fab3c2e 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:4.1.3' } } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 7be3d8b..8d7e07a 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,2 +1,17 @@ -org.gradle.jvmargs=-Xmx1536M +## For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx1024m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 +# +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +#Sat Mar 20 19:11:05 EDT 2021 +android.enableJetifier=true android.enableR8=true +android.useAndroidX=true +org.gradle.jvmargs=-Xmx1536M diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 2819f02..8413cf2 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 23 08:50:38 CEST 2017 +#Sat Mar 20 19:06:23 EDT 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 5ca2738..3c3e6a0 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -8,12 +8,7 @@ /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; @@ -29,8 +24,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -40,15 +33,12 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; @@ -62,8 +52,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -73,10 +61,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, - 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, @@ -190,7 +175,6 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -210,7 +194,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; @@ -263,7 +247,6 @@ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -335,7 +318,6 @@ }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -389,7 +371,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a1..919434a 100644 --- a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/example/lib/column_example1.dart b/example/lib/column_example1.dart index ed9e476..5c508fb 100644 --- a/example/lib/column_example1.dart +++ b/example/lib/column_example1.dart @@ -7,7 +7,7 @@ class ColumnExample1 extends StatefulWidget { } class _ColumnExample1State extends State { - List _rows; + late List _rows; @override void initState() { @@ -18,7 +18,11 @@ class _ColumnExample1State extends State { (int index) => ReorderableWidget( reorderable: true, key: ValueKey(index), - child: Text('This is row $index', textScaleFactor: 1.5), + child: Container( + width: double.infinity, + child: Align( + alignment: Alignment.centerLeft, + child: Text('This is row $index', textScaleFactor: 1.5))), )); _rows += [ @@ -34,7 +38,12 @@ class _ColumnExample1State extends State { (int index) => ReorderableWidget( reorderable: true, key: ValueKey(11 + index), - child: Text('This is row $index', textScaleFactor: 1.5), + child: Container( + width: double.infinity, + child: Align( + alignment: Alignment.centerLeft, + child: Text('This is row $index', textScaleFactor: 1.5)), + ), )); } @@ -55,7 +64,8 @@ class _ColumnExample1State extends State { onReorder: _onReorder, onNoReorder: (int index) { //this callback is optional - debugPrint('${DateTime.now().toString().substring(5, 22)} reorder cancelled. index:$index'); + debugPrint( + '${DateTime.now().toString().substring(5, 22)} reorder cancelled. index:$index'); }, ); } diff --git a/example/lib/column_example2.dart b/example/lib/column_example2.dart index 93e8922..6ffd4a5 100644 --- a/example/lib/column_example2.dart +++ b/example/lib/column_example2.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; - import 'package:reorderables/reorderables.dart'; class ColumnExample2 extends StatefulWidget { @@ -8,15 +7,20 @@ class ColumnExample2 extends StatefulWidget { } class _ColumnExample2State extends State { - List _rows; + late List _rows; @override void initState() { super.initState(); _rows = List.generate( 10, - (int index) => Text('This is row $index', - key: ValueKey(index), textScaleFactor: 1.5)); + (int index) => Container( + key: ValueKey(index), + width: double.infinity, + child: Center( + child: Text('This is row $index', textScaleFactor: 1.5), + ), + )); } @override @@ -36,7 +40,8 @@ class _ColumnExample2State extends State { onReorder: _onReorder, onNoReorder: (int index) { //this callback is optional - debugPrint('${DateTime.now().toString().substring(5, 22)} reorder cancelled. index:$index'); + debugPrint( + '${DateTime.now().toString().substring(5, 22)} reorder cancelled. index:$index'); }, )); diff --git a/example/lib/main.dart b/example/lib/main.dart index 442d55f..5de16e4 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,12 +1,12 @@ import 'package:flutter/material.dart'; -import './table_example.dart'; -import './wrap_example.dart'; -import './nested_wrap_example.dart'; import './column_example1.dart'; import './column_example2.dart'; +import './nested_wrap_example.dart'; import './row_example.dart'; import './sliver_example.dart'; +import './table_example.dart'; +import './wrap_example.dart'; void main() => runApp(MyApp()); @@ -22,7 +22,7 @@ class MyApp extends StatelessWidget { } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + MyHomePage({Key? key, required this.title}) : super(key: key); // This widget is the home page of your application. It is stateful, meaning // that it has a State object (defined below) that contains fields that affect @@ -62,37 +62,42 @@ class _MyHomePageState extends State { ), body: _examples[_currentIndex], bottomNavigationBar: BottomNavigationBar( - currentIndex: _currentIndex, // this will be set when a new tab is tapped + fixedColor: _bottomNavigationColor, + showSelectedLabels: true, + showUnselectedLabels: false, + currentIndex: _currentIndex, + // this will be set when a new tab is tapped // type: BottomNavigationBarType.fixed, items: [ BottomNavigationBarItem( - icon: Icon(Icons.grid_on, color: _bottomNavigationColor), - title: Text('ReroderableTable', maxLines: 2, style: TextStyle(color: _bottomNavigationColor)), - ), + icon: Icon(Icons.grid_on, color: _bottomNavigationColor), + tooltip: "ReorderableTable", + label: "Table"), BottomNavigationBarItem( - icon: Icon(Icons.apps, color: _bottomNavigationColor), - title: Text('ReroderableWrap', maxLines: 2, style: TextStyle(color: _bottomNavigationColor)), - ), + icon: Icon(Icons.apps, color: _bottomNavigationColor), + tooltip: "ReorderableWrap", + label: "Wrap"), BottomNavigationBarItem( - icon: Icon(Icons.view_quilt, color: _bottomNavigationColor), - title: Text('Nested ReroderableWrap', maxLines: 3, style: TextStyle(color: _bottomNavigationColor)), - ), + icon: Icon(Icons.view_quilt, color: _bottomNavigationColor), + tooltip: 'Nested ReroderableWrap', + label: "Nested"), BottomNavigationBarItem( - icon: Icon(Icons.more_vert, color: _bottomNavigationColor), - title: Text('ReroderableColumn 1', maxLines: 2, style: TextStyle(color: _bottomNavigationColor)) - ), + icon: Icon(Icons.more_vert, color: _bottomNavigationColor), + tooltip: "ReorderableColumn 1", + label: "Column 1"), BottomNavigationBarItem( - icon: Icon(Icons.more_vert, color: _bottomNavigationColor), - title: Text('ReroderableColumn 2', maxLines: 2, style: TextStyle(color: _bottomNavigationColor)) - ), + icon: Icon(Icons.more_vert, color: _bottomNavigationColor), + tooltip: "ReroderableColumn 2", + label: "Column 2"), BottomNavigationBarItem( - icon: Icon(Icons.more_horiz, color: _bottomNavigationColor), - title: Text('ReroderableRow', maxLines: 2, style: TextStyle(color: _bottomNavigationColor)) - ), + icon: Icon(Icons.more_horiz, color: _bottomNavigationColor), + tooltip: "ReorderableRow", + label: "Row"), BottomNavigationBarItem( - icon: Icon(Icons.calendar_view_day, color: _bottomNavigationColor), - title: Text('ReroderableSliverList', maxLines: 2, style: TextStyle(color: _bottomNavigationColor)) - ), + icon: + Icon(Icons.calendar_view_day, color: _bottomNavigationColor), + tooltip: "ReroderableSliverList", + label: "SliverList"), ], onTap: (int index) { setState(() { diff --git a/example/lib/nested_wrap_example.dart b/example/lib/nested_wrap_example.dart index bff76c8..e1b4f21 100644 --- a/example/lib/nested_wrap_example.dart +++ b/example/lib/nested_wrap_example.dart @@ -4,14 +4,14 @@ import 'package:reorderables/reorderables.dart'; class NestedWrapExample extends StatefulWidget { NestedWrapExample({ - Key key, + Key? key, this.depth = 0, this.valuePrefix = '', this.color, }) : super(key: key); final int depth; final String valuePrefix; - final Color color; + final Color? color; final List _tiles = []; @override @@ -20,8 +20,8 @@ class NestedWrapExample extends StatefulWidget { class _NestedWrapExampleState extends State { // List _tiles; - Color _color; - Color _colorBrighter; + Color? _color; + Color? _colorBrighter; @override void initState() { diff --git a/example/lib/row_example.dart b/example/lib/row_example.dart index 2054928..7872509 100644 --- a/example/lib/row_example.dart +++ b/example/lib/row_example.dart @@ -8,7 +8,7 @@ class RowExample extends StatefulWidget { } class _RowExampleState extends State { - List _columns; + late List _columns; @override void initState() { diff --git a/example/lib/sliver_example.dart b/example/lib/sliver_example.dart index 14087c7..d311d94 100644 --- a/example/lib/sliver_example.dart +++ b/example/lib/sliver_example.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; - import 'package:reorderables/reorderables.dart'; class SliverExample extends StatefulWidget { @@ -8,14 +7,19 @@ class SliverExample extends StatefulWidget { } class _SliverExampleState extends State { - List _rows; + late List _rows; @override void initState() { super.initState(); - _rows = List.generate(50, - (int index) => Text('This is sliver child $index', textScaleFactor: 2) - ); + _rows = List.generate( + 50, + (int index) => Container( + width: double.infinity, + child: Align( + alignment: Alignment.centerLeft, + child: + Text('This is sliver child $index', textScaleFactor: 2)))); } @override @@ -26,9 +30,11 @@ class _SliverExampleState extends State { _rows.insert(newIndex, row); }); } + // Make sure there is a scroll controller attached to the scroll view that contains ReorderableSliverList. // Otherwise an error will be thrown. - ScrollController _scrollController = PrimaryScrollController.of(context) ?? ScrollController(); + ScrollController _scrollController = + PrimaryScrollController.of(context) ?? ScrollController(); return CustomScrollView( // A ScrollController must be included in CustomScrollView, otherwise @@ -40,7 +46,7 @@ class _SliverExampleState extends State { flexibleSpace: FlexibleSpaceBar( title: Text('ReorderableSliverList'), background: Image.network( - 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Yushan' + 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Yushan' '_main_east_peak%2BHuang_Chung_Yu%E9%BB%83%E4%B8%AD%E4%BD%91%2B' '9030.png/640px-Yushan_main_east_peak%2BHuang_Chung_Yu%E9%BB%83' '%E4%B8%AD%E4%BD%91%2B9030.png'), @@ -56,10 +62,12 @@ class _SliverExampleState extends State { onReorder: _onReorder, onNoReorder: (int index) { //this callback is optional - debugPrint('${DateTime.now().toString().substring(5, 22)} reorder cancelled. index:$index'); + debugPrint( + '${DateTime.now().toString().substring(5, 22)} reorder cancelled. index:$index'); }, onReorderStarted: (int index) { - debugPrint('${DateTime.now().toString().substring(5, 22)} reorder started. index:$index'); + debugPrint( + '${DateTime.now().toString().substring(5, 22)} reorder started. index:$index'); }, ) ], diff --git a/example/lib/table_example.dart b/example/lib/table_example.dart index 037335f..6615d04 100644 --- a/example/lib/table_example.dart +++ b/example/lib/table_example.dart @@ -9,7 +9,7 @@ class TableExample extends StatefulWidget { class _TableExampleState extends State { //The children of ReorderableTableRow must be of type ReorderableTableRow - List _itemRows; + late List _itemRows; @override void initState() { diff --git a/example/lib/wrap_example.dart b/example/lib/wrap_example.dart index 9b9148e..b168269 100644 --- a/example/lib/wrap_example.dart +++ b/example/lib/wrap_example.dart @@ -9,7 +9,7 @@ class WrapExample extends StatefulWidget { class _WrapExampleState extends State { final double _iconSize = 90; - List _tiles; + late List _tiles; @override void initState() { diff --git a/example/pubspec.yaml b/example/pubspec.yaml index ee7d80c..62009df 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,6 @@ name: reorderables_example description: Demonstrates how to use the reorderables package.. - +publish_to: none # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. @@ -10,7 +10,7 @@ description: Demonstrates how to use the reorderables package.. version: 1.2.0 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: reorderables: @@ -21,7 +21,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.2 + cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: diff --git a/example/web/favicon.png b/example/web/favicon.png new file mode 100644 index 0000000..8aaa46a Binary files /dev/null and b/example/web/favicon.png differ diff --git a/example/web/icons/Icon-192.png b/example/web/icons/Icon-192.png new file mode 100644 index 0000000..b749bfe Binary files /dev/null and b/example/web/icons/Icon-192.png differ diff --git a/example/web/icons/Icon-512.png b/example/web/icons/Icon-512.png new file mode 100644 index 0000000..88cfd48 Binary files /dev/null and b/example/web/icons/Icon-512.png differ diff --git a/example/web/index.html b/example/web/index.html new file mode 100644 index 0000000..1460b5e --- /dev/null +++ b/example/web/index.html @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + example + + + + + + + + diff --git a/example/web/manifest.json b/example/web/manifest.json new file mode 100644 index 0000000..8c01291 --- /dev/null +++ b/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/lib/generated/i18n.dart b/lib/generated/i18n.dart deleted file mode 100644 index 30fdb7a..0000000 --- a/lib/generated/i18n.dart +++ /dev/null @@ -1,126 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -// ignore_for_file: non_constant_identifier_names -// ignore_for_file: camel_case_types -// ignore_for_file: prefer_single_quotes - -// This file is automatically generated. DO NOT EDIT, all your changes would be lost. -class S implements WidgetsLocalizations { - const S(); - - static S current; - - static const GeneratedLocalizationsDelegate delegate = - GeneratedLocalizationsDelegate(); - - static S of(BuildContext context) => Localizations.of(context, S); - - @override - TextDirection get textDirection => TextDirection.ltr; - -} - -class $en extends S { - const $en(); -} - -class GeneratedLocalizationsDelegate extends LocalizationsDelegate { - const GeneratedLocalizationsDelegate(); - - List get supportedLocales { - return const [ - Locale("en", ""), - ]; - } - - LocaleListResolutionCallback listResolution({Locale fallback, bool withCountry = true}) { - return (List locales, Iterable supported) { - if (locales == null || locales.isEmpty) { - return fallback ?? supported.first; - } else { - return _resolve(locales.first, fallback, supported, withCountry); - } - }; - } - - LocaleResolutionCallback resolution({Locale fallback, bool withCountry = true}) { - return (Locale locale, Iterable supported) { - return _resolve(locale, fallback, supported, withCountry); - }; - } - - @override - Future load(Locale locale) { - final String lang = getLang(locale); - if (lang != null) { - switch (lang) { - case "en": - S.current = const $en(); - return SynchronousFuture(S.current); - default: - // NO-OP. - } - } - S.current = const S(); - return SynchronousFuture(S.current); - } - - @override - bool isSupported(Locale locale) => _isSupported(locale, true); - - @override - bool shouldReload(GeneratedLocalizationsDelegate old) => false; - - /// - /// Internal method to resolve a locale from a list of locales. - /// - Locale _resolve(Locale locale, Locale fallback, Iterable supported, bool withCountry) { - if (locale == null || !_isSupported(locale, withCountry)) { - return fallback ?? supported.first; - } - - final Locale languageLocale = Locale(locale.languageCode, ""); - if (supported.contains(locale)) { - return locale; - } else if (supported.contains(languageLocale)) { - return languageLocale; - } else { - final Locale fallbackLocale = fallback ?? supported.first; - return fallbackLocale; - } - } - - /// - /// Returns true if the specified locale is supported, false otherwise. - /// - bool _isSupported(Locale locale, bool withCountry) { - if (locale != null) { - for (Locale supportedLocale in supportedLocales) { - // Language must always match both locales. - if (supportedLocale.languageCode != locale.languageCode) { - continue; - } - - // If country code matches, return this locale. - if (supportedLocale.countryCode == locale.countryCode) { - return true; - } - - // If no country requirement is requested, check if this locale has no country. - if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)) { - return true; - } - } - } - return false; - } -} - -String getLang(Locale l) => l == null - ? null - : l.countryCode != null && l.countryCode.isEmpty - ? l.languageCode - : l.toString(); diff --git a/lib/src/rendering/tabluar_flex.dart b/lib/src/rendering/tabluar_flex.dart index 9c5b2ab..5202348 100644 --- a/lib/src/rendering/tabluar_flex.dart +++ b/lib/src/rendering/tabluar_flex.dart @@ -1,32 +1,15 @@ -import 'dart:math' as math; import 'dart:collection'; +import 'dart:math' as math; -import 'package:flutter/rendering.dart'; import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; -bool _startIsTopLeft(Axis direction, TextDirection textDirection, +bool? _startIsTopLeft(Axis direction, TextDirection? textDirection, VerticalDirection verticalDirection) { - assert(direction != null); // If the relevant value of textDirection or verticalDirection is null, this returns null too. - switch (direction) { - case Axis.horizontal: - switch (textDirection) { - case TextDirection.ltr: - return true; - case TextDirection.rtl: - return false; - } - break; - case Axis.vertical: - switch (verticalDirection) { - case VerticalDirection.down: - return true; - case VerticalDirection.up: - return false; - } - break; - } - return null; + return direction == Axis.horizontal + ? (textDirection == null ? null : textDirection == TextDirection.ltr) + : verticalDirection == VerticalDirection.down; } typedef _ChildSizingFunction = double Function(RenderBox child, double extent); @@ -37,15 +20,15 @@ class RenderTabluarFlex extends RenderFlex { /// By default, the flex layout is horizontal and children are aligned to the /// start of the main axis and the center of the cross axis. RenderTabluarFlex({ - List children, + List? children, Axis direction = Axis.horizontal, MainAxisSize mainAxisSize = MainAxisSize.max, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, - TextBaseline textBaseline, - Decoration decoration, + TextBaseline? textBaseline, + Decoration? decoration, ImageConfiguration configuration = ImageConfiguration.empty, }) : _decoration = decoration, _configuration = configuration, @@ -60,15 +43,15 @@ class RenderTabluarFlex extends RenderFlex { textBaseline: textBaseline, ); - BoxPainter _painter; + BoxPainter? _painter; /// What decoration to paint. /// /// Commonly a [BoxDecoration]. - Decoration get decoration => _decoration; - Decoration _decoration; + Decoration? get decoration => _decoration; + Decoration? _decoration; - set decoration(Decoration value) { + set decoration(Decoration? value) { // assert(value != null); if (value == _decoration) return; _painter?.dispose(); @@ -87,7 +70,6 @@ class RenderTabluarFlex extends RenderFlex { ImageConfiguration _configuration; set configuration(ImageConfiguration value) { - assert(value != null); if (value == _configuration) return; _configuration = value; markNeedsPaint(); @@ -107,52 +89,37 @@ class RenderTabluarFlex extends RenderFlex { } bool get _debugHasNecessaryDirections { - assert(direction != null); - assert(crossAxisAlignment != null); if (firstChild != null && lastChild != firstChild) { // i.e. there's more than one child - switch (direction) { - case Axis.horizontal: - assert(textDirection != null, - 'Horizontal $runtimeType with multiple children has a null textDirection, so the layout order is undefined.'); - break; - case Axis.vertical: - assert(verticalDirection != null, - 'Vertical $runtimeType with multiple children has a null verticalDirection, so the layout order is undefined.'); - break; - } + assert( + direction == Axis.vertical || textDirection != null, + 'Horizontal $runtimeType with multiple children has a ' + 'null textDirection, so the layout order is undefined.'); } if (mainAxisAlignment == MainAxisAlignment.start || mainAxisAlignment == MainAxisAlignment.end) { - switch (direction) { - case Axis.horizontal: - assert(textDirection != null, - 'Horizontal $runtimeType with $mainAxisAlignment has a null textDirection, so the alignment cannot be resolved.'); - break; - case Axis.vertical: - assert(verticalDirection != null, - 'Vertical $runtimeType with $mainAxisAlignment has a null verticalDirection, so the alignment cannot be resolved.'); - break; - } + assert( + direction == Axis.vertical || textDirection != null, + 'Horizontal $runtimeType with $mainAxisAlignment has a null ' + 'textDirection, so the alignment cannot be resolved.'); } if (crossAxisAlignment == CrossAxisAlignment.start || crossAxisAlignment == CrossAxisAlignment.end) { - switch (direction) { - case Axis.horizontal: - assert(verticalDirection != null, - 'Horizontal $runtimeType with $crossAxisAlignment has a null verticalDirection, so the alignment cannot be resolved.'); - break; - case Axis.vertical: - assert(textDirection != null, - 'Vertical $runtimeType with $crossAxisAlignment has a null textDirection, so the alignment cannot be resolved.'); - break; - } + assert( + direction == Axis.horizontal || textDirection != null, + 'Vertical $runtimeType with $crossAxisAlignment has a null ' + 'textDirection, so the alignment cannot be resolved.'); } return true; } // Set during layout if overflow occurred on the main axis. - double _overflow; + double _overflow = 0; + + /// + /// Determines whether the current overflow value is greater than zero. + /// + bool get _hasOverflow => _overflow > 0.0; final ListQueue> layoutCallbackQueue = ListQueue>(); @@ -168,10 +135,10 @@ class RenderTabluarFlex extends RenderFlex { // } double _getIntrinsicSize( - {Axis sizingDirection, - double + {required Axis sizingDirection, + required double extent, // the extent in the direction that isn't the sizing direction - _ChildSizingFunction + required _ChildSizingFunction childSize // a method to find the size in the sizing direction }) { if (direction == sizingDirection) { @@ -181,7 +148,7 @@ class RenderTabluarFlex extends RenderFlex { double totalFlex = 0.0; double inflexibleSpace = 0.0; double maxFlexFractionSoFar = 0.0; - RenderBox child = firstChild; + RenderBox? child = firstChild; while (child != null) { final int flex = _getFlex(child); totalFlex += flex; @@ -192,7 +159,8 @@ class RenderTabluarFlex extends RenderFlex { } else { inflexibleSpace += childSize(child, extent); } - final FlexParentData childParentData = child.parentData; + final FlexParentData childParentData = + child.parentData! as FlexParentData; child = childParentData.nextSibling; } return maxFlexFractionSoFar * totalFlex + inflexibleSpace; @@ -208,7 +176,7 @@ class RenderTabluarFlex extends RenderFlex { int totalFlex = 0; double inflexibleSpace = 0.0; double maxCrossSize = 0.0; - RenderBox child = firstChild; + RenderBox? child = firstChild; Map maxGrandchildCrossSize = {}; while (child != null) { final int flex = _getFlex(child); @@ -227,7 +195,7 @@ class RenderTabluarFlex extends RenderFlex { break; } - RenderTabluarFlex tabluarFlexChild = + RenderTabluarFlex? tabluarFlexChild = _findTabluarFlexDescendant(child); if (tabluarFlexChild is RenderTabluarFlex) { // RenderTabluarFlex _child = child as RenderTabluarFlex; @@ -245,7 +213,8 @@ class RenderTabluarFlex extends RenderFlex { inflexibleSpace += mainSize; maxCrossSize = math.max(maxCrossSize, crossSize); } - final FlexParentData childParentData = child.parentData; + final FlexParentData childParentData = + child.parentData! as FlexParentData; child = childParentData.nextSibling; } @@ -260,7 +229,7 @@ class RenderTabluarFlex extends RenderFlex { final int flex = _getFlex(child); if (flex > 0) { double mainSize = spacePerFlex * flex; - RenderTabluarFlex tabluarFlexChild = + RenderTabluarFlex? tabluarFlexChild = _findTabluarFlexDescendant(child); if (tabluarFlexChild is RenderTabluarFlex) { List grandchildren = @@ -275,7 +244,8 @@ class RenderTabluarFlex extends RenderFlex { // maxCrossSize = math.max(maxCrossSize, childSize(child, spacePerFlex * flex)); maxCrossSize = math.max(maxCrossSize, childSize(child, mainSize)); } - final FlexParentData childParentData = child.parentData; + final FlexParentData childParentData = + child.parentData! as FlexParentData; child = childParentData.nextSibling; } @@ -327,41 +297,27 @@ class RenderTabluarFlex extends RenderFlex { } int _getFlex(RenderBox child) { - final FlexParentData childParentData = child.parentData; - return childParentData.flex ?? 0; + final FlexParentData? childParentData = child.parentData as FlexParentData; + return childParentData?.flex ?? 0; } - FlexFit _getFit(RenderBox child) { - final FlexParentData childParentData = child.parentData; - return childParentData.fit ?? FlexFit.tight; + FlexFit _getFit(RenderBox? child) { + final FlexParentData? childParentData = child?.parentData as FlexParentData; + return childParentData?.fit ?? FlexFit.tight; } - double _getCrossSize(RenderBox child) { - switch (direction) { - case Axis.horizontal: - return child.size.height; - case Axis.vertical: - return child.size.width; - } - return null; - } + double _getCrossSize(RenderBox child) => + direction == Axis.horizontal ? child.size.height : child.size.width; - double _getMainSize(RenderBox child) { - switch (direction) { - case Axis.horizontal: - return child.size.width; - case Axis.vertical: - return child.size.height; - } - return null; - } + double _getMainSize(RenderBox child) => + direction == Axis.horizontal ? child.size.width : child.size.height; - RenderTabluarFlex _findTabluarFlexDescendant(RenderBox child) { - RenderObject curDescendant = child; + RenderTabluarFlex? _findTabluarFlexDescendant(RenderBox child) { + RenderObject? curDescendant = child; ListQueue childrenQueue = ListQueue(); while (curDescendant != null && curDescendant is! RenderTabluarFlex) { // RenderObject firstChildRenderer; - curDescendant.visitChildren((RenderObject renderObject) { + curDescendant!.visitChildren((RenderObject renderObject) { // firstChildRenderer ??= renderObject; if (curDescendant is! RenderTabluarFlex) { if (renderObject is RenderTabluarFlex) { @@ -378,8 +334,7 @@ class RenderTabluarFlex extends RenderFlex { } } - RenderTabluarFlex tabluarFlexDescendant = curDescendant; - return tabluarFlexDescendant; + return curDescendant == null ? null : curDescendant as RenderTabluarFlex; } @override @@ -388,7 +343,6 @@ class RenderTabluarFlex extends RenderFlex { // Determine used flex factor, size inflexible items, calculate free space. int totalFlex = 0; int totalChildren = 0; - assert(constraints != null); final double maxMainSize = direction == Axis.horizontal ? constraints.maxWidth : constraints.maxHeight; @@ -399,7 +353,7 @@ class RenderTabluarFlex extends RenderFlex { Map tabluarFlexDescendants = {}; void _layoutChild(RenderBox child, BoxConstraints constraints) { - RenderTabluarFlex tabluarFlexChild = _findTabluarFlexDescendant(child); + RenderTabluarFlex? tabluarFlexChild = _findTabluarFlexDescendant(child); // debugPrint('this:$this _layoutChild: child:$child tabluarFlexChild:$tabluarFlexChild'); if (tabluarFlexChild != null) { //when this is laying out its child (and descendants), this function will be called. So that we can get the grandchild's size @@ -466,12 +420,12 @@ class RenderTabluarFlex extends RenderFlex { case Axis.horizontal: innerConstraints = innerConstraints.copyWith( minWidth: math.max(innerConstraints.minWidth, - minChildrenMainSize[childIndex])); + minChildrenMainSize[childIndex]!)); break; case Axis.vertical: innerConstraints = innerConstraints.copyWith( minHeight: math.max(innerConstraints.minHeight, - minChildrenMainSize[childIndex])); + minChildrenMainSize[childIndex]!)); break; } } @@ -484,11 +438,12 @@ class RenderTabluarFlex extends RenderFlex { double crossSize = 0.0; double allocatedSize = 0.0; // Sum of the sizes of the non-flexible children. - RenderBox child = firstChild; - RenderBox lastFlexChild; + RenderBox? child = firstChild; + RenderBox? lastFlexChild; int childIndex = 0; while (child != null) { - final FlexParentData childParentData = child.parentData; + final FlexParentData childParentData = + child.parentData! as FlexParentData; totalChildren++; final int flex = _getFlex(child); if (flex > 0) { @@ -512,16 +467,16 @@ class RenderTabluarFlex extends RenderFlex { 'axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to ' 'expand to fill the remaining space in the $axis direction.'; final StringBuffer information = StringBuffer(); - RenderBox node = this; + RenderBox? node = this; switch (direction) { case Axis.horizontal: - while (!node.constraints.hasBoundedWidth && - node.parent is RenderBox) node = node.parent; + while (!node!.constraints.hasBoundedWidth && + node.parent is RenderBox) node = node.parent as RenderBox; if (!node.constraints.hasBoundedWidth) node = null; break; case Axis.vertical: - while (!node.constraints.hasBoundedHeight && - node.parent is RenderBox) node = node.parent; + while (!node!.constraints.hasBoundedHeight && + node.parent is RenderBox) node = node.parent as RenderBox; if (!node.constraints.hasBoundedHeight) node = null; break; } @@ -556,7 +511,7 @@ class RenderTabluarFlex extends RenderFlex { 'If none of the above helps enough to fix this problem, please don\'t hesitate to file a bug:\n' ' https://github.com/flutter/flutter/issues/new?template=BUG.md'); }()); - totalFlex += childParentData.flex; + totalFlex += childParentData.flex!; lastFlexChild = child; } else { BoxConstraints innerConstraints = _innerConstraints(childIndex); @@ -616,7 +571,6 @@ class RenderTabluarFlex extends RenderFlex { minChildExtent = 0.0; break; } - assert(minChildExtent != null); BoxConstraints innerConstraints; if (crossAxisAlignment == CrossAxisAlignment.stretch) { switch (direction) { @@ -657,12 +611,12 @@ class RenderTabluarFlex extends RenderFlex { case Axis.horizontal: innerConstraints = innerConstraints.copyWith( minWidth: math.max(innerConstraints.minWidth, - minChildrenMainSize[childIndex])); + minChildrenMainSize[childIndex]!)); break; case Axis.vertical: innerConstraints = innerConstraints.copyWith( minHeight: math.max(innerConstraints.minHeight, - minChildrenMainSize[childIndex])); + minChildrenMainSize[childIndex]!)); break; } } @@ -684,12 +638,13 @@ class RenderTabluarFlex extends RenderFlex { 'To use FlexAlignItems.baseline, you must also specify which baseline to use using the "baseline" argument.'); return true; }()); - final double distance = - child.getDistanceToBaseline(textBaseline, onlyReal: true); + final double? distance = + child.getDistanceToBaseline(textBaseline!, onlyReal: true); if (distance != null) maxBaselineDistance = math.max(maxBaselineDistance, distance); } - final FlexParentData childParentData = child.parentData; + final FlexParentData childParentData = + child.parentData! as FlexParentData; child = childParentData.nextSibling; childIndex++; } @@ -706,7 +661,7 @@ class RenderTabluarFlex extends RenderFlex { child = firstChild; while (child != null) { // debugPrint('this:$this relayout child:$child'); - BoxConstraints innerConstraints = childrenConstraints[child]; + BoxConstraints innerConstraints = childrenConstraints[child]!; switch (direction) { case Axis.horizontal: innerConstraints = innerConstraints.copyWith( @@ -725,7 +680,7 @@ class RenderTabluarFlex extends RenderFlex { callbackCalled = true; } - RenderTabluarFlex tabluarFlexChild = tabluarFlexDescendants[child]; + RenderTabluarFlex tabluarFlexChild = tabluarFlexDescendants[child]!; tabluarFlexChild.layoutCallbackQueue.addLast(_childLayoutCallback); tabluarFlexChild.minMainSizesQueue.addLast(maxGrandchildrenCrossSize); tabluarFlexChild.layout(innerConstraints, parentUsesSize: true); @@ -740,7 +695,8 @@ class RenderTabluarFlex extends RenderFlex { } crossSize = math.max(crossSize, _getCrossSize(child)); - final FlexParentData childParentData = child.parentData; + final FlexParentData childParentData = + child.parentData! as FlexParentData; child = childParentData.nextSibling; } // debugPrint('this:$this updated crossSize:$crossSize'); @@ -810,7 +766,8 @@ class RenderTabluarFlex extends RenderFlex { flipMainAxis ? actualSize - leadingSpace : leadingSpace; child = firstChild; while (child != null) { - final FlexParentData childParentData = child.parentData; + final FlexParentData childParentData = + child.parentData! as FlexParentData; double childCrossPosition; switch (crossAxisAlignment) { case CrossAxisAlignment.start: @@ -831,8 +788,8 @@ class RenderTabluarFlex extends RenderFlex { childCrossPosition = 0.0; if (direction == Axis.horizontal) { assert(textBaseline != null); - final double distance = - child.getDistanceToBaseline(textBaseline, onlyReal: true); + final double? distance = + child.getDistanceToBaseline(textBaseline!, onlyReal: true); if (distance != null) childCrossPosition = maxBaselineDistance - distance; } @@ -872,7 +829,7 @@ class RenderTabluarFlex extends RenderFlex { @override void paint(PaintingContext context, Offset offset) { - if (_overflow <= 0.0) { + if (!_hasOverflow) { defaultPaint(context, offset); return; } @@ -881,10 +838,10 @@ class RenderTabluarFlex extends RenderFlex { if (size.isEmpty) return; if (_decoration != null) { - _painter ??= _decoration.createBoxPainter(markNeedsPaint); + _painter ??= _decoration!.createBoxPainter(markNeedsPaint); final ImageConfiguration filledConfiguration = configuration.copyWith(size: size); - _painter.paint(context.canvas, offset, filledConfiguration); + _painter!.paint(context.canvas, offset, filledConfiguration); } // We have overflow. Clip it. @@ -934,13 +891,13 @@ class RenderTabluarFlex extends RenderFlex { } @override - Rect describeApproximatePaintClip(RenderObject child) => - _overflow > 0.0 ? Offset.zero & size : null; + Rect? describeApproximatePaintClip(RenderObject child) => + _hasOverflow ? Offset.zero & size : null; @override String toStringShort() { String header = super.toStringShort(); - if (_overflow is double && _overflow > 0.0) header += ' OVERFLOWING'; + if (_hasOverflow) header += ' OVERFLOWING'; return header; } } diff --git a/lib/src/rendering/transitions.dart b/lib/src/rendering/transitions.dart index 99d99d7..e2b5c6f 100644 --- a/lib/src/rendering/transitions.dart +++ b/lib/src/rendering/transitions.dart @@ -1,13 +1,12 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/animation.dart'; -import 'package:flutter/foundation.dart'; class RenderSizeTransitionWithIntrinsicSize extends RenderProxyBox { RenderSizeTransitionWithIntrinsicSize({ this.axis = Axis.vertical, - @required this.sizeFactor, - RenderBox child, - }) : assert(sizeFactor != null), + required this.sizeFactor, + RenderBox? child, + }) : // _axis = axis, // _sizeFactor = sizeFactor, super(child); @@ -26,6 +25,7 @@ class RenderSizeTransitionWithIntrinsicSize extends RenderProxyBox { @override double computeMinIntrinsicWidth(double height) { + final child = this.child; if (child != null) { double childWidth = child.getMinIntrinsicWidth(height); return axis == Axis.horizontal @@ -37,6 +37,7 @@ class RenderSizeTransitionWithIntrinsicSize extends RenderProxyBox { @override double computeMaxIntrinsicWidth(double height) { + final child = this.child; if (child != null) { double childWidth = child.getMaxIntrinsicWidth(height); return axis == Axis.horizontal @@ -48,6 +49,7 @@ class RenderSizeTransitionWithIntrinsicSize extends RenderProxyBox { @override double computeMinIntrinsicHeight(double width) { + final child = this.child; if (child != null) { double childHeight = child.getMinIntrinsicHeight(width); return axis == Axis.vertical @@ -59,6 +61,7 @@ class RenderSizeTransitionWithIntrinsicSize extends RenderProxyBox { @override double computeMaxIntrinsicHeight(double width) { + final child = this.child; if (child != null) { double childHeight = child.getMaxIntrinsicHeight(width); return axis == Axis.vertical diff --git a/lib/src/rendering/wrap.dart b/lib/src/rendering/wrap.dart index 4b739d7..c41ba9c 100644 --- a/lib/src/rendering/wrap.dart +++ b/lib/src/rendering/wrap.dart @@ -19,14 +19,14 @@ class WrapWithMainAxisCountParentData extends WrapParentData { class RenderWrapWithMainAxisCount extends RenderWrap { RenderWrapWithMainAxisCount({ - List children, + List? children, Axis direction = Axis.horizontal, WrapAlignment alignment = WrapAlignment.start, double spacing = 0.0, WrapAlignment runAlignment = WrapAlignment.start, double runSpacing = 0.0, WrapCrossAlignment crossAxisAlignment = WrapCrossAlignment.start, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, this.minMainAxisCount, this.maxMainAxisCount, @@ -36,24 +36,25 @@ class RenderWrapWithMainAxisCount extends RenderWrap { // _minMainAxisCount = minMainAxisCount, // _maxMainAxisCount = maxMainAxisCount, super( - children: children, - direction: direction, - alignment: alignment, - spacing: spacing, - runAlignment: runAlignment, - runSpacing: runSpacing, - crossAxisAlignment: crossAxisAlignment, - textDirection: textDirection, - verticalDirection: verticalDirection); - - int minMainAxisCount; + children: children, + direction: direction, + alignment: alignment, + spacing: spacing, + runAlignment: runAlignment, + runSpacing: runSpacing, + crossAxisAlignment: crossAxisAlignment, + textDirection: textDirection, + verticalDirection: verticalDirection, + ); + + int? minMainAxisCount; // int get minMainAxisCount => _minMainAxisCount; // set minMainAxisCount(int value) { // _minMainAxisCount = value; // } - int maxMainAxisCount; + int? maxMainAxisCount; // int get maxMainAxisCount => _maxMainAxisCount; // set maxMainAxisCount(int value) { @@ -61,60 +62,32 @@ class RenderWrapWithMainAxisCount extends RenderWrap { // } bool get _debugHasNecessaryDirections { - assert(direction != null); - assert(alignment != null); - assert(runAlignment != null); - assert(crossAxisAlignment != null); if (firstChild != null && lastChild != firstChild) { // i.e. there's more than one child - switch (direction) { - case Axis.horizontal: - assert(textDirection != null, - 'Horizontal $runtimeType with multiple children has a null textDirection, so the layout order is undefined.'); - break; - case Axis.vertical: - assert(verticalDirection != null, - 'Vertical $runtimeType with multiple children has a null verticalDirection, so the layout order is undefined.'); - break; - } + assert( + direction == Axis.vertical || textDirection != null, + 'Horizontal $runtimeType with multiple children has a null ' + 'textDirection, so the layout order is undefined.'); } if (alignment == WrapAlignment.start || alignment == WrapAlignment.end) { - switch (direction) { - case Axis.horizontal: - assert(textDirection != null, - 'Horizontal $runtimeType with alignment $alignment has a null textDirection, so the alignment cannot be resolved.'); - break; - case Axis.vertical: - assert(verticalDirection != null, - 'Vertical $runtimeType with alignment $alignment has a null verticalDirection, so the alignment cannot be resolved.'); - break; - } + assert( + direction == Axis.vertical || textDirection != null, + 'Horizontal $runtimeType with alignment $alignment has a null ' + 'textDirection, so the alignment cannot be resolved.'); } if (runAlignment == WrapAlignment.start || runAlignment == WrapAlignment.end) { - switch (direction) { - case Axis.horizontal: - assert(verticalDirection != null, - 'Horizontal $runtimeType with runAlignment $runAlignment has a null verticalDirection, so the alignment cannot be resolved.'); - break; - case Axis.vertical: - assert(textDirection != null, - 'Vertical $runtimeType with runAlignment $runAlignment has a null textDirection, so the alignment cannot be resolved.'); - break; - } + assert( + direction == Axis.horizontal || textDirection != null, + 'Horizontal $runtimeType with runAlignment $runAlignment has a null ' + 'verticalDirection, so the alignment cannot be resolved.'); } if (crossAxisAlignment == WrapCrossAlignment.start || crossAxisAlignment == WrapCrossAlignment.end) { - switch (direction) { - case Axis.horizontal: - assert(verticalDirection != null, - 'Horizontal $runtimeType with crossAxisAlignment $crossAxisAlignment has a null verticalDirection, so the alignment cannot be resolved.'); - break; - case Axis.vertical: - assert(textDirection != null, - 'Vertical $runtimeType with crossAxisAlignment $crossAxisAlignment has a null textDirection, so the alignment cannot be resolved.'); - break; - } + assert( + direction == Axis.horizontal || textDirection != null, + 'Vertical $runtimeType with crossAxisAlignment $crossAxisAlignment ' + 'has a null textDirection, so the alignment cannot be resolved.'); } return true; } @@ -132,7 +105,7 @@ class RenderWrapWithMainAxisCount extends RenderWrap { double runWidth = 0.0; double runHeight = 0.0; int childCount = 0; - RenderBox child = firstChild; + RenderBox? child = firstChild; int minChildCount = minMainAxisCount ?? 1; int maxChildCount = maxMainAxisCount ?? -1; while (child != null) { @@ -167,7 +140,7 @@ class RenderWrapWithMainAxisCount extends RenderWrap { double runHeight = 0.0; double runWidth = 0.0; int childCount = 0; - RenderBox child = firstChild; + RenderBox? child = firstChild; int minChildCount = minMainAxisCount ?? 1; int maxChildCount = maxMainAxisCount ?? -1; while (child != null) { @@ -199,14 +172,14 @@ class RenderWrapWithMainAxisCount extends RenderWrap { { // Axis sizingDirection, // double extent, // the extent in the direction that isn't the sizing direction - int childCountAlongMainAxis, - _ChildSizingFunction + required int childCountAlongMainAxis, + required _ChildSizingFunction childSize // a method to find the size in the sizing direction }) { double runMainAxisExtent = 0.0; double maxRunMainAxisExtent = 0.0; int childCount = 0; - RenderBox child = firstChild; + RenderBox? child = firstChild; // final List runMainAxisExtents = []; while (child != null) { final double childMainAxisExtent = childSize(child, double.infinity); @@ -238,7 +211,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { case Axis.vertical: return _computeIntrinsicWidthForHeight(height); } - return null; } @override @@ -252,7 +224,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { case Axis.vertical: return _computeIntrinsicWidthForHeight(height); } - return null; } @override @@ -266,7 +237,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { childSize: (RenderBox child, double extent) => child.getMinIntrinsicHeight(extent)); } - return null; } @override @@ -280,7 +250,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { childSize: (RenderBox child, double extent) => child.getMaxIntrinsicHeight(extent)); } - return null; } double _getMainAxisExtent(RenderBox child) { @@ -290,7 +259,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { case Axis.vertical: return child.size.height; } - return 0.0; } double _getCrossAxisExtent(RenderBox child) { @@ -300,7 +268,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { case Axis.vertical: return child.size.width; } - return 0.0; } Offset _getOffset(double mainAxisOffset, double crossAxisOffset) { @@ -310,7 +277,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { case Axis.vertical: return Offset(crossAxisOffset, mainAxisOffset); } - return Offset.zero; } double _getChildCrossAxisOffset(bool flipCrossAxis, double runCrossAxisExtent, @@ -324,17 +290,16 @@ class RenderWrapWithMainAxisCount extends RenderWrap { case WrapCrossAlignment.center: return freeSpace / 2.0; } - return 0.0; } bool _hasVisualOverflow = false; - List childRunIndexes; + late List childRunIndexes; @override void performLayout() { assert(_debugHasNecessaryDirections); _hasVisualOverflow = false; - RenderBox child = firstChild; + RenderBox? child = firstChild; if (child == null) { size = constraints.smallest; return; @@ -357,8 +322,6 @@ class RenderWrapWithMainAxisCount extends RenderWrap { if (textDirection == TextDirection.rtl) flipCrossAxis = true; break; } - assert(childConstraints != null); - assert(mainAxisLimit != null); final double spacing = this.spacing; final double runSpacing = this.runSpacing; final List<_RunMetrics> runMetrics = <_RunMetrics>[]; @@ -394,7 +357,8 @@ class RenderWrapWithMainAxisCount extends RenderWrap { if (childCount > 0) runMainAxisExtent += spacing; runCrossAxisExtent = math.max(runCrossAxisExtent, childCrossAxisExtent); childCount += 1; - final WrapWithMainAxisCountParentData childParentData = child.parentData; + final WrapWithMainAxisCountParentData childParentData = + child.parentData! as WrapWithMainAxisCountParentData; childParentData._runIndex = runMetrics.length; child = childParentData.nextSibling; childRunIndexes.add(runIndex); @@ -505,7 +469,7 @@ class RenderWrapWithMainAxisCount extends RenderWrap { while (child != null) { final WrapWithMainAxisCountParentData childParentData = - child.parentData; + child.parentData! as WrapWithMainAxisCountParentData; if (childParentData._runIndex != i) break; final double childMainAxisExtent = _getMainAxisExtent(child); final double childCrossAxisExtent = _getCrossAxisExtent(child); diff --git a/lib/src/widgets/basic.dart b/lib/src/widgets/basic.dart index 5762ff2..62fab31 100644 --- a/lib/src/widgets/basic.dart +++ b/lib/src/widgets/basic.dart @@ -12,10 +12,9 @@ class SafeStatefulBuilder extends StatefulWidget { /// /// The [builder] argument must not be null. const SafeStatefulBuilder({ - Key key, - @required this.builder, - }) : assert(builder != null), - super(key: key); + required this.builder, + Key? key, + }) : super(key: key); /// Called to obtain the child widget. /// diff --git a/lib/src/widgets/passthrough_overlay.dart b/lib/src/widgets/passthrough_overlay.dart index 3df491f..7226627 100644 --- a/lib/src/widgets/passthrough_overlay.dart +++ b/lib/src/widgets/passthrough_overlay.dart @@ -5,9 +5,8 @@ import 'dart:async'; import 'dart:collection'; -import 'package:flutter/material.dart'; - import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/scheduler.dart'; @@ -61,13 +60,10 @@ class PassthroughOverlayEntry { /// [Overlay.of] and then call [OverlayState.insert]. To remove the entry, /// call [remove] on the overlay entry itself. PassthroughOverlayEntry({ - @required this.builder, + required this.builder, bool opaque = false, bool maintainState = false, - }) : assert(builder != null), - assert(opaque != null), - assert(maintainState != null), - _opaque = opaque, + }) : _opaque = opaque, _maintainState = maintainState; /// This entry will include the widget built by this builder in the overlay at @@ -84,11 +80,12 @@ class PassthroughOverlayEntry { /// set. bool get opaque => _opaque; bool _opaque; + set opaque(bool value) { if (_opaque == value) return; _opaque = value; assert(_overlay != null); - _overlay._didChangeEntryOpacity(); + _overlay!._didChangeEntryOpacity(); } /// Whether this entry must be included in the tree even if there is a fully @@ -107,15 +104,15 @@ class PassthroughOverlayEntry { /// from subsequent routes will be handled properly when they complete. bool get maintainState => _maintainState; bool _maintainState; + set maintainState(bool value) { - assert(_maintainState != null); if (_maintainState == value) return; _maintainState = value; assert(_overlay != null); - _overlay._didChangeEntryOpacity(); + _overlay!._didChangeEntryOpacity(); } - PassthroughOverlayState _overlay; + PassthroughOverlayState? _overlay; final GlobalKey<_OverlayEntryState> _key = GlobalKey<_OverlayEntryState>(); /// Remove this entry from the overlay. @@ -131,11 +128,11 @@ class PassthroughOverlayEntry { /// the next frame (i.e. many milliseconds later). void remove() { assert(_overlay != null); - final PassthroughOverlayState overlay = _overlay; + final PassthroughOverlayState overlay = _overlay!; _overlay = null; - if (SchedulerBinding.instance.schedulerPhase == + if (SchedulerBinding.instance!.schedulerPhase == SchedulerPhase.persistentCallbacks) { - SchedulerBinding.instance.addPostFrameCallback((Duration duration) { + SchedulerBinding.instance!.addPostFrameCallback((Duration duration) { overlay._remove(this); }); } else { @@ -156,9 +153,7 @@ class PassthroughOverlayEntry { } class _OverlayEntry extends StatefulWidget { - _OverlayEntry(this.entry) - : assert(entry != null), - super(key: entry._key); + _OverlayEntry(this.entry) : super(key: entry._key); final PassthroughOverlayEntry entry; @@ -173,7 +168,9 @@ class _OverlayEntryState extends State<_OverlayEntry> { } void _markNeedsBuild() { - setState(() {/* the state that changed is in the builder */}); + setState(() { + /* the state that changed is in the builder */ + }); } } @@ -202,10 +199,10 @@ class PassthroughOverlay extends StatefulWidget { /// /// Rather than creating an overlay, consider using the overlay that is /// created by the [WidgetsApp] or the [MaterialApp] for the application. - const PassthroughOverlay( - {Key key, this.initialEntries = const []}) - : assert(initialEntries != null), - super(key: key); + const PassthroughOverlay({ + this.initialEntries = const [], + Key? key, + }) : super(key: key); /// The entries to include in the overlay initially. /// @@ -236,8 +233,8 @@ class PassthroughOverlay extends StatefulWidget { /// OverlayState overlay = Overlay.of(context); /// ``` static PassthroughOverlayState of(BuildContext context, - {Widget debugRequiredFor}) { - final PassthroughOverlayState result = + {Widget? debugRequiredFor}) { + final PassthroughOverlayState? result = context.findAncestorStateOfType(); assert(() { if (debugRequiredFor != null && result == null) { @@ -253,7 +250,7 @@ class PassthroughOverlay extends StatefulWidget { } return true; }()); - return result; + return result!; } @override @@ -278,7 +275,7 @@ class PassthroughOverlayState extends State /// /// If [above] is non-null, the entry is inserted just above [above]. /// Otherwise, the entry is inserted on top. - void insert(PassthroughOverlayEntry entry, {PassthroughOverlayEntry above}) { + void insert(PassthroughOverlayEntry entry, {PassthroughOverlayEntry? above}) { assert(entry._overlay == null); assert( above == null || (above._overlay == this && _entries.contains(above))); @@ -295,7 +292,7 @@ class PassthroughOverlayState extends State /// If [above] is non-null, the entries are inserted just above [above]. /// Otherwise, the entries are inserted on top. void insertAll(Iterable entries, - {PassthroughOverlayEntry above}) { + {PassthroughOverlayEntry? above}) { assert( above == null || (above._overlay == this && _entries.contains(above))); if (entries.isEmpty) return; @@ -313,7 +310,9 @@ class PassthroughOverlayState extends State void _remove(PassthroughOverlayEntry entry) { if (mounted) { _entries.remove(entry); - setState(() {/* entry was removed */}); + setState(() { + /* entry was removed */ + }); } } @@ -367,8 +366,8 @@ class PassthroughOverlayState extends State } return _Theatre( onstage: Stack( - fit: StackFit - .passthrough, //HanSheng changed it to passthrough so that this widget doesn't change layout constraints + fit: StackFit.passthrough, + //HanSheng changed it to passthrough so that this widget doesn't change layout constraints children: onstageChildren.reversed.toList(growable: false), ), offstage: offstageChildren, @@ -395,12 +394,11 @@ class PassthroughOverlayState extends State /// widgets. class _Theatre extends RenderObjectWidget { _Theatre({ + required this.offstage, this.onstage, - @required this.offstage, - }) : assert(offstage != null), - assert(!offstage.any((Widget child) => child == null)); + }); - final Stack onstage; + final Stack? onstage; final List offstage; @@ -417,23 +415,23 @@ class _TheatreElement extends RenderObjectElement { super(widget); @override - _Theatre get widget => super.widget; + _Theatre get widget => super.widget as _Theatre; @override - _RenderTheatre get renderObject => super.renderObject; + _RenderTheatre get renderObject => super.renderObject as _RenderTheatre; - Element _onstage; + Element? _onstage; static final Object _onstageSlot = Object(); - List _offstage; + late List _offstage; final Set _forgottenOffstageChildren = HashSet(); @override - void insertChildRenderObject(RenderBox child, dynamic slot) { + void insertRenderObjectChild(RenderBox child, dynamic slot) { assert(renderObject.debugValidateChild(child)); if (slot == _onstageSlot) { assert(child is RenderStack); - renderObject.child = child; + renderObject.child = child as RenderStack?; } else { assert(slot == null || slot is Element); renderObject.insert(child, after: slot?.renderObject); @@ -441,11 +439,11 @@ class _TheatreElement extends RenderObjectElement { } @override - void moveChildRenderObject(RenderBox child, dynamic slot) { + void moveRenderObjectChild(RenderBox child, dynamic oldSlot, dynamic slot) { if (slot == _onstageSlot) { renderObject.remove(child); assert(child is RenderStack); - renderObject.child = child; + renderObject.child = child as RenderStack?; } else { assert(slot == null || slot is Element); if (renderObject.child == child) { @@ -458,7 +456,7 @@ class _TheatreElement extends RenderObjectElement { } @override - void removeChildRenderObject(RenderBox child) { + void removeRenderObjectChild(RenderBox child, dynamic slot) { if (renderObject.child == child) { renderObject.child = null; } else { @@ -468,7 +466,7 @@ class _TheatreElement extends RenderObjectElement { @override void visitChildren(ElementVisitor visitor) { - if (_onstage != null) visitor(_onstage); + if (_onstage != null) visitor(_onstage!); for (Element child in _offstage) { if (!_forgottenOffstageChildren.contains(child)) visitor(child); } @@ -476,11 +474,11 @@ class _TheatreElement extends RenderObjectElement { @override void debugVisitOnstageChildren(ElementVisitor visitor) { - if (_onstage != null) visitor(_onstage); + if (_onstage != null) visitor(_onstage!); } @override - bool forgetChild(Element child) { + void forgetChild(Element child) { if (child == _onstage) { _onstage = null; } else { @@ -488,15 +486,15 @@ class _TheatreElement extends RenderObjectElement { assert(!_forgottenOffstageChildren.contains(child)); _forgottenOffstageChildren.add(child); } - return true; + super.forgetChild(child); } @override - void mount(Element parent, dynamic newSlot) { + void mount(Element? parent, dynamic newSlot) { super.mount(parent, newSlot); _onstage = updateChild(_onstage, widget.onstage, _onstageSlot); - _offstage = List(widget.offstage.length); - Element previousChild; + _offstage = []; + Element? previousChild; for (int i = 0; i < _offstage.length; i += 1) { final Element newChild = inflateWidget(widget.offstage[i], previousChild); _offstage[i] = newChild; @@ -552,13 +550,13 @@ class _RenderTheatre extends RenderBox @override void redepthChildren() { - if (child != null) redepthChild(child); + if (child != null) redepthChild(child!); super.redepthChildren(); } @override void visitChildren(RenderObjectVisitor visitor) { - if (child != null) visitor(child); + if (child != null) visitor(child!); super.visitChildren(visitor); } @@ -566,10 +564,10 @@ class _RenderTheatre extends RenderBox List debugDescribeChildren() { final List children = []; - if (child != null) children.add(child.toDiagnosticsNode(name: 'onstage')); + if (child != null) children.add(child!.toDiagnosticsNode(name: 'onstage')); if (firstChild != null) { - RenderBox child = firstChild; + RenderBox child = firstChild!; int count = 1; while (true) { @@ -580,8 +578,9 @@ class _RenderTheatre extends RenderBox ), ); if (child == lastChild) break; - final StackParentData childParentData = child.parentData; - child = childParentData.nextSibling; + final StackParentData childParentData = + child.parentData! as StackParentData; + child = childParentData.nextSibling!; count += 1; } } else { @@ -597,6 +596,6 @@ class _RenderTheatre extends RenderBox @override void visitChildrenForSemantics(RenderObjectVisitor visitor) { - if (child != null) visitor(child); + if (child != null) visitor(child!); } } diff --git a/lib/src/widgets/reorderable_flex.dart b/lib/src/widgets/reorderable_flex.dart index 7abc888..1e7bf84 100644 --- a/lib/src/widgets/reorderable_flex.dart +++ b/lib/src/widgets/reorderable_flex.dart @@ -38,12 +38,12 @@ import './typedefs.dart'; class ReorderableFlex extends StatefulWidget { /// Creates a reorderable list. ReorderableFlex({ - Key key, + Key? key, this.header, this.footer, - @required this.children, - @required this.onReorder, - @required this.direction, + required this.children, + required this.onReorder, + required this.direction, this.scrollDirection = Axis.vertical, this.padding, this.buildItemsContainer, @@ -53,13 +53,13 @@ class ReorderableFlex extends StatefulWidget { this.scrollController, this.needsLongPressDraggable = true, this.draggingWidgetOpacity = 0.2, - this.reorderAnimationDuration = const Duration(milliseconds: 200), - this.scrollAnimationDuration = const Duration(milliseconds: 200), + this.reorderAnimationDuration, + this.scrollAnimationDuration, this.ignorePrimaryScrollController = false, - }) : assert(direction != null), - assert(onReorder != null), - assert(children != null), - assert( + this.hapticFeedbackOnStart = true, + this.onReorderGhostStep, + this.onReorderStarted, + }) : assert( children.every((Widget w) => w.key != null), 'All children of this widget must have a key.', ), @@ -68,12 +68,12 @@ class ReorderableFlex extends StatefulWidget { /// A non-reorderable header widget to show before the list. /// /// If null, no header will appear at the top/left of the widget. - final Widget header; + final Widget? header; /// A non-reorderable footer widget to show after the list. /// /// If null, no footer will appear at the bottom/right of the widget. - final Widget footer; + final Widget? footer; /// The widgets to display. final List children; @@ -83,28 +83,32 @@ class ReorderableFlex extends StatefulWidget { /// List [children] can only drag along this [Axis]. final Axis direction; final Axis scrollDirection; - final ScrollController scrollController; + final ScrollController? scrollController; /// The amount of space by which to inset the [children]. - final EdgeInsets padding; + final EdgeInsets? padding; /// Called when a child is dropped into a new position to shuffle the /// children. final ReorderCallback onReorder; - final NoReorderCallback onNoReorder; + final NoReorderCallback? onNoReorder; + final ReorderCallback? onReorderGhostStep; + final ReorderStartedCallback? onReorderStarted; - final BuildItemsContainer buildItemsContainer; - final BuildDraggableFeedback buildDraggableFeedback; + final BuildItemsContainer? buildItemsContainer; + final BuildDraggableFeedback? buildDraggableFeedback; final MainAxisAlignment mainAxisAlignment; final bool needsLongPressDraggable; final double draggingWidgetOpacity; - final Duration reorderAnimationDuration; - final Duration scrollAnimationDuration; + final Duration? reorderAnimationDuration; + final Duration? scrollAnimationDuration; final bool ignorePrimaryScrollController; + final bool hapticFeedbackOnStart; + @override _ReorderableFlexState createState() => _ReorderableFlexState(); } @@ -124,7 +128,7 @@ class _ReorderableFlexState extends State { GlobalKey(debugLabel: '$ReorderableFlex overlay key'); // This entry contains the scrolling list itself. - PassthroughOverlayEntry _listOverlayEntry; + late PassthroughOverlayEntry _listOverlayEntry; @override void initState() { @@ -147,8 +151,13 @@ class _ReorderableFlexState extends State { scrollController: widget.scrollController, needsLongPressDraggable: widget.needsLongPressDraggable, draggingWidgetOpacity: widget.draggingWidgetOpacity, - reorderAnimationDuration: widget.reorderAnimationDuration, - scrollAnimationDuration: widget.scrollAnimationDuration, + reorderAnimationDuration: widget.reorderAnimationDuration ?? + const Duration(milliseconds: 200), + scrollAnimationDuration: widget.scrollAnimationDuration ?? + const Duration(milliseconds: 200), + onReorderGhostStep: widget.onReorderGhostStep, + hapticFeedbackOnStart: widget.hapticFeedbackOnStart, + onReorderStarted: widget.onReorderStarted, ); }, ); @@ -173,39 +182,45 @@ class _ReorderableFlexContent extends StatefulWidget { const _ReorderableFlexContent({ this.header, this.footer, - @required this.children, - @required this.direction, - @required this.scrollDirection, - @required this.padding, - @required this.onReorder, - @required this.onNoReorder, - @required this.buildItemsContainer, - @required this.buildDraggableFeedback, - @required this.mainAxisAlignment, - @required this.scrollController, - @required this.needsLongPressDraggable, - @required this.draggingWidgetOpacity, - @required this.reorderAnimationDuration, - @required this.scrollAnimationDuration, + required this.children, + required this.direction, + required this.scrollDirection, + required this.onReorder, + required this.mainAxisAlignment, + required this.scrollController, + required this.needsLongPressDraggable, + required this.draggingWidgetOpacity, + required this.onNoReorder, + required this.buildItemsContainer, + required this.buildDraggableFeedback, + required this.padding, + this.reorderAnimationDuration = const Duration(milliseconds: 200), + this.scrollAnimationDuration = const Duration(milliseconds: 200), + this.onReorderGhostStep, + this.hapticFeedbackOnStart = true, + this.onReorderStarted, }); - final Widget header; - final Widget footer; + final Widget? header; + final Widget? footer; final List children; final Axis direction; final Axis scrollDirection; - final ScrollController scrollController; - final EdgeInsets padding; final ReorderCallback onReorder; - final NoReorderCallback onNoReorder; - final BuildItemsContainer buildItemsContainer; - final BuildDraggableFeedback buildDraggableFeedback; + final NoReorderCallback? onNoReorder; + final BuildItemsContainer? buildItemsContainer; + final BuildDraggableFeedback? buildDraggableFeedback; + final ScrollController? scrollController; + final EdgeInsets? padding; final MainAxisAlignment mainAxisAlignment; final bool needsLongPressDraggable; final double draggingWidgetOpacity; final Duration reorderAnimationDuration; final Duration scrollAnimationDuration; + final bool hapticFeedbackOnStart; + final ReorderCallback? onReorderGhostStep; + final ReorderStartedCallback? onReorderStarted; @override _ReorderableFlexContentState createState() => _ReorderableFlexContentState(); @@ -224,31 +239,31 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> static const double _dropAreaMargin = 0.0; // How long an animation to reorder an element in the list takes. - Duration _reorderAnimationDuration; + late Duration _reorderAnimationDuration; // How long an animation to scroll to an off-screen element in the // list takes. - Duration _scrollAnimationDuration; + late Duration _scrollAnimationDuration; // Controls scrolls and measures scroll progress. - ScrollController _scrollController; - ScrollPosition _attachedScrollPosition; + late ScrollController _scrollController; + ScrollPosition? _attachedScrollPosition; // This controls the entrance of the dragging widget into a new place. - AnimationController _entranceController; + late AnimationController _entranceController; // This controls the 'ghost' of the dragging widget, which is left behind // where the widget used to be. - AnimationController _ghostController; + late AnimationController _ghostController; // The member of widget.children currently being dragged. // // Null if no drag is underway. - Key _dragging; - Widget _draggingWidget; + Key? _dragging; + Widget? _draggingWidget; // The last computed size of the feedback widget being dragged. - Size _draggingFeedbackSize = Size(0, 0); + Size? _draggingFeedbackSize = Size(0, 0); // The location that the dragging widget occupied before it started to drag. int _dragStartIndex = -1; @@ -272,7 +287,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> if (_draggingFeedbackSize == null) { return Size(0, 0); } - return _draggingFeedbackSize + Offset(_dropAreaMargin, _dropAreaMargin); + return _draggingFeedbackSize! + Offset(_dropAreaMargin, _dropAreaMargin); // double dropAreaWithoutMargin; // switch (widget.direction) { // case Axis.horizontal: @@ -300,8 +315,8 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> @override void didChangeDependencies() { - if (_scrollController != null && _attachedScrollPosition != null) { - _scrollController.detach(_attachedScrollPosition); + if (_attachedScrollPosition != null) { + _scrollController.detach(_attachedScrollPosition!); _attachedScrollPosition = null; } @@ -310,14 +325,13 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> ScrollController(); if (_scrollController.hasClients) { - ScrollableState scrollableState = Scrollable.of(context); - _attachedScrollPosition = scrollableState?.position; + _attachedScrollPosition = Scrollable.of(context)?.position; } else { _attachedScrollPosition = null; } if (_attachedScrollPosition != null) { - _scrollController.attach(_attachedScrollPosition); + _scrollController.attach(_attachedScrollPosition!); } super.didChangeDependencies(); @@ -325,8 +339,8 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> @override void dispose() { - if (_scrollController != null && _attachedScrollPosition != null) { - _scrollController.detach(_attachedScrollPosition); + if (_attachedScrollPosition != null) { + _scrollController.detach(_attachedScrollPosition!); _attachedScrollPosition = null; } _entranceController.dispose(); @@ -346,6 +360,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> return; } + widget.onReorderGhostStep?.call(_currentIndex, _nextIndex); _currentIndex = _nextIndex; _ghostController.reverse(from: 1.0); _entranceController.forward(from: 0.0); @@ -364,10 +379,9 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> // Scrolls to a target context if that context is not on the screen. void _scrollTo(BuildContext context) { if (_scrolling) return; - final RenderObject contextObject = context.findRenderObject(); + final RenderObject contextObject = context.findRenderObject()!; final RenderAbstractViewport viewport = - RenderAbstractViewport.of(contextObject); - assert(viewport != null); + RenderAbstractViewport.of(contextObject)!; // If and only if the current scroll offset falls in-between the offsets // necessary to reveal the selected context at the top or bottom of the // screen, then it is already on-screen. @@ -407,7 +421,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> // Wraps children in Row or Column, so that the children flow in // the widget's scrollDirection. - Widget _buildContainerForMainAxis({List children}) { + Widget _buildContainerForMainAxis({required List children}) { switch (widget.direction) { case Axis.horizontal: return Row( @@ -427,7 +441,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> // Handles up the logic for dragging and reordering items in the list. Widget _wrap(Widget toWrap, int index) { assert(toWrap.key != null); - final GlobalObjectKey keyIndexGlobalKey = GlobalObjectKey(toWrap.key); + final GlobalObjectKey keyIndexGlobalKey = GlobalObjectKey(toWrap.key!); // We pass the toWrapWithGlobalKey into the Draggable so that when a list // item gets dragged, the accessibility framework can preserve the selected // state of the dragging item. @@ -441,7 +455,8 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> _ghostIndex = index; _currentIndex = index; _entranceController.value = 1.0; - _draggingFeedbackSize = keyIndexGlobalKey.currentContext.size; + _draggingFeedbackSize = keyIndexGlobalKey.currentContext?.size; + widget.onReorderStarted?.call(index); }); } @@ -450,7 +465,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> // debugPrint('startIndex:$startIndex endIndex:$endIndex'); if (startIndex != endIndex) widget.onReorder(startIndex, endIndex); - else if (widget.onNoReorder != null) widget.onNoReorder(startIndex); + else if (widget.onNoReorder != null) widget.onNoReorder!(startIndex); // Animates leftover space in the drop area closed. // TODO(djshuckerow): bring the animation in line with the Material // specifications. @@ -495,34 +510,32 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> final MaterialLocalizations localizations = MaterialLocalizations.of(context); - if (localizations != null) { - // If the item can move to before its current position in the list. - if (index > 0) { - semanticsActions[CustomSemanticsAction( - label: localizations.reorderItemToStart)] = moveToStart; - String reorderItemBefore = localizations.reorderItemUp; - if (widget.direction == Axis.horizontal) { - reorderItemBefore = Directionality.of(context) == TextDirection.ltr - ? localizations.reorderItemLeft - : localizations.reorderItemRight; - } - semanticsActions[CustomSemanticsAction(label: reorderItemBefore)] = - moveBefore; + if (index > 0) { + semanticsActions[CustomSemanticsAction( + label: localizations.reorderItemToStart)] = moveToStart; + String reorderItemBefore = localizations.reorderItemUp; + if (widget.direction == Axis.horizontal) { + reorderItemBefore = Directionality.of(context) == TextDirection.ltr + ? localizations.reorderItemLeft + : localizations.reorderItemRight; } + semanticsActions[CustomSemanticsAction(label: reorderItemBefore)] = + moveBefore; + } - // If the item can move to after its current position in the list. - if (index < widget.children.length - 1) { - String reorderItemAfter = localizations.reorderItemDown; - if (widget.direction == Axis.horizontal) { - reorderItemAfter = Directionality.of(context) == TextDirection.ltr - ? localizations.reorderItemRight - : localizations.reorderItemLeft; - } - semanticsActions[CustomSemanticsAction(label: reorderItemAfter)] = - moveAfter; - semanticsActions[CustomSemanticsAction( - label: localizations.reorderItemToEnd)] = moveToEnd; + // If the item can move to after its current position in the list. + if (index < widget.children.length - 1) { + String reorderItemAfter = localizations.reorderItemDown; + if (widget.direction == Axis.horizontal) { + reorderItemAfter = Directionality.of(context) == TextDirection.ltr + ? localizations.reorderItemRight + : localizations.reorderItemLeft; } + semanticsActions[CustomSemanticsAction(label: reorderItemAfter)] = + moveAfter; + semanticsActions[ + CustomSemanticsAction(label: localizations.reorderItemToEnd)] = + moveToEnd; } // We pass toWrap with a GlobalKey into the Draggable so that when a list @@ -566,7 +579,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> ); } - Widget buildDragTarget(BuildContext context, List acceptedCandidates, + Widget buildDragTarget(BuildContext context, List acceptedCandidates, List rejectedCandidates) { final Widget toWrapWithSemantics = wrapWithSemantics(); @@ -574,7 +587,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> // RenderRepaintBoundary renderObject = _contentKey.currentContext.findRenderObject(); // BoxConstraints contentSizeConstraints = BoxConstraints.loose(renderObject.size); BoxConstraints contentSizeConstraints = BoxConstraints.loose( - _draggingFeedbackSize); //renderObject.constraints + _draggingFeedbackSize!); //renderObject.constraints // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_flex.dart(515) $this.buildDragTarget: contentConstraints:$contentSizeConstraints _draggingFeedbackSize:$_draggingFeedbackSize'); return (widget.buildDraggableFeedback ?? defaultBuildDraggableFeedback)( context, contentSizeConstraints, toWrap); @@ -640,6 +653,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> // had been dragged to. onDraggableCanceled: (Velocity velocity, Offset offset) => onDragEnded(), + hapticFeedbackOnStart: widget.hapticFeedbackOnStart, ) : Draggable( maxSimultaneousDrags: 1, @@ -716,7 +730,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> return Builder(builder: (BuildContext context) { Widget dragTarget = DragTarget( builder: buildDragTarget, - onWillAccept: (Key toAccept) { + onWillAccept: (Key? toAccept) { bool willAccept = _dragging == toAccept && toAccept != toWrap.key; // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_flex.dart(609) $this._wrap: ' @@ -744,7 +758,7 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> return willAccept; //_dragging == toAccept && toAccept != toWrap.key; }, onAccept: (Key accepted) {}, - onLeave: (Object leaving) {}, + onLeave: (Object? leaving) {}, ); dragTarget = KeyedSubtree(key: keyIndexGlobalKey, child: dragTarget); @@ -831,13 +845,13 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> // return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { final List wrappedChildren = []; if (widget.header != null) { - wrappedChildren.add(widget.header); + wrappedChildren.add(widget.header!); } for (int i = 0; i < widget.children.length; i += 1) { wrappedChildren.add(_wrap(widget.children[i], i)); } if (widget.footer != null) { - wrappedChildren.add(widget.footer); + wrappedChildren.add(widget.footer!); } // const Key endWidgetKey = Key('DraggableList - End Widget'); // Widget finalDropArea; @@ -960,26 +974,29 @@ class _ReorderableFlexContentState extends State<_ReorderableFlexContent> /// * [ReorderableColumn], for a version of this widget that is always vertical. class ReorderableRow extends ReorderableFlex { ReorderableRow({ - Key key, - Widget header, - Widget footer, - ReorderCallback onReorder, - EdgeInsets padding, + required ReorderCallback onReorder, + Key? key, + Widget? header, + Widget? footer, + EdgeInsets? padding, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, MainAxisSize mainAxisSize = MainAxisSize.max, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, - TextBaseline textBaseline, + TextBaseline? textBaseline, List children = const [], - BuildDraggableFeedback buildDraggableFeedback, - NoReorderCallback onNoReorder, - ScrollController scrollController, + BuildDraggableFeedback? buildDraggableFeedback, + NoReorderCallback? onNoReorder, + ScrollController? scrollController, bool needsLongPressDraggable = true, double draggingWidgetOpacity = 0.2, - Duration reorderAnimationDuration, - Duration scrollAnimationDuration, + Duration? reorderAnimationDuration, + Duration? scrollAnimationDuration, bool ignorePrimaryScrollController = false, + bool hapticFeedbackOnStart = true, + ReorderCallback? onReorderGhostStep, + ReorderStartedCallback? onReorderStarted, }) : super( key: key, header: header, @@ -1009,7 +1026,10 @@ class ReorderableRow extends ReorderableFlex { draggingWidgetOpacity: draggingWidgetOpacity, reorderAnimationDuration: reorderAnimationDuration, scrollAnimationDuration: scrollAnimationDuration, - ignorePrimaryScrollController: ignorePrimaryScrollController); + ignorePrimaryScrollController: ignorePrimaryScrollController, + hapticFeedbackOnStart: hapticFeedbackOnStart, + onReorderGhostStep: onReorderGhostStep, + onReorderStarted: onReorderStarted); } /// Reorderable (drag and drop) version of [Column], a widget that displays its @@ -1039,26 +1059,29 @@ class ReorderableRow extends ReorderableFlex { /// * [ReorderableRow], for a version of this widget that is always horizontal. class ReorderableColumn extends ReorderableFlex { ReorderableColumn({ - Key key, - Widget header, - Widget footer, - ReorderCallback onReorder, - EdgeInsets padding, + required ReorderCallback onReorder, + Key? key, + Widget? header, + Widget? footer, + EdgeInsets? padding, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, MainAxisSize mainAxisSize = MainAxisSize.max, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, - TextBaseline textBaseline, + TextBaseline? textBaseline, List children = const [], - BuildDraggableFeedback buildDraggableFeedback, - NoReorderCallback onNoReorder, - ScrollController scrollController, + BuildDraggableFeedback? buildDraggableFeedback, + NoReorderCallback? onNoReorder, + ScrollController? scrollController, bool needsLongPressDraggable = true, double draggingWidgetOpacity = 0.2, - Duration reorderAnimationDuration = const Duration(milliseconds: 200), - Duration scrollAnimationDuration = const Duration(milliseconds: 200), + Duration? reorderAnimationDuration, + Duration? scrollAnimationDuration, bool ignorePrimaryScrollController = false, + bool hapticFeedbackOnStart = true, + ReorderCallback? onReorderGhostStep, + ReorderStartedCallback? onReorderStarted, }) : super( key: key, header: header, @@ -1087,5 +1110,8 @@ class ReorderableColumn extends ReorderableFlex { draggingWidgetOpacity: draggingWidgetOpacity, reorderAnimationDuration: reorderAnimationDuration, scrollAnimationDuration: scrollAnimationDuration, - ignorePrimaryScrollController: ignorePrimaryScrollController); + ignorePrimaryScrollController: ignorePrimaryScrollController, + hapticFeedbackOnStart: hapticFeedbackOnStart, + onReorderGhostStep: onReorderGhostStep, + onReorderStarted: onReorderStarted); } diff --git a/lib/src/widgets/reorderable_mixin.dart b/lib/src/widgets/reorderable_mixin.dart index 96bc273..cbe44d0 100644 --- a/lib/src/widgets/reorderable_mixin.dart +++ b/lib/src/widgets/reorderable_mixin.dart @@ -7,7 +7,7 @@ mixin ReorderableMixin { Widget makeAppearingWidget( Widget child, AnimationController entranceController, - Size draggingFeedbackSize, + Size? draggingFeedbackSize, Axis direction, ) { if (null == draggingFeedbackSize) { @@ -35,7 +35,7 @@ mixin ReorderableMixin { Widget makeDisappearingWidget( Widget child, AnimationController ghostController, - Size draggingFeedbackSize, + Size? draggingFeedbackSize, Axis direction, ) { if (null == draggingFeedbackSize) { diff --git a/lib/src/widgets/reorderable_sliver.dart b/lib/src/widgets/reorderable_sliver.dart index 3366b1f..8044f61 100644 --- a/lib/src/widgets/reorderable_sliver.dart +++ b/lib/src/widgets/reorderable_sliver.dart @@ -19,10 +19,10 @@ import './reorderable_mixin.dart'; int _kDefaultSemanticIndexCallback(Widget _, int localIndex) => localIndex; mixin _ReorderableSliverChildDelegateMixin { - Widget Function(Widget toWrap, int index) _wrap; + Widget Function(Widget toWrap, int index)? _wrap; set wrap(Function value) { - _wrap = value; + _wrap = value as Widget Function(Widget toWrap, int index)?; } } @@ -48,7 +48,7 @@ class ReorderableSliverChildBuilderDelegate extends SliverChildBuilderDelegate /// null. ReorderableSliverChildBuilderDelegate( IndexedWidgetBuilder builder, { - int childCount, + int? childCount, bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, bool addSemanticIndexes = true, @@ -84,11 +84,10 @@ class ReorderableSliverChildBuilderDelegate extends SliverChildBuilderDelegate // } @override - Widget build(BuildContext context, int index) { + Widget? build(BuildContext context, int index) { // Widget child = super.build(context, index); - assert(builder != null); - if (index < 0 || (childCount != null && index >= childCount)) return null; - Widget child = builder(context, index); + if (index < 0 || (childCount != null && index >= childCount!)) return null; + Widget? child = builder(context, index); // try { // child = builder(context, index); // } catch (exception, stackTrace) { @@ -97,7 +96,7 @@ class ReorderableSliverChildBuilderDelegate extends SliverChildBuilderDelegate if (child == null) return null; if (addRepaintBoundaries) child = RepaintBoundary.wrap(child, index); if (addSemanticIndexes) { - final int semanticIndex = semanticIndexCallback(child, index); + final int? semanticIndex = semanticIndexCallback(child, index); if (semanticIndex != null) child = IndexedSemantics( index: semanticIndex + semanticIndexOffset, child: child); @@ -110,7 +109,7 @@ class ReorderableSliverChildBuilderDelegate extends SliverChildBuilderDelegate // child: child // ); - child = _wrap(child, index); + child = _wrap!(child, index); if (addAutomaticKeepAlives) child = AutomaticKeepAlive(child: child); return child; @@ -159,16 +158,14 @@ class ReorderableSliverChildListDelegate extends SliverChildListDelegate true; @override - Widget build(BuildContext context, int index) { + Widget? build(BuildContext context, int index) { // Widget child = super.build(context, index); - assert(children != null); if (index < 0 || index >= children.length) return null; Widget child = children[index]; // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_sliver.dart(97) $this.build: index:$index child:$child'); - assert(child != null); if (addRepaintBoundaries) child = RepaintBoundary.wrap(child, index); if (addSemanticIndexes) { - final int semanticIndex = semanticIndexCallback(child, index); + final int? semanticIndex = semanticIndexCallback(child, index); if (semanticIndex != null) child = IndexedSemantics( index: semanticIndex + semanticIndexOffset, child: child); @@ -182,7 +179,7 @@ class ReorderableSliverChildListDelegate extends SliverChildListDelegate // child: child // ); - child = _wrap(child, index); + child = _wrap!(child, index); if (addAutomaticKeepAlives) child = AutomaticKeepAlive(child: child); return child; @@ -241,9 +238,8 @@ class ReorderableSliverChildListDelegate extends SliverChildListDelegate class ReorderableSliverList extends StatefulWidget { /// Creates a reorderable list. ReorderableSliverList({ - Key key, - @required this.delegate, - @required this.onReorder, + required this.delegate, + required this.onReorder, this.buildItemsContainer, this.buildDraggableFeedback, this.onNoReorder, @@ -251,8 +247,10 @@ class ReorderableSliverList extends StatefulWidget { this.onDragStart, this.onDragEnd, this.enabled = true, - }): assert(onReorder != null && delegate != null), - super(key: key); + this.controller, + Key? key, + }) : super(key: key); + /// The delegate that provides the children for this widget. /// /// The children are constructed lazily using this widget to avoid creating @@ -268,30 +266,31 @@ class ReorderableSliverList extends StatefulWidget { /// Called when a child is dropped into a new position to shuffle the /// children. final ReorderCallback onReorder; - final NoReorderCallback onNoReorder; + final NoReorderCallback? onNoReorder; /// Called when a drag process is started - final VoidCallback onDragStart; + final VoidCallback? onDragStart; + /// Called when the drag process has ended, either via [Draggable.onDraggableCanceled] or [Draggable.onDragCompleted] - final VoidCallback onDragEnd; + final VoidCallback? onDragEnd; /// Called when the draggable starts being dragged. - final ReorderStartedCallback onReorderStarted; + final ReorderStartedCallback? onReorderStarted; - final BuildItemsContainer buildItemsContainer; - final BuildDraggableFeedback buildDraggableFeedback; + final BuildItemsContainer? buildItemsContainer; + final BuildDraggableFeedback? buildDraggableFeedback; /// Sets whether the children are reorderable or not final bool enabled; + final ScrollController? controller; + @override _ReorderableSliverListState createState() => _ReorderableSliverListState(); } class _ReorderableSliverListState extends State - with TickerProviderStateMixin, ReorderableMixin -{ - + with TickerProviderStateMixin, ReorderableMixin { // The extent along the [widget.scrollDirection] axis to allow a child to // drop into when the user reorders list children. // @@ -310,24 +309,24 @@ class _ReorderableSliverListState extends State static const Duration _scrollAnimationDuration = Duration(milliseconds: 200); // Controls scrolls and measures scroll progress. - ScrollController _scrollController; - ScrollPosition _attachedScrollPosition; + late ScrollController _scrollController; + ScrollPosition? _attachedScrollPosition; // This controls the entrance of the dragging widget into a new place. - AnimationController _entranceController; + late AnimationController _entranceController; // This controls the 'ghost' of the dragging widget, which is left behind // where the widget used to be. - AnimationController _ghostController; + late AnimationController _ghostController; // The member of widget.children currently being dragged. // // Null if no drag is underway. // Key _dragging; - Widget _draggingWidget; + Widget? _draggingWidget; // The last computed size of the feedback widget being dragged. - Size _draggingFeedbackSize; + Size? _draggingFeedbackSize; // BuildContext _draggingContext; @@ -349,7 +348,7 @@ class _ReorderableSliverListState extends State // final GlobalKey _contentKey = GlobalKey(debugLabel: '$ReorderableSliverList content key'); - int _childCount; + late int _childCount; final Map _setStateMap = {}; final List _spacedIndexes = []; @@ -358,7 +357,7 @@ class _ReorderableSliverListState extends State if (_draggingFeedbackSize == null) { return Size(0, 0); } - return _draggingFeedbackSize + Offset(_dropAreaMargin, _dropAreaMargin); + return _draggingFeedbackSize! + Offset(_dropAreaMargin, _dropAreaMargin); } @override @@ -379,23 +378,19 @@ class _ReorderableSliverListState extends State @override void didChangeDependencies() { - if (_scrollController != null && _attachedScrollPosition != null) { - _scrollController.detach(_attachedScrollPosition); + if (_attachedScrollPosition != null) { + _scrollController.detach(_attachedScrollPosition!); _attachedScrollPosition = null; } _scrollController = - PrimaryScrollController.of(context) ?? ScrollController(); + widget.controller ?? PrimaryScrollController.of(context) ?? ScrollController(); - if (!_scrollController.hasClients) { - ScrollableState scrollableState = Scrollable.of(context); - _attachedScrollPosition = scrollableState?.position; - } else { - _attachedScrollPosition = null; - } + _attachedScrollPosition = + _scrollController.hasClients ? null : Scrollable.of(context)?.position; if (_attachedScrollPosition != null) { - _scrollController.attach(_attachedScrollPosition); + _scrollController.attach(_attachedScrollPosition!); } super.didChangeDependencies(); @@ -403,8 +398,8 @@ class _ReorderableSliverListState extends State @override void dispose() { - if (_scrollController != null && _attachedScrollPosition != null) { - _scrollController.detach(_attachedScrollPosition); + if (_attachedScrollPosition != null) { + _scrollController.detach(_attachedScrollPosition!); _attachedScrollPosition = null; } _entranceController.dispose(); @@ -428,7 +423,7 @@ class _ReorderableSliverListState extends State // Animates the droppable space from _currentIndex to _nextIndex. void _requestAnimationToNextIndex( - {bool isAcceptingNewTarget = false, int updatingIndex}) { + {bool isAcceptingNewTarget = false, int? updatingIndex}) { // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_sliver.dart(345) $this._requestAnimationToNextIndex: ' // '_dragStartIndex:$_dragStartIndex _ghostIndex:$_ghostIndex _currentIndex:$_currentIndex _nextIndex:$_nextIndex isAcceptingNewTarget:$isAcceptingNewTarget isCompleted:${_entranceController.isCompleted}'); @@ -478,7 +473,7 @@ class _ReorderableSliverListState extends State if (_setStateMap[index] == null) { // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_sliver.dart(394) $this._setState: index:$index _setStateMap:$_setStateMap'); } - _setStateMap[index](_setState); + _setStateMap[index]!(_setState); } else { _update(); } @@ -500,10 +495,9 @@ class _ReorderableSliverListState extends State // Scrolls to a target context if that context is not on the screen. void _scrollTo(BuildContext context) { if (_scrolling) return; - final RenderObject contextObject = context.findRenderObject(); + final RenderObject contextObject = context.findRenderObject()!; final RenderAbstractViewport viewport = - RenderAbstractViewport.of(contextObject); - assert(viewport != null); + RenderAbstractViewport.of(contextObject)!; // if (_scrollController.positions.isEmpty) { // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_sliver.dart(537) $this._scrollTo: empty pos'); @@ -555,7 +549,7 @@ class _ReorderableSliverListState extends State // Wraps children in Row or Column, so that the children flow in // the widget's scrollDirection. - Widget _buildContainerForMainAxis({List children}) { + Widget _buildContainerForMainAxis({required List children}) { var column = Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -582,14 +576,14 @@ class _ReorderableSliverListState extends State Widget _statefulWrap(Widget toWrap, int index, StateSetter setState) { // assert(toWrap.key != null); // final GlobalObjectKey keyIndexGlobalKey = GlobalObjectKey(toWrap.key); - BuildContext draggableContext; + BuildContext? draggableContext; // We pass the toWrapWithGlobalKey into the Draggable so that when a list // item gets dragged, the accessibility framework can preserve the selected // state of the dragging item. // Starts dragging toWrap. void onDragStarted() { - if (widget.onDragStart != null) widget.onDragStart(); + if (widget.onDragStart != null) widget.onDragStart!(); // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_sliver.dart(419) $this.onDragStarted: index:$index'); setState(() { _draggingWidget = toWrap; @@ -599,11 +593,11 @@ class _ReorderableSliverListState extends State _currentIndex = index; _entranceController.value = 1.0; _draggingFeedbackSize = - draggableContext.size; //keyIndexGlobalKey.currentContext.size; + draggableContext!.size; //keyIndexGlobalKey.currentContext.size; // _draggingContext = draggableContext; }); if (widget.onReorderStarted != null) { - widget.onReorderStarted(index); + widget.onReorderStarted!(index); } } @@ -612,7 +606,7 @@ class _ReorderableSliverListState extends State // debugPrint('startIndex:$startIndex endIndex:$endIndex'); if (startIndex != endIndex) widget.onReorder(startIndex, endIndex); - else if (widget.onNoReorder != null) widget.onNoReorder(startIndex); + else if (widget.onNoReorder != null) widget.onNoReorder!(startIndex); // Animates leftover space in the drop area closed. // TODO(djshuckerow): bring the animation in line with the Material // specifications. @@ -634,7 +628,7 @@ class _ReorderableSliverListState extends State // Drops toWrap into the last position it was hovering over. void onDragEnded() { // reorder(_dragStartIndex, _currentIndex); - if (widget.onDragEnd != null) widget.onDragEnd(); + if (widget.onDragEnd != null) widget.onDragEnd!(); this.setState(() { void _update() { _reorder(_dragStartIndex, _currentIndex); @@ -653,7 +647,7 @@ class _ReorderableSliverListState extends State void _setState() { if (updateIndexes.length > 0) { int index = updateIndexes.removeLast(); - _setStateMap[index](_setState); + _setStateMap[index]!(_setState); } else { _update(); } @@ -679,34 +673,31 @@ class _ReorderableSliverListState extends State final MaterialLocalizations localizations = MaterialLocalizations.of(context); - if (localizations != null) { - // If the item can move to before its current position in the list. - if (index > 0) { - semanticsActions[CustomSemanticsAction( - label: localizations.reorderItemToStart)] = moveToStart; - String reorderItemBefore = localizations.reorderItemUp; + if (index > 0) { + semanticsActions[CustomSemanticsAction( + label: localizations.reorderItemToStart)] = moveToStart; + String reorderItemBefore = localizations.reorderItemUp; // if (widget.direction == Axis.horizontal) { // reorderItemBefore = Directionality.of(context) == TextDirection.ltr // ? localizations.reorderItemLeft // : localizations.reorderItemRight; // } - semanticsActions[CustomSemanticsAction(label: reorderItemBefore)] = - moveBefore; - } + semanticsActions[CustomSemanticsAction(label: reorderItemBefore)] = + moveBefore; + } - // If the item can move to after its current position in the list. - if (index < _childCount - 1) { - String reorderItemAfter = localizations.reorderItemDown; + // If the item can move to after its current position in the list. + if (index < _childCount - 1) { + String reorderItemAfter = localizations.reorderItemDown; // if (widget.direction == Axis.horizontal) { // reorderItemAfter = Directionality.of(context) == TextDirection.ltr // ? localizations.reorderItemRight // : localizations.reorderItemLeft; // } - semanticsActions[CustomSemanticsAction(label: reorderItemAfter)] = - moveAfter; - semanticsActions[CustomSemanticsAction( - label: localizations.reorderItemToEnd)] = moveToEnd; - } + semanticsActions[CustomSemanticsAction(label: reorderItemAfter)] = + moveAfter; + semanticsActions[CustomSemanticsAction( + label: localizations.reorderItemToEnd)] = moveToEnd; } // We pass toWrap with a GlobalKey into the Draggable so that when a list @@ -733,14 +724,24 @@ class _ReorderableSliverListState extends State } Widget _makeAppearingWidget(Widget child) { - return makeAppearingWidget(child, _entranceController, _draggingFeedbackSize, Axis.vertical,); + return makeAppearingWidget( + child, + _entranceController, + _draggingFeedbackSize, + Axis.vertical, + ); } Widget _makeDisappearingWidget(Widget child) { - return makeDisappearingWidget(child, _ghostController, _draggingFeedbackSize, Axis.vertical,); + return makeDisappearingWidget( + child, + _ghostController, + _draggingFeedbackSize, + Axis.vertical, + ); } - Widget buildDragTarget(BuildContext context, List acceptedCandidates, + Widget buildDragTarget(BuildContext context, List acceptedCandidates, List rejectedCandidates) { final Widget toWrapWithSemantics = wrapWithSemantics(); @@ -748,7 +749,7 @@ class _ReorderableSliverListState extends State // RenderRepaintBoundary renderObject = _contentKey.currentContext.findRenderObject(); // BoxConstraints contentSizeConstraints = BoxConstraints.loose(renderObject.size); BoxConstraints contentSizeConstraints = BoxConstraints.loose( - _draggingFeedbackSize); //renderObject.constraints + _draggingFeedbackSize!); //renderObject.constraints // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_flex.dart(515) $this.buildDragTarget: contentConstraints:$contentSizeConstraints _draggingFeedbackSize:$_draggingFeedbackSize'); return (widget.buildDraggableFeedback ?? defaultBuildDraggableFeedback)( context, contentSizeConstraints, toWrap); @@ -766,7 +767,7 @@ class _ReorderableSliverListState extends State // We build the draggable inside of a layout builder so that we can // constrain the size of the feedback dragging widget. child = LongPressDraggable( - maxSimultaneousDrags: widget.enabled?1:0, + maxSimultaneousDrags: widget.enabled ? 1 : 0, axis: Axis.vertical, //widget.direction, data: index, @@ -799,17 +800,14 @@ class _ReorderableSliverListState extends State child: toWrapWithSemantics, behavior: HitTestBehavior.opaque), //toWrapWithSemantics,//_dragging == toWrap.key ? const SizedBox() : toWrapWithSemantics, childWhenDragging: IgnorePointer( - ignoring: true, - child: SizedBox( - // Small values (<50) cause an error when used with ListTile. - width: double.infinity, - child: Opacity( - opacity: 0, + ignoring: true, + child: SizedBox( + // Small values (<50) cause an error when used with ListTile. + width: double.infinity, + child: Opacity( + opacity: 0, // child: _makeAppearingWidget(toWrap) - child: Container(width: 0, height: 0, child: toWrap) - ) - ) - ), + child: Container(width: 0, height: 0, child: toWrap)))), //ConstrainedBox(constraints: contentConstraints),//SizedBox(), dragAnchor: DragAnchor.child, onDragStarted: onDragStarted, @@ -850,7 +848,7 @@ class _ReorderableSliverListState extends State return Builder(builder: (BuildContext context) { Widget dragTarget = DragTarget( builder: buildDragTarget, - onWillAccept: (int toAccept) { + onWillAccept: (int? toAccept) { bool willAccept = _dragStartIndex == toAccept && toAccept != index; // debugPrint('${DateTime.now().toString().substring(5, 22)} reorderable_sliver.dart(679) $this._statefulWrap: ' // 'onWillAccept: toAccept:$toAccept return:$willAccept _nextIndex:$_nextIndex index:$index _currentIndex:$_currentIndex _dragStartIndex:$_dragStartIndex'); @@ -880,7 +878,7 @@ class _ReorderableSliverListState extends State return willAccept; //_dragging == toAccept && toAccept != toWrap.key; }, onAccept: (int accepted) {}, - onLeave: (Object leaving) {}, + onLeave: (Object? leaving) {}, ); // dragTarget = KeyedSubtree( @@ -960,8 +958,8 @@ class _ReorderableSliverListState extends State assert(widget.delegate is _ReorderableSliverChildDelegateMixin); if (widget.delegate is ReorderableSliverChildBuilderDelegate) { - _childCount = - (widget.delegate as ReorderableSliverChildBuilderDelegate).childCount; + _childCount = (widget.delegate as ReorderableSliverChildBuilderDelegate) + .childCount!; } else if (widget.delegate is ReorderableSliverChildListDelegate) { _childCount = (widget.delegate as ReorderableSliverChildListDelegate) .children diff --git a/lib/src/widgets/reorderable_table.dart b/lib/src/widgets/reorderable_table.dart index 7db1345..d94210b 100644 --- a/lib/src/widgets/reorderable_table.dart +++ b/lib/src/widgets/reorderable_table.dart @@ -8,18 +8,17 @@ import '../rendering/tabluar_flex.dart'; class ReorderableTableRow extends TabluarRow { ReorderableTableRow({ - Key key, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, MainAxisSize mainAxisSize = MainAxisSize.max, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, - TextBaseline textBaseline, + TextBaseline? textBaseline, List children = const [], - Decoration decoration, + Decoration? decoration, + Key? key, }) : super( children: children, - key: key, mainAxisAlignment: mainAxisAlignment, mainAxisSize: mainAxisSize, crossAxisAlignment: crossAxisAlignment, @@ -27,6 +26,7 @@ class ReorderableTableRow extends TabluarRow { verticalDirection: verticalDirection, textBaseline: textBaseline, decoration: decoration, + key: key, ); } @@ -56,7 +56,7 @@ class ReorderableTable extends StatelessWidget { /// The [children], [defaultColumnWidth], and [defaultVerticalAlignment] /// arguments must not be null. ReorderableTable({ - Key key, + required this.onReorder, this.children = const [], this.columnWidths, this.defaultColumnWidth = const FlexColumnWidth(1.0), @@ -66,26 +66,13 @@ class ReorderableTable extends StatelessWidget { this.textBaseline, this.header, this.footer, - @required this.onReorder, this.decorateDraggableFeedback, this.onNoReorder, - thi, this.reorderAnimationDuration, this.scrollAnimationDuration, this.ignorePrimaryScrollController = false, - }) : assert(children != null), - assert(defaultColumnWidth != null), - assert(defaultVerticalAlignment != null), - assert(() { - if (children.any((ReorderableTableRow row) => - row.children.any((Widget cell) => cell == null))) { - throw FlutterError( - 'One of the children of one of the rows of the table was null.\n' - 'The children of a ReorderableTableRow must not be null.'); - } - return true; - }()), - assert(() { + Key? key, + }) : assert(() { if (children.any((ReorderableTableRow row1) => row1.key != null && children.any((ReorderableTableRow row2) => @@ -145,7 +132,7 @@ class ReorderableTable extends StatelessWidget { /// sizing algorithms are used here. In particular, [IntrinsicColumnWidth] is /// quite expensive because it needs to measure each cell in the column to /// determine the intrinsic size of the column. - final Map columnWidths; + final Map? columnWidths; /// How to determine with widths of columns that don't have an explicit sizing algorithm. /// @@ -156,32 +143,32 @@ class ReorderableTable extends StatelessWidget { /// The direction in which the columns are ordered. /// /// Defaults to the ambient [Directionality]. - final TextDirection textDirection; + final TextDirection? textDirection; /// The style to use when painting the boundary and interior divisions of the table. - final TableBorder border; + final TableBorder? border; /// How cells that do not explicitly specify a vertical alignment are aligned vertically. final TableCellVerticalAlignment defaultVerticalAlignment; /// The text baseline to use when aligning rows using [TableCellVerticalAlignment.baseline]. - final TextBaseline textBaseline; + final TextBaseline? textBaseline; /// Non-reorderable widget at top of the table. Cells in [header] also affects /// alignment of columns. - final Widget header; + final Widget? header; /// Non-reorderable widget at top of the table. Cells in [footer] also affects /// alignment of columns. - final Widget footer; + final Widget? footer; /// Called when a child is dropped into a new position to shuffle the /// children. final ReorderCallback onReorder; - final NoReorderCallback onNoReorder; - final DecorateDraggableFeedback decorateDraggableFeedback; - final Duration reorderAnimationDuration; - final Duration scrollAnimationDuration; + final NoReorderCallback? onNoReorder; + final DecorateDraggableFeedback? decorateDraggableFeedback; + final Duration? reorderAnimationDuration; + final Duration? scrollAnimationDuration; final bool ignorePrimaryScrollController; @override @@ -220,9 +207,9 @@ class ReorderableTable extends StatelessWidget { buildDraggableFeedback: (BuildContext feedbackContext, BoxConstraints constraints, Widget child) { // The child is a ReorderableTableRow because children is a List - ReorderableTableRow tableRow = child; + ReorderableTableRow tableRow = child as ReorderableTableRow; RenderTabluarFlex renderTabluarFlex = - tableKey.currentContext.findRenderObject(); + tableKey.currentContext!.findRenderObject() as RenderTabluarFlex; int grandChildIndex = 0; for (; grandChildIndex < tableRow.children.length; @@ -230,7 +217,7 @@ class ReorderableTable extends StatelessWidget { tableRow.children[grandChildIndex] = ConstrainedBox( constraints: BoxConstraints( minWidth: renderTabluarFlex - .maxGrandchildrenCrossSize[grandChildIndex]), + .maxGrandchildrenCrossSize[grandChildIndex]!), child: tableRow.children[grandChildIndex]); } for (; @@ -240,7 +227,7 @@ class ReorderableTable extends StatelessWidget { tableRow.children.add(ConstrainedBox( constraints: BoxConstraints( minWidth: renderTabluarFlex - .maxGrandchildrenCrossSize[grandChildIndex]), + .maxGrandchildrenCrossSize[grandChildIndex]!), )); } diff --git a/lib/src/widgets/reorderable_widget.dart b/lib/src/widgets/reorderable_widget.dart index 74867c5..579e7b6 100644 --- a/lib/src/widgets/reorderable_widget.dart +++ b/lib/src/widgets/reorderable_widget.dart @@ -4,11 +4,11 @@ class ReorderableWidget extends StatelessWidget implements ReorderableItem { final Widget child; final bool reorderable; - ReorderableWidget( - {@required this.child, @required this.reorderable, @required Key key}) - : assert(reorderable != null && reorderable is bool), - assert(key != null, 'A key is mandatory for each Widget'), - super(key: key); + ReorderableWidget({ + required this.child, + required this.reorderable, + required Key key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -19,5 +19,5 @@ class ReorderableWidget extends StatelessWidget implements ReorderableItem { abstract class ReorderableItem extends Widget { final bool reorderable; - ReorderableItem({@required this.reorderable}); + ReorderableItem({required this.reorderable}); } diff --git a/lib/src/widgets/reorderable_wrap.dart b/lib/src/widgets/reorderable_wrap.dart index 6db7acc..43db99a 100644 --- a/lib/src/widgets/reorderable_wrap.dart +++ b/lib/src/widgets/reorderable_wrap.dart @@ -9,11 +9,9 @@ import 'package:flutter/rendering.dart'; import 'package:reorderables/reorderables.dart'; import './passthrough_overlay.dart'; - //import './transitions.dart'; import './typedefs.dart'; import './wrap.dart'; - //import './transitions.dart'; import '../rendering/wrap.dart'; import 'reorderable_mixin.dart'; @@ -36,13 +34,11 @@ import 'reorderable_mixin.dart'; class ReorderableWrap extends StatefulWidget { /// Creates a reorderable wrap. ReorderableWrap({ - Key key, + required this.children, + required this.onReorder, this.header, this.footer, this.controller, - this.enabledDragging = true, - @required this.children, - @required this.onReorder, this.direction = Axis.horizontal, this.scrollDirection = Axis.vertical, this.padding = EdgeInsets.zero, @@ -63,9 +59,11 @@ class ReorderableWrap extends StatefulWidget { this.reorderAnimationDuration = const Duration(milliseconds: 200), this.scrollAnimationDuration = const Duration(milliseconds: 200), this.ignorePrimaryScrollController = false, - }) : assert(direction != null), - assert(onReorder != null), - assert(children != null), + this.enabledDragging = true, + this.hapticFeedbackOnStart = true, + this.onReorderGhostStep, + Key? key, + }) : // assert( // children.every((Widget w) => w.key != null), // 'All children of this widget must have a key.', @@ -75,13 +73,13 @@ class ReorderableWrap extends StatefulWidget { /// A non-reorderable header widget to show before the list. /// /// If null, no header will appear before the list. - final List header; - final Widget footer; + final List? header; + final Widget? footer; /// A custom scroll [controller]. /// To control the initial scroll offset of the scroll view, provide a /// [controller] with its [ScrollController.initialScrollOffset] property set. - final ScrollController controller; + final ScrollController? controller; /// The widgets to display. final List children; @@ -96,18 +94,19 @@ class ReorderableWrap extends StatefulWidget { final Axis scrollDirection; /// The amount of space by which to inset the [children]. - final EdgeInsets padding; + final EdgeInsets? padding; /// Called when a child is dropped into a new position to shuffle the /// children. final ReorderCallback onReorder; - final NoReorderCallback onNoReorder; + final NoReorderCallback? onNoReorder; + final ReorderCallback? onReorderGhostStep; /// Called when the draggable starts being dragged. - final ReorderStartedCallback onReorderStarted; + final ReorderStartedCallback? onReorderStarted; - final BuildItemsContainer buildItemsContainer; - final BuildDraggableFeedback buildDraggableFeedback; + final BuildItemsContainer? buildItemsContainer; + final BuildDraggableFeedback? buildDraggableFeedback; /// The flag of whether needs long press to trigger dragging mode. /// true means it needs long press and false means no need. @@ -211,7 +210,7 @@ class ReorderableWrap extends StatefulWidget { /// [crossAxisAlignment] is either [WrapCrossAlignment.start] or /// [WrapCrossAlignment.end], or there's more than one child, then the /// [textDirection] (or the ambient [Directionality]) must not be null. - final TextDirection textDirection; + final TextDirection? textDirection; /// Determines the order to lay children out vertically and how to interpret /// `start` and `end` in the vertical direction. @@ -237,14 +236,16 @@ class ReorderableWrap extends StatefulWidget { /// [verticalDirection] must not be null. final VerticalDirection verticalDirection; - final int minMainAxisCount; - final int maxMainAxisCount; + final int? minMainAxisCount; + final int? maxMainAxisCount; final Duration reorderAnimationDuration; final Duration scrollAnimationDuration; final bool ignorePrimaryScrollController; final bool enabledDragging; + final bool hapticFeedbackOnStart; + @override _ReorderableWrapState createState() => _ReorderableWrapState(); } @@ -264,7 +265,7 @@ class _ReorderableWrapState extends State { GlobalKey(debugLabel: '$ReorderableWrap overlay key'); // This entry contains the scrolling list itself. - PassthroughOverlayEntry _listOverlayEntry; + late PassthroughOverlayEntry _listOverlayEntry; @override void initState() { @@ -281,7 +282,7 @@ class _ReorderableWrapState extends State { onReorder: widget.onReorder, onNoReorder: widget.onNoReorder, onReorderStarted: widget.onReorderStarted, - padding: widget.padding, + padding: widget.padding ?? EdgeInsets.zero, buildItemsContainer: widget.buildItemsContainer, buildDraggableFeedback: widget.buildDraggableFeedback, needsLongPressDraggable: widget.needsLongPressDraggable, @@ -298,6 +299,8 @@ class _ReorderableWrapState extends State { reorderAnimationDuration: widget.reorderAnimationDuration, scrollAnimationDuration: widget.scrollAnimationDuration, enableDragging: widget.enabledDragging, + hapticFeedbackOnStart: widget.hapticFeedbackOnStart, + onReorderGhostStep: widget.onReorderGhostStep, ); }, ); @@ -320,45 +323,47 @@ class _ReorderableWrapState extends State { // ReorderableListView. class _ReorderableWrapContent extends StatefulWidget { const _ReorderableWrapContent({ + required this.children, + required this.direction, + required this.scrollDirection, + required this.padding, + required this.onReorder, + required this.onNoReorder, + required this.onReorderStarted, + required this.buildItemsContainer, + required this.buildDraggableFeedback, + required this.needsLongPressDraggable, + required this.alignment, + required this.spacing, + required this.runAlignment, + required this.runSpacing, + required this.crossAxisAlignment, + required this.textDirection, + required this.verticalDirection, + required this.minMainAxisCount, + required this.maxMainAxisCount, this.header, this.footer, this.controller, - @required this.children, - @required this.direction, - @required this.scrollDirection, - @required this.padding, - @required this.onReorder, - @required this.onNoReorder, - @required this.onReorderStarted, - @required this.buildItemsContainer, - @required this.buildDraggableFeedback, - @required this.needsLongPressDraggable, - @required this.alignment, - @required this.spacing, - @required this.runAlignment, - @required this.runSpacing, - @required this.crossAxisAlignment, - @required this.textDirection, - @required this.verticalDirection, - @required this.minMainAxisCount, - @required this.maxMainAxisCount, - @required this.reorderAnimationDuration, - @required this.scrollAnimationDuration, - @required this.enableDragging, + this.reorderAnimationDuration = const Duration(milliseconds: 200), + this.scrollAnimationDuration = const Duration(milliseconds: 200), + this.enableDragging = true, + this.hapticFeedbackOnStart = true, + this.onReorderGhostStep, }); - final List header; - final Widget footer; - final ScrollController controller; + final List? header; + final Widget? footer; + final ScrollController? controller; final List children; final Axis direction; final Axis scrollDirection; final EdgeInsets padding; final ReorderCallback onReorder; - final NoReorderCallback onNoReorder; - final ReorderStartedCallback onReorderStarted; - final BuildItemsContainer buildItemsContainer; - final BuildDraggableFeedback buildDraggableFeedback; + final NoReorderCallback? onNoReorder; + final ReorderStartedCallback? onReorderStarted; + final BuildItemsContainer? buildItemsContainer; + final BuildDraggableFeedback? buildDraggableFeedback; final bool needsLongPressDraggable; final WrapAlignment alignment; @@ -366,13 +371,15 @@ class _ReorderableWrapContent extends StatefulWidget { final WrapAlignment runAlignment; final double runSpacing; final WrapCrossAlignment crossAxisAlignment; - final TextDirection textDirection; + final TextDirection? textDirection; final VerticalDirection verticalDirection; - final int minMainAxisCount; - final int maxMainAxisCount; - final bool enableDragging; + final int? minMainAxisCount; + final int? maxMainAxisCount; final Duration reorderAnimationDuration; final Duration scrollAnimationDuration; + final bool enableDragging; + final bool hapticFeedbackOnStart; + final ReorderCallback? onReorderGhostStep; @override _ReorderableWrapContentState createState() => _ReorderableWrapContentState(); @@ -391,36 +398,36 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> static const double _dropAreaMargin = 0.0; // How long an animation to reorder an element in the list takes. - Duration _reorderAnimationDuration; + late Duration _reorderAnimationDuration; // How long an animation to scroll to an off-screen element in the // list takes. - Duration _scrollAnimationDuration; + late Duration _scrollAnimationDuration; // Controls scrolls and measures scroll progress. - ScrollController _scrollController; + late ScrollController _scrollController; // This controls the entrance of the dragging widget into a new place. - AnimationController _entranceController; + late AnimationController _entranceController; // This controls the 'ghost' of the dragging widget, which is left behind // where the widget used to be. - AnimationController _ghostController; + late AnimationController _ghostController; // The member of widget.children currently being dragged. // // Null if no drag is underway. // int _dragging; - Widget _draggingWidget; + Widget? _draggingWidget; // The last computed size of the feedback widget being dragged. - Size _draggingFeedbackSize; + Size? _draggingFeedbackSize; // List _childKeys; - List _childContexts; - List _childSizes; - List _childIndexToDisplayIndex; - List _childDisplayIndexToIndex; + late List _childContexts; + late List _childSizes; + late List _childIndexToDisplayIndex; + late List _childDisplayIndexToIndex; // The location that the dragging widget occupied before it started to drag. int _dragStartIndex = -1; @@ -439,16 +446,16 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> bool _scrolling = false; final GlobalKey _wrapKey = GlobalKey(debugLabel: '$ReorderableWrap wrap key'); - List _wrapChildRunIndexes; - List _childRunIndexes; - List _nextChildRunIndexes; - List _wrapChildren; + late List _wrapChildRunIndexes; + late List _childRunIndexes; + late List _nextChildRunIndexes; + late List _wrapChildren; Size get _dropAreaSize { if (_draggingFeedbackSize == null) { return Size(0, 0); } - return _draggingFeedbackSize + Offset(_dropAreaMargin, _dropAreaMargin); + return _draggingFeedbackSize! + Offset(_dropAreaMargin, _dropAreaMargin); // double dropAreaWithoutMargin; // switch (widget.direction) { // case Axis.horizontal: @@ -509,7 +516,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // && _dragStartIndex == _ghostIndex return; } - + widget.onReorderGhostStep?.call(_currentDisplayIndex, _nextDisplayIndex); _currentDisplayIndex = _nextDisplayIndex; _ghostController.reverse(from: 1.0); _entranceController.forward(from: 0.0); @@ -528,10 +535,9 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // Scrolls to a target context if that context is not on the screen. void _scrollTo(BuildContext context) { if (_scrolling) return; - final RenderObject contextObject = context.findRenderObject(); + final RenderObject contextObject = context.findRenderObject()!; final RenderAbstractViewport viewport = - RenderAbstractViewport.of(contextObject); - assert(viewport != null); + RenderAbstractViewport.of(contextObject)!; // If and only if the current scroll offset falls in-between the offsets // necessary to reveal the selected context at the top or bottom of the // screen, then it is already on-screen. @@ -568,7 +574,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // Wraps children in Row or Column, so that the children flow in // the widget's scrollDirection. - Widget _buildContainerForMainAxis({List children}) { + Widget _buildContainerForMainAxis({required List children}) { // MainAxisSize mainAxisSize = MainAxisSize.min; // CrossAxisAlignment crossAxisAlignment; WrapAlignment runAlignment; @@ -640,14 +646,15 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // for (int i = 0; i < widget.children.length; i++) { // _childSizes[i] = _childKeys[i].currentContext.size; // } - _draggingFeedbackSize = _childContexts[index].size; + _draggingFeedbackSize = _childContexts[index]!.size; for (int i = 0; i < widget.children.length; i++) { - _childSizes[i] = _childContexts[i].size; + _childSizes[i] = _childContexts[i]!.size!; } if (_wrapKey.currentContext != null) { RenderWrapWithMainAxisCount wrapRenderObject = - _wrapKey.currentContext.findRenderObject(); + _wrapKey.currentContext!.findRenderObject() + as RenderWrapWithMainAxisCount; _wrapChildRunIndexes = wrapRenderObject.childRunIndexes; for (int i = 0; i < _childRunIndexes.length; i++) { _nextChildRunIndexes[i] = @@ -658,7 +665,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> widget.maxMainAxisCount != null && widget.minMainAxisCount == widget.maxMainAxisCount) { _wrapChildRunIndexes = List.generate(widget.children.length, - (int index) => index ~/ widget.minMainAxisCount); + (int index) => index ~/ widget.minMainAxisCount!); for (int i = 0; i < _childRunIndexes.length; i++) { _nextChildRunIndexes[i] = _wrapChildRunIndexes[_childIndexToDisplayIndex[i]]; @@ -667,9 +674,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> } // debugPrint('onDragStarted: index:$index _ghostDisplayIndex:$_ghostDisplayIndex _currentDisplayIndex:$_currentDisplayIndex _dragStartIndex:$_dragStartIndex'); - if (widget.onReorderStarted != null) { - widget.onReorderStarted(index); - } + widget.onReorderStarted?.call(index); }); } @@ -678,7 +683,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // debugPrint('_reorder: startIndex:$startIndex endIndex:$endIndex'); if (startIndex != endIndex) widget.onReorder(startIndex, endIndex); - else if (widget.onNoReorder != null) widget.onNoReorder(startIndex); + else if (widget.onNoReorder != null) widget.onNoReorder!(startIndex); // Animates leftover space in the drop area closed. // TODO(djshuckerow): bring the animation in line with the Material // specifications. @@ -725,34 +730,32 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> final MaterialLocalizations localizations = MaterialLocalizations.of(context); - if (localizations != null) { - // If the item can move to before its current position in the list. - if (index > 0) { - semanticsActions[CustomSemanticsAction( - label: localizations.reorderItemToStart)] = moveToStart; - String reorderItemBefore = localizations.reorderItemUp; - if (widget.direction == Axis.horizontal) { - reorderItemBefore = Directionality.of(context) == TextDirection.ltr - ? localizations.reorderItemLeft - : localizations.reorderItemRight; - } - semanticsActions[CustomSemanticsAction(label: reorderItemBefore)] = - moveBefore; + if (index > 0) { + semanticsActions[CustomSemanticsAction( + label: localizations.reorderItemToStart)] = moveToStart; + String reorderItemBefore = localizations.reorderItemUp; + if (widget.direction == Axis.horizontal) { + reorderItemBefore = Directionality.of(context) == TextDirection.ltr + ? localizations.reorderItemLeft + : localizations.reorderItemRight; } + semanticsActions[CustomSemanticsAction(label: reorderItemBefore)] = + moveBefore; + } - // If the item can move to after its current position in the list. - if (index < widget.children.length - 1) { - String reorderItemAfter = localizations.reorderItemDown; - if (widget.direction == Axis.horizontal) { - reorderItemAfter = Directionality.of(context) == TextDirection.ltr - ? localizations.reorderItemRight - : localizations.reorderItemLeft; - } - semanticsActions[CustomSemanticsAction(label: reorderItemAfter)] = - moveAfter; - semanticsActions[CustomSemanticsAction( - label: localizations.reorderItemToEnd)] = moveToEnd; + // If the item can move to after its current position in the list. + if (index < widget.children.length - 1) { + String reorderItemAfter = localizations.reorderItemDown; + if (widget.direction == Axis.horizontal) { + reorderItemAfter = Directionality.of(context) == TextDirection.ltr + ? localizations.reorderItemRight + : localizations.reorderItemLeft; } + semanticsActions[CustomSemanticsAction(label: reorderItemAfter)] = + moveAfter; + semanticsActions[ + CustomSemanticsAction(label: localizations.reorderItemToEnd)] = + moveToEnd; } // We pass toWrap with a GlobalKey into the Draggable so that when a list @@ -804,7 +807,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // RenderRepaintBoundary renderObject = _contentKey.currentContext.findRenderObject(); // BoxConstraints contentSizeConstraints = BoxConstraints.loose(renderObject.size); BoxConstraints contentSizeConstraints = BoxConstraints.loose( - _draggingFeedbackSize); //renderObject.constraints + _draggingFeedbackSize!); //renderObject.constraints // debugPrint('feedbackBuilder: contentConstraints:$contentSizeConstraints'); return (widget.buildDraggableFeedback ?? defaultBuildDraggableFeedback)( context, contentSizeConstraints, toWrap); @@ -851,6 +854,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> // had been dragged to. onDraggableCanceled: (Velocity velocity, Offset offset) => onDragEnded(), + hapticFeedbackOnStart: widget.hapticFeedbackOnStart, ) : Draggable( maxSimultaneousDrags: widget.enableDragging ? 1 : 0, @@ -926,7 +930,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> } // debugPrint(' make $checkingTargetIndex($checkingTargetDisplayIndex) disappearing around $index'); Widget disappearingPreChild = - _makeDisappearingWidget(_wrapChildren[checkingTargetIndex]); + _makeDisappearingWidget(_wrapChildren[checkingTargetIndex]!); // return _buildContainerForMainAxis( // children: _ghostDisplayIndex < _currentDisplayIndex // ? [disappearingPreChild, child] @@ -947,7 +951,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> containedDraggable, displayIndex)); } - bool _onWillAccept(int toAccept, bool isPre) { + bool _onWillAccept(int? toAccept, bool isPre) { int nextDisplayIndex; if (_currentDisplayIndex < displayIndex) { nextDisplayIndex = isPre ? displayIndex - 1 : displayIndex; @@ -969,12 +973,15 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> if (!willAccept) { return false; } - assert(_childDisplayIndexToIndex[_currentDisplayIndex] != index && - _currentDisplayIndex != displayIndex); + if (!(_childDisplayIndexToIndex[_currentDisplayIndex] != index && + _currentDisplayIndex != displayIndex)) { + return false; + } if (_wrapKey.currentContext != null) { RenderWrapWithMainAxisCount wrapRenderObject = - _wrapKey.currentContext.findRenderObject(); + _wrapKey.currentContext!.findRenderObject() + as RenderWrapWithMainAxisCount; _wrapChildRunIndexes = wrapRenderObject.childRunIndexes; // for (int i=0; i<_childRunIndexes.length; i++) { // _childRunIndexes[i] = _wrapChildRunIndexes[_childIndexToDisplayIndex[i]]; @@ -984,7 +991,7 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> widget.maxMainAxisCount != null && widget.minMainAxisCount == widget.maxMainAxisCount) { _wrapChildRunIndexes = List.generate(widget.children.length, - (int index) => index ~/ widget.minMainAxisCount); + (int index) => index ~/ widget.minMainAxisCount!); // for (int i=0; i<_childRunIndexes.length; i++) { // _childRunIndexes[i] = _wrapChildRunIndexes[_childIndexToDisplayIndex[i]]; // } @@ -1002,26 +1009,26 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> } Widget preDragTarget = DragTarget( - builder: (BuildContext context, List acceptedCandidates, + builder: (BuildContext context, List acceptedCandidates, List rejectedCandidates) => SizedBox(), - onWillAccept: (int toAccept) => _onWillAccept(toAccept, true), + onWillAccept: (int? toAccept) => _onWillAccept(toAccept, true), onAccept: (int accepted) {}, - onLeave: (Object leaving) {}, + onLeave: (Object? leaving) {}, ); Widget nextDragTarget = DragTarget( - builder: (BuildContext context, List acceptedCandidates, + builder: (BuildContext context, List acceptedCandidates, List rejectedCandidates) => SizedBox(), - onWillAccept: (int toAccept) => _onWillAccept(toAccept, false), + onWillAccept: (int? toAccept) => _onWillAccept(toAccept, false), onAccept: (int accepted) {}, - onLeave: (Object leaving) {}, + onLeave: (Object? leaving) {}, ); Widget dragTarget = Stack( // key: keyIndexGlobalKey, // fit: StackFit.passthrough, - overflow: Overflow.clip, + clipBehavior: Clip.hardEdge, children: [ containedDraggable, Positioned( @@ -1210,13 +1217,12 @@ class _ReorderableWrapContentState extends State<_ReorderableWrapContent> _currentDisplayIndex, wrappedChildren.removeAt(_dragStartIndex)); } if (widget.header != null) { - wrappedChildren.insertAll(0, widget.header); + wrappedChildren.insertAll(0, widget.header!); } if (widget.footer != null) { - wrappedChildren.add(widget.footer); + wrappedChildren.add(widget.footer!); } - if (widget.controller != null) { return Padding( child: (widget.buildItemsContainer ?? defaultBuildItemsContainer)( diff --git a/lib/src/widgets/tabluar_flex.dart b/lib/src/widgets/tabluar_flex.dart index b95eb90..3638b6a 100644 --- a/lib/src/widgets/tabluar_flex.dart +++ b/lib/src/widgets/tabluar_flex.dart @@ -5,16 +5,16 @@ import '../rendering/tabluar_flex.dart'; class TabluarFlex extends Flex { TabluarFlex({ - Key key, - @required Axis direction, + required Axis direction, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, MainAxisSize mainAxisSize = MainAxisSize.max, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, - TextBaseline textBaseline, + TextBaseline? textBaseline, List children = const [], this.decoration, + Key? key, }) : super( key: key, children: children, @@ -30,7 +30,7 @@ class TabluarFlex extends Flex { /// What decoration to paint. /// /// Commonly a [BoxDecoration]. - final Decoration decoration; + final Decoration? decoration; @override RenderTabluarFlex createRenderObject(BuildContext context) { @@ -231,15 +231,15 @@ class TabluarRow extends TabluarFlex { /// `start` or `end` values for the [mainAxisAlignment], the [textDirection] /// must not be null. TabluarRow({ - Key key, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, MainAxisSize mainAxisSize = MainAxisSize.max, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, - TextBaseline textBaseline, + TextBaseline? textBaseline, List children = const [], - Decoration decoration, + Decoration? decoration, + Key? key, }) : super( children: children, key: key, @@ -429,15 +429,15 @@ class TabluarColumn extends TabluarFlex { /// to be necessary to disambiguate `start` or `end` values for the /// [crossAxisAlignment], the [textDirection] must not be null. TabluarColumn({ - Key key, MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, MainAxisSize mainAxisSize = MainAxisSize.max, CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, - TextDirection textDirection, VerticalDirection verticalDirection = VerticalDirection.down, - TextBaseline textBaseline, List children = const [], - Decoration decoration, + TextDirection? textDirection, + TextBaseline? textBaseline, + Decoration? decoration, + Key? key, }) : super( children: children, key: key, diff --git a/lib/src/widgets/transitions.dart b/lib/src/widgets/transitions.dart index da5167b..89b486a 100644 --- a/lib/src/widgets/transitions.dart +++ b/lib/src/widgets/transitions.dart @@ -11,11 +11,11 @@ class SizeTransitionWithIntrinsicSize extends SingleChildRenderObjectWidget { /// defaults to 0.0, which centers the child along the main axis during the /// transition. SizeTransitionWithIntrinsicSize({ - Key key, this.axis = Axis.vertical, - @required this.sizeFactor, + required this.sizeFactor, double axisAlignment = 0.0, - Widget child, + Widget? child, + Key? key, }) : super( key: key, child: SizeTransition( diff --git a/lib/src/widgets/wrap.dart b/lib/src/widgets/wrap.dart index e481e36..15c5dfd 100644 --- a/lib/src/widgets/wrap.dart +++ b/lib/src/widgets/wrap.dart @@ -5,14 +5,14 @@ import '../rendering/wrap.dart'; class WrapWithMainAxisCount extends Wrap { WrapWithMainAxisCount({ - Key key, + Key? key, Axis direction = Axis.horizontal, WrapAlignment alignment = WrapAlignment.start, double spacing = 0.0, WrapAlignment runAlignment = WrapAlignment.start, double runSpacing = 0.0, WrapCrossAlignment crossAxisAlignment = WrapCrossAlignment.start, - TextDirection textDirection, + TextDirection? textDirection, VerticalDirection verticalDirection = VerticalDirection.down, List children = const [], this.minMainAxisCount, @@ -29,8 +29,8 @@ class WrapWithMainAxisCount extends Wrap { verticalDirection: verticalDirection, children: children); - final int minMainAxisCount; - final int maxMainAxisCount; + final int? minMainAxisCount; + final int? maxMainAxisCount; @override RenderWrapWithMainAxisCount createRenderObject(BuildContext context) { diff --git a/pubspec.yaml b/pubspec.yaml index 2a651d8..ee11223 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,10 @@ name: reorderables description: Reorderable table, row, column, wrap, sliver list that allow drag and drop of their children. -version: 0.3.2 +version: 0.4.1 homepage: https://github.com/hanshengchiu/reorderables environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.14.0 <3.0.0" # flutter: ">=1.6.3" dependencies: