diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 4ed2e25..346a21d 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -1,57 +1,61 @@ +plugins { + id "com.android.application" + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') +def localPropertiesFile = rootProject.file("local.properties") if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> + localPropertiesFile.withReader("UTF-8") { reader -> localProperties.load(reader) } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +def flutterVersionCode = localProperties.getProperty("flutter.versionCode") if (flutterVersionCode == null) { - flutterVersionCode = '1' + flutterVersionCode = "1" } -def flutterVersionName = localProperties.getProperty('flutter.versionName') +def flutterVersionName = localProperties.getProperty("flutter.versionName") if (flutterVersionName == null) { - flutterVersionName = '1.0' + flutterVersionName = "1.0" } -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { - compileSdkVersion 28 - lintOptions { - disable 'InvalidPackage' + namespace = "com.example.example" + compileSdk = 34 + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.example" - minSdkVersion 16 - targetSdkVersion 28 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + applicationId = "com.example.example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdk 21 + targetSdk 34 + versionCode = flutterVersionCode.toInteger() + versionName = flutterVersionName } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug + signingConfig = signingConfigs.debug } } } flutter { - source '../..' + source = "../.." } dependencies { diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 7c8161d..b760c12 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -17,6 +17,7 @@ plugins.load(reader) } + repositories { + google() + mavenCentral() + gradlePluginPortal() + } } -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.3.0" apply false + id "org.jetbrains.kotlin.android" version "1.7.10" apply false } + +include ":app" \ No newline at end of file diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh new file mode 100755 index 0000000..de6439f --- /dev/null +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/Users/reaprite/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/reaprite/Desktop/software/flutter_animated_dialog/example" +export "COCOAPODS_PARALLEL_CODE_SIGN=true" +export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_BUILD_DIR=build" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" +export "DART_OBFUSCATION=false" +export "TRACK_WIDGET_CREATION=true" +export "TREE_SHAKE_ICONS=false" +export "PACKAGE_CONFIG=.dart_tool/package_config.json" diff --git a/example/lib/main.dart b/example/lib/main.dart index e8ba6fd..7d197c8 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -44,11 +44,11 @@ class _MyAppState extends State { // The StatefulWidget's job is to take in some data and create a State class. // In this case, the Widget takes a title, and creates a _MyHomePageState. class MyHomePage extends StatefulWidget { - final String title; + final String? title; - final VoidCallback onSetting; + final VoidCallback? onSetting; - MyHomePage({Key key, this.title, this.onSetting}) : super(key: key); + MyHomePage({Key? key, this.title, this.onSetting}) : super(key: key); @override _MyHomePageState createState() => _MyHomePageState(); @@ -59,23 +59,23 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { // Whether the green box should be visible or invisible - String selectedIndexText; + String? selectedIndexText; - int selectIdx; + int? selectIdx; - String singleSelectedIndexText; + String? singleSelectedIndexText; - int selectIndex; + int? selectIndex; - String multiSelectedIndexesText; + String? multiSelectedIndexesText; - List selectedIndexes; + List? selectedIndexes; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(widget.title), + title: Text(widget.title ?? ""), actions: [ IconButton( icon: Icon(Icons.settings), @@ -683,7 +683,7 @@ class _MyHomePageState extends State { ), ListTile( title: Text( - "List dialog ${selectedIndexText != null && selectedIndexText.isNotEmpty ? '(index:' + selectedIndexText + ')' : ''}", + "List dialog ${selectedIndexText != null && selectedIndexText!.isNotEmpty ? '(index:' + selectedIndexText! + ')' : ''}", ), onTap: () async { int index = await showAnimatedDialog( @@ -722,7 +722,7 @@ class _MyHomePageState extends State { ), ListTile( title: Text( - "List single select${singleSelectedIndexText != null && singleSelectedIndexText.isNotEmpty ? '(index:' + singleSelectedIndexText + ')' : ''}", + "List single select${singleSelectedIndexText != null && singleSelectedIndexText!.isNotEmpty ? '(index:' + singleSelectedIndexText! + ')' : ''}", ), onTap: () async { int index = await showAnimatedDialog( @@ -733,7 +733,7 @@ class _MyHomePageState extends State { titleText: 'Title', listType: ListType.singleSelect, activeColor: Colors.red, - selectedIndex: selectIndex, + selectedIndex: selectIndex!, dataList: List.generate( 20, (index) { @@ -759,7 +759,7 @@ class _MyHomePageState extends State { ), ListTile( title: Text( - "List multiple select${multiSelectedIndexesText != null && multiSelectedIndexesText.isNotEmpty ? '(index:' + multiSelectedIndexesText + ')' : ''}", + "List multiple select${multiSelectedIndexesText != null && multiSelectedIndexesText!.isNotEmpty ? '(index:' + multiSelectedIndexesText! + ')' : ''}", ), onTap: () async { List indexes = await showAnimatedDialog( @@ -769,7 +769,7 @@ class _MyHomePageState extends State { return ClassicListDialogWidget( titleText: 'Title', listType: ListType.multiSelect, - selectedIndexes: selectedIndexes, + selectedIndexes: selectedIndexes!, activeColor: Colors.green, dataList: List.generate( 20, @@ -788,7 +788,7 @@ class _MyHomePageState extends State { print('selectedIndex:${selectedIndexes?.toString()}'); setState(() { this.multiSelectedIndexesText = - selectedIndexes != null && selectedIndexes.length > 0 + selectedIndexes != null && selectedIndexes!.length > 0 ? selectedIndexes.toString() : ''; }); diff --git a/example/lib/model/list_data_model.dart b/example/lib/model/list_data_model.dart index 51ec3be..588176b 100644 --- a/example/lib/model/list_data_model.dart +++ b/example/lib/model/list_data_model.dart @@ -6,7 +6,7 @@ class ListDataModel { ///Value String value; - ListDataModel({this.name, this.value}); + ListDataModel({required this.name, required this.value}); @override String toString() { diff --git a/example/pubspec.lock b/example/pubspec.lock index c4a18a7..b8d5c91 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,58 +5,58 @@ packages: dependency: transitive description: name: async - url: "https://pub.flutter-io.cn" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.flutter-io.cn" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.flutter-io.cn" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.1.0-nullsafety.5" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.2.0-nullsafety.3" + version: "1.3.0" clock: dependency: transitive description: name: clock - url: "https://pub.flutter-io.cn" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.flutter-io.cn" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.18.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - url: "https://pub.flutter-io.cn" + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" source: hosted - version: "0.1.3" + version: "1.0.8" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.flutter-io.cn" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -74,27 +74,62 @@ packages: description: flutter source: sdk version: "0.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + url: "https://pub.dev" + source: hosted + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.flutter-io.cn" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + url: "https://pub.dev" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.8.0" meta: dependency: transitive description: name: meta - url: "https://pub.flutter-io.cn" + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + url: "https://pub.dev" source: hosted - version: "1.3.0-nullsafety.6" + version: "1.12.0" path: dependency: transitive description: name: path - url: "https://pub.flutter-io.cn" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.9.0" sky_engine: dependency: transitive description: flutter @@ -104,57 +139,66 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.flutter-io.cn" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.flutter-io.cn" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.flutter-io.cn" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.flutter-io.cn" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.flutter-io.cn" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.flutter-io.cn" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + url: "https://pub.dev" source: hosted - version: "0.2.19-nullsafety.6" - typed_data: + version: "0.7.0" + vector_math: dependency: transitive description: - name: typed_data - url: "https://pub.flutter-io.cn" + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "1.3.0-nullsafety.5" - vector_math: + version: "2.1.4" + vm_service: dependency: transitive description: - name: vector_math - url: "https://pub.flutter-io.cn" + name: vm_service + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + url: "https://pub.dev" source: hosted - version: "2.1.0-nullsafety.5" + version: "14.2.1" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=3.4.3 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 41c31c8..521fb60 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -14,7 +14,7 @@ description: A new Flutter example module. version: 1.0.0+1 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=3.4.3 <4.0.0' dependencies: flutter: @@ -22,7 +22,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.5 flutter_animated_dialog: path: ../ diff --git a/lib/src/animated_dialog.dart b/lib/src/animated_dialog.dart index 29749ea..7226917 100644 --- a/lib/src/animated_dialog.dart +++ b/lib/src/animated_dialog.dart @@ -67,15 +67,15 @@ enum DialogTransitionType { } /// Displays a Material dialog above the current contents of the app -Future showAnimatedDialog({ - @required BuildContext context, +Future showAnimatedDialog({ + required BuildContext context, bool barrierDismissible = false, - @required WidgetBuilder builder, + required WidgetBuilder builder, animationType = DialogTransitionType.fade, Curve curve = Curves.linear, - Duration duration, - AlignmentGeometry alignment = Alignment.center, - Axis axis, + Duration? duration, + Alignment alignment = Alignment.center, + Axis? axis, }) { assert(builder != null); assert(debugCheckHasMaterialLocalizations(context)); @@ -106,7 +106,6 @@ Future showAnimatedDialog({ switch (animationType) { case DialogTransitionType.fade: return FadeTransition(opacity: animation, child: child); - break; case DialogTransitionType.slideFromRight: return SlideTransition( transformHitTests: false, @@ -116,7 +115,6 @@ Future showAnimatedDialog({ ).chain(CurveTween(curve: curve)).animate(animation), child: child, ); - break; case DialogTransitionType.slideFromLeft: return SlideTransition( transformHitTests: false, @@ -126,7 +124,6 @@ Future showAnimatedDialog({ ).chain(CurveTween(curve: curve)).animate(animation), child: child, ); - break; case DialogTransitionType.slideFromRightFade: return SlideTransition( position: Tween( @@ -138,7 +135,6 @@ Future showAnimatedDialog({ child: child, ), ); - break; case DialogTransitionType.slideFromLeftFade: return SlideTransition( position: Tween( @@ -150,7 +146,6 @@ Future showAnimatedDialog({ child: child, ), ); - break; case DialogTransitionType.slideFromTop: return SlideTransition( transformHitTests: false, @@ -160,7 +155,6 @@ Future showAnimatedDialog({ ).chain(CurveTween(curve: curve)).animate(animation), child: child, ); - break; case DialogTransitionType.slideFromTopFade: return SlideTransition( position: Tween( @@ -172,7 +166,6 @@ Future showAnimatedDialog({ child: child, ), ); - break; case DialogTransitionType.slideFromBottom: return SlideTransition( transformHitTests: false, @@ -182,7 +175,6 @@ Future showAnimatedDialog({ ).chain(CurveTween(curve: curve)).animate(animation), child: child, ); - break; case DialogTransitionType.slideFromBottomFade: return SlideTransition( position: Tween( @@ -194,7 +186,6 @@ Future showAnimatedDialog({ child: child, ), ); - break; case DialogTransitionType.scale: return ScaleTransition( alignment: alignment, @@ -208,7 +199,7 @@ Future showAnimatedDialog({ ), child: child, ); - break; + case DialogTransitionType.fadeScale: return ScaleTransition( alignment: alignment, @@ -228,7 +219,7 @@ Future showAnimatedDialog({ child: child, ), ); - break; + case DialogTransitionType.scaleRotate: return ScaleTransition( alignment: alignment, @@ -247,7 +238,7 @@ Future showAnimatedDialog({ child: child, ), ); - break; + case DialogTransitionType.rotate: return CustomRotationTransition( alignment: alignment, @@ -255,7 +246,7 @@ Future showAnimatedDialog({ parent: animation, curve: Interval(0.0, 1.0, curve: curve))), child: child, ); - break; + case DialogTransitionType.fadeRotate: return CustomRotationTransition( alignment: alignment, @@ -269,7 +260,7 @@ Future showAnimatedDialog({ child: child, ), ); - break; + case DialogTransitionType.rotate3D: return Rotation3DTransition( alignment: alignment, @@ -285,10 +276,10 @@ Future showAnimatedDialog({ child: child, ), ); - break; + case DialogTransitionType.size: return Align( - alignment: alignment ?? Alignment.center, + alignment: alignment, child: SizeTransition( sizeFactor: CurvedAnimation( parent: animation, @@ -298,10 +289,10 @@ Future showAnimatedDialog({ child: child, ), ); - break; + case DialogTransitionType.sizeFade: return Align( - alignment: alignment ?? Alignment.center, + alignment: alignment, child: SizeTransition( sizeFactor: CurvedAnimation( parent: animation, @@ -316,10 +307,10 @@ Future showAnimatedDialog({ ), ), ); - break; + case DialogTransitionType.none: return child; - break; + default: return FadeTransition(opacity: animation, child: child); } @@ -344,7 +335,7 @@ class CustomDialogWidget extends StatelessWidget { /// null, which implies a default that depends on the values of the other /// properties. See the documentation of [titlePadding] for details. const CustomDialogWidget({ - Key key, + Key? key, this.title, this.titlePadding, this.titleTextStyle, @@ -365,7 +356,7 @@ class CustomDialogWidget extends StatelessWidget { /// of the dialog. /// /// Typically a [Text] widget. - final Widget title; + final Widget? title; /// Padding around the title. /// @@ -377,13 +368,13 @@ class CustomDialogWidget extends StatelessWidget { /// provided (but see [contentPadding]). If it _is_ null, then an extra 20 /// pixels of bottom padding is added to separate the [title] from the /// [actions]. - final EdgeInsetsGeometry titlePadding; + final EdgeInsetsGeometry? titlePadding; /// Style for the text in the [title] of this [AlertDialog]. /// /// If null, [DialogTheme.titleTextStyle] is used, if that's null, defaults to /// [ThemeData.textTheme.title]. - final TextStyle titleTextStyle; + final TextStyle? titleTextStyle; /// The (optional) content of the dialog is displayed in the center of the /// dialog in a lighter font. @@ -392,7 +383,7 @@ class CustomDialogWidget extends StatelessWidget { /// message. As noted in the [AlertDialog] documentation, it's important /// to use a [SingleChildScrollView] if there's any risk that the content /// will not fit. - final Widget content; + final Widget? content; /// Padding around the content. /// @@ -406,30 +397,30 @@ class CustomDialogWidget extends StatelessWidget { /// /// If null, [DialogTheme.contentTextStyle] is used, if that's null, defaults /// to [ThemeData.textTheme.subhead]. - final TextStyle contentTextStyle; + final TextStyle? contentTextStyle; /// The (optional) set of actions that are displayed at the bottom of the /// dialog. /// - /// Typically this is a list of [FlatButton] widgets. + /// Typically this is a list of [TextButton] widgets. /// - /// These widgets will be wrapped in a [ButtonBar], which introduces 8 pixels + /// These widgets will be wrapped in a [OverflowBar], which introduces 8 pixels /// of padding on each side. /// /// If the [title] is not null but the [content] _is_ null, then an extra 20 - /// pixels of padding is added above the [ButtonBar] to separate the [title] + /// pixels of padding is added above the [OverflowBar] to separate the [title] /// from the [actions]. - final List actions; + final List? actions; ///Widget in the bottom - final Widget bottomWidget; + final Widget? bottomWidget; /// {@macro flutter.material.dialog.backgroundColor} - final Color backgroundColor; + final Color? backgroundColor; /// {@macro flutter.material.dialog.elevation} /// {@macro flutter.material.material.elevation} - final double elevation; + final double? elevation; /// The semantic label of the dialog used by accessibility frameworks to /// announce screen transitions when the dialog is opened and closed. @@ -442,13 +433,13 @@ class CustomDialogWidget extends StatelessWidget { /// /// * [SemanticsConfiguration.isRouteName], for a description of how this /// value is used. - final String semanticLabel; + final String? semanticLabel; /// {@macro flutter.material.dialog.shape} - final ShapeBorder shape; + final ShapeBorder? shape; ///Min width - final double minWidth; + final double? minWidth; @override Widget build(BuildContext context) { @@ -456,16 +447,16 @@ class CustomDialogWidget extends StatelessWidget { final ThemeData theme = Theme.of(context); final DialogTheme dialogTheme = DialogTheme.of(context); final List children = []; - String label = semanticLabel; + String? label = semanticLabel; if (title != null) { children.add(Padding( padding: titlePadding ?? EdgeInsets.fromLTRB(24.0, 24.0, 24.0, content == null ? 20.0 : 0.0), child: DefaultTextStyle( - style: titleTextStyle ?? + style: (titleTextStyle ?? dialogTheme.titleTextStyle ?? - theme.textTheme.headline6, + theme.textTheme.titleLarge)!, child: Semantics( child: title, namesRoute: true, @@ -503,10 +494,10 @@ class CustomDialogWidget extends StatelessWidget { child: Padding( padding: contentPadding, child: DefaultTextStyle( - style: contentTextStyle ?? + style: (contentTextStyle ?? dialogTheme.contentTextStyle ?? - theme.textTheme.subtitle1, - child: content, + theme.textTheme.titleMedium)!, + child: content ?? Container(), ), ), ), @@ -514,13 +505,13 @@ class CustomDialogWidget extends StatelessWidget { } if (bottomWidget != null) { - children.add(bottomWidget); + children.add(bottomWidget!); } else if (actions != null) { children.add( ButtonBarTheme( data: ButtonBarTheme.of(context), - child: ButtonBar( - children: actions, + child: OverflowBar( + children: actions ?? [], ), ), ); @@ -575,14 +566,14 @@ class CustomDialog extends StatelessWidget { /// /// Typically used in conjunction with [showDialog]. const CustomDialog({ - Key key, + Key? key, this.backgroundColor, - this.elevation, + required this.elevation, this.insetAnimationDuration = const Duration(milliseconds: 100), this.insetAnimationCurve = Curves.decelerate, this.minWidth = 280.0, - this.shape, - this.child, + required this.shape, + required this.child, }) : super(key: key); /// {@template flutter.material.dialog.backgroundColor} @@ -592,7 +583,7 @@ class CustomDialog extends StatelessWidget { /// /// If `null`, [ThemeData.cardColor] is used. /// {@endtemplate} - final Color backgroundColor; + final Color? backgroundColor; /// {@template flutter.material.dialog.elevation} /// The z-coordinate of this [Dialog]. @@ -601,7 +592,7 @@ class CustomDialog extends StatelessWidget { /// dialog's elevation is 24.0. /// {@endtemplate} /// {@macro flutter.material.material.elevation} - final double elevation; + final double? elevation; /// The duration of the animation to show when the system keyboard intrudes /// into the space that the dialog is placed in. @@ -616,7 +607,7 @@ class CustomDialog extends StatelessWidget { final Curve insetAnimationCurve; ///Min width of the dialog - final double minWidth; + final double? minWidth; /// {@template flutter.material.dialog.shape} /// The shape of this dialog's border. @@ -625,7 +616,7 @@ class CustomDialog extends StatelessWidget { /// /// The default shape is a [RoundedRectangleBorder] with a radius of 2.0. /// {@endtemplate} - final ShapeBorder shape; + final ShapeBorder? shape; /// The widget below this widget in the tree. /// diff --git a/lib/src/classic_dialog_widget.dart b/lib/src/classic_dialog_widget.dart index 0b97b2a..8988464 100644 --- a/lib/src/classic_dialog_widget.dart +++ b/lib/src/classic_dialog_widget.dart @@ -18,31 +18,31 @@ typedef OnMultiSelectionCallback = void Function(List selectedIndexes); @immutable class ClassicGeneralDialogWidget extends StatelessWidget { ///Title text of the dialog - final String titleText; + final String? titleText; ///Content text of the dialog - final String contentText; + final String? contentText; ///Text of negative button, the left button at the bottom of dialog - final String negativeText; + final String? negativeText; ///Text of positive button, the right button at the bottom of dialog - final String positiveText; + final String? positiveText; ///TextStyle of negative button, the left button at the bottom of dialog - final TextStyle negativeTextStyle; + final TextStyle? negativeTextStyle; ///TextStyle of positive button, the right button at the bottom of dialog - final TextStyle positiveTextStyle; + final TextStyle? positiveTextStyle; ///Click callback of negative button - final VoidCallback onNegativeClick; + final VoidCallback? onNegativeClick; ///Click callback of positive button - final VoidCallback onPositiveClick; + final VoidCallback? onPositiveClick; ///Actions at the bottom of dialog, when this is set, [negativeText] [positiveText] [onNegativeClick] [onPositiveClick] will not work。 - final List actions; + final List? actions; ClassicGeneralDialogWidget({ this.titleText, @@ -62,48 +62,61 @@ class ClassicGeneralDialogWidget extends StatelessWidget { return CustomDialogWidget( title: titleText != null ? Text( - titleText, + titleText!, style: Theme.of(context).dialogTheme.titleTextStyle, ) : null, content: contentText != null ? Text( - contentText, + contentText!, style: Theme.of(context).dialogTheme.contentTextStyle, ) : null, actions: actions ?? [ onNegativeClick != null - ? FlatButton( - onPressed: onNegativeClick, + ? InkWell( + onTap: onNegativeClick, splashColor: Theme.of(context).splashColor, highlightColor: Theme.of(context).highlightColor, - child: Text( - negativeText ?? 'cancel', - style: negativeTextStyle ?? - TextStyle( - color: Theme.of(context).textTheme.overline.color, - fontSize: - Theme.of(context).textTheme.button.fontSize), + child: Padding( + padding: EdgeInsets.fromLTRB(24.0, 10.0, 14.0, 10.0), + child: Text( + negativeText ?? 'cancel', + style: negativeTextStyle ?? + TextStyle( + color: Theme.of(context) + .textTheme + .bodySmall! + .color, + fontSize: Theme.of(context) + .textTheme + .labelLarge! + .fontSize), + ), ), ) - : null, + : Container(), onPositiveClick != null - ? FlatButton( - onPressed: onPositiveClick, + ? InkWell( + onTap: onPositiveClick, splashColor: Theme.of(context).splashColor, highlightColor: Theme.of(context).highlightColor, - child: Text( - positiveText ?? 'confirm', - style: positiveTextStyle ?? - TextStyle( - color: Theme.of(context).primaryColor, - fontSize: - Theme.of(context).textTheme.button.fontSize), + child: Padding( + padding: EdgeInsets.fromLTRB(24.0, 10.0, 14.0, 10.0), + child: Text( + positiveText ?? 'confirm', + style: positiveTextStyle ?? + TextStyle( + color: Theme.of(context).primaryColor, + fontSize: Theme.of(context) + .textTheme + .labelLarge! + .fontSize), + ), ), ) - : null, + : Container(), ], elevation: 0.0, shape: Theme.of(context).dialogTheme.shape, @@ -133,16 +146,16 @@ enum ListType { /// class ClassicListDialogWidget extends StatefulWidget { ///Title text of the dialog - final String titleText; + final String? titleText; ///Data of the list - final List dataList; + final List? dataList; ///Custom list item widget - final Widget listItem; + final Widget? listItem; ///Click callback of default list item - final VoidCallback onListItemClick; + final VoidCallback? onListItemClick; ///List type final ListType listType; @@ -151,28 +164,28 @@ class ClassicListDialogWidget extends StatefulWidget { final ListTileControlAffinity controlAffinity; ///The active color of radio or checkbox - final Color activeColor; + final Color? activeColor; ///Selected indexes when [listType] is [ListType.multiSelect] - final List selectedIndexes; + final List? selectedIndexes; ///Selected index when [listType] is [ListType.singleSelect] - final int selectedIndex; + final int? selectedIndex; ///Text of negative button, the left button at the bottom of dialog - final String negativeText; + final String? negativeText; ///Text of positive button, the right button at the bottom of dialog - final String positiveText; + final String? positiveText; ///Click callback of negative button - final VoidCallback onNegativeClick; + final VoidCallback? onNegativeClick; ///Click callback of positive button - final VoidCallback onPositiveClick; + final VoidCallback? onPositiveClick; ///Actions at the bottom of dialog, when this is set, [negativeText] [positiveText] [onNegativeClick] [onPositiveClick] will not work。 - final List actions; + final List? actions; ClassicListDialogWidget({ this.titleText, @@ -199,28 +212,30 @@ class ClassicListDialogWidget extends StatefulWidget { } class ClassicListDialogWidgetState extends State { - int selectedIndex; - List valueList; + int? selectedIndex; + List? valueList; List selectedIndexes = []; @override void initState() { super.initState(); - valueList = List.generate(widget.dataList.length, (index) { - if (widget.selectedIndexes != null && - widget.selectedIndexes.contains(index)) { - return true; - } - return false; - }).toList(growable: true); + valueList = widget.dataList != null + ? List.generate(widget.dataList!.length, (index) { + if (widget.selectedIndexes != null && + widget.selectedIndexes!.contains(index)) { + return true; + } + return false; + }).toList(growable: true) + : []; selectedIndex = widget.selectedIndex; - selectedIndexes = widget.selectedIndexes; + selectedIndexes = widget.selectedIndexes ?? []; } @override Widget build(BuildContext context) { // TODO: implement build - Widget contentWidget; + Widget? contentWidget; if (widget.dataList != null) { contentWidget = ListView.builder( shrinkWrap: true, @@ -230,7 +245,7 @@ class ClassicListDialogWidgetState extends State { case ListType.single: return ListTile( title: Text( - widget.dataList[index].toString(), + widget.dataList![index].toString(), style: Theme.of(context).dialogTheme.contentTextStyle, ), onTap: widget.onListItemClick ?? @@ -238,12 +253,11 @@ class ClassicListDialogWidgetState extends State { Navigator.of(context).pop(index); }, ); - break; case ListType.singleSelect: return RadioListTile( controlAffinity: widget.controlAffinity, title: Text( - widget.dataList[index].toString(), + widget.dataList![index].toString(), style: Theme.of(context).dialogTheme.contentTextStyle, ), activeColor: @@ -256,29 +270,28 @@ class ClassicListDialogWidgetState extends State { }); }, ); - break; + case ListType.multiSelect: return CheckboxListTile( controlAffinity: widget.controlAffinity, - selected: valueList[index], - value: valueList[index], + selected: valueList![index], + value: valueList![index], title: Text( - widget.dataList[index].toString(), + widget.dataList![index].toString(), style: Theme.of(context).dialogTheme.contentTextStyle, ), onChanged: (value) { setState(() { - valueList[index] = value; + valueList![index] = value!; }); }, activeColor: widget.activeColor ?? Theme.of(context).primaryColor, ); - break; default: return ListTile( title: Text( - widget.dataList[index].toString(), + widget.dataList![index].toString(), style: Theme.of(context).dialogTheme.contentTextStyle, ), onTap: widget.onListItemClick ?? @@ -286,13 +299,12 @@ class ClassicListDialogWidgetState extends State { Navigator.of(context).pop(index); }, ); - break; } } else { return widget.listItem; } }, - itemCount: widget.dataList.length, + itemCount: widget.dataList!.length, ); contentWidget = Container( width: double.maxFinite, @@ -303,7 +315,7 @@ class ClassicListDialogWidgetState extends State { return CustomDialogWidget( title: widget.titleText != null ? Text( - widget.titleText, + widget.titleText!, style: Theme.of(context).dialogTheme.titleTextStyle, ) : null, @@ -312,21 +324,26 @@ class ClassicListDialogWidgetState extends State { actions: widget.actions ?? [ widget.onNegativeClick != null - ? FlatButton( - onPressed: widget.onNegativeClick, + ? InkWell( + onTap: widget.onNegativeClick, splashColor: Theme.of(context).splashColor, highlightColor: Theme.of(context).highlightColor, - child: Text( - widget.negativeText ?? 'cancel', - style: TextStyle( - color: Theme.of(context).textTheme.overline.color, - fontSize: - Theme.of(context).textTheme.button.fontSize), + child: Padding( + padding: EdgeInsets.fromLTRB(24.0, 10.0, 14.0, 10.0), + child: Text( + widget.negativeText ?? 'cancel', + style: TextStyle( + color: Theme.of(context).textTheme.bodySmall!.color, + fontSize: Theme.of(context) + .textTheme + .labelLarge! + .fontSize), + ), ), ) - : null, - FlatButton( - onPressed: widget.onPositiveClick ?? + : Container(), + InkWell( + onTap: widget.onPositiveClick ?? () { switch (widget.listType) { case ListType.single: @@ -337,9 +354,9 @@ class ClassicListDialogWidgetState extends State { break; case ListType.multiSelect: selectedIndexes = []; - int length = valueList.length; + int length = valueList!.length; for (int i = 0; i < length; i++) { - if (valueList[i]) { + if (valueList![i]) { selectedIndexes.add(i); } } @@ -349,11 +366,15 @@ class ClassicListDialogWidgetState extends State { }, splashColor: Theme.of(context).splashColor, highlightColor: Theme.of(context).highlightColor, - child: Text( - widget.positiveText ?? 'confirm', - style: TextStyle( - color: Theme.of(context).primaryColor, - fontSize: Theme.of(context).textTheme.button.fontSize), + child: Padding( + padding: EdgeInsets.fromLTRB(24.0, 10.0, 14.0, 10.0), + child: Text( + widget.positiveText ?? 'confirm', + style: TextStyle( + color: Theme.of(context).primaryColor, + fontSize: + Theme.of(context).textTheme.labelLarge!.fontSize), + ), ), ), ], diff --git a/lib/src/custom_dialog_transitions.dart b/lib/src/custom_dialog_transitions.dart index dabea8c..2171a2d 100644 --- a/lib/src/custom_dialog_transitions.dart +++ b/lib/src/custom_dialog_transitions.dart @@ -18,8 +18,8 @@ class Rotation3DTransition extends AnimatedWidget { /// /// The [turns] argument must not be null. const Rotation3DTransition({ - Key key, - @required Animation turns, + Key? key, + required Animation turns, this.alignment = Alignment.center, this.child, }) : assert(turns != null), @@ -29,7 +29,7 @@ class Rotation3DTransition extends AnimatedWidget { /// /// If the current value of the turns animation is v, the child will be /// rotated v * 2 * pi radians before being painted. - Animation get turns => listenable; + Animation get turns => listenable as Animation; /// The alignment of the origin of the coordinate system around which the /// rotation occurs, relative to the size of the box. @@ -41,7 +41,7 @@ class Rotation3DTransition extends AnimatedWidget { /// The widget below this widget in the tree. /// /// {@macro flutter.widgets.child} - final Widget child; + final Widget? child; @override Widget build(BuildContext context) { @@ -73,8 +73,8 @@ class CustomRotationTransition extends AnimatedWidget { /// /// The [turns] argument must not be null. const CustomRotationTransition({ - Key key, - @required Animation turns, + Key? key, + required Animation turns, this.alignment = Alignment.center, this.child, }) : assert(turns != null), @@ -84,7 +84,7 @@ class CustomRotationTransition extends AnimatedWidget { /// /// If the current value of the turns animation is v, the child will be /// rotated v * 2 * pi radians before being painted. - Animation get turns => listenable; + Animation get turns => listenable as Animation; /// The alignment of the origin of the coordinate system around which the /// rotation occurs, relative to the size of the box. @@ -96,7 +96,7 @@ class CustomRotationTransition extends AnimatedWidget { /// The widget below this widget in the tree. /// /// {@macro flutter.widgets.child} - final Widget child; + final Widget? child; @override Widget build(BuildContext context) { diff --git a/pubspec.lock b/pubspec.lock index f190af6..2c27a98 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,51 +5,50 @@ packages: dependency: transitive description: name: async - url: "https://pub.flutter-io.cn" + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" source: hosted - version: "2.5.0-nullsafety.3" + version: "2.11.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.flutter-io.cn" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.1" characters: dependency: transitive description: name: characters - url: "https://pub.flutter-io.cn" + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" source: hosted - version: "1.1.0-nullsafety.5" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.2.0-nullsafety.3" + version: "1.3.0" clock: dependency: transitive description: name: clock - url: "https://pub.flutter-io.cn" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.1.1" collection: dependency: transitive description: name: collection - url: "https://pub.flutter-io.cn" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" source: hosted - version: "1.15.0-nullsafety.5" + version: "1.18.0" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.flutter-io.cn" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -60,27 +59,62 @@ packages: description: flutter source: sdk version: "0.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + url: "https://pub.dev" + source: hosted + version: "10.0.4" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + url: "https://pub.dev" + source: hosted + version: "3.0.3" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + url: "https://pub.dev" + source: hosted + version: "3.0.1" matcher: dependency: transitive description: name: matcher - url: "https://pub.flutter-io.cn" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + url: "https://pub.dev" + source: hosted + version: "0.12.16+1" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + url: "https://pub.dev" source: hosted - version: "0.12.10-nullsafety.3" + version: "0.8.0" meta: dependency: transitive description: name: meta - url: "https://pub.flutter-io.cn" + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + url: "https://pub.dev" source: hosted - version: "1.3.0-nullsafety.6" + version: "1.12.0" path: dependency: transitive description: name: path - url: "https://pub.flutter-io.cn" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + url: "https://pub.dev" source: hosted - version: "1.8.0-nullsafety.3" + version: "1.9.0" sky_engine: dependency: transitive description: flutter @@ -90,57 +124,66 @@ packages: dependency: transitive description: name: source_span - url: "https://pub.flutter-io.cn" + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" source: hosted - version: "1.8.0-nullsafety.4" + version: "1.10.0" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.flutter-io.cn" + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" source: hosted - version: "1.10.0-nullsafety.6" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.flutter-io.cn" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" source: hosted - version: "2.1.0-nullsafety.3" + version: "2.1.2" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.flutter-io.cn" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.0-nullsafety.3" + version: "1.2.0" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.flutter-io.cn" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted - version: "1.2.0-nullsafety.3" + version: "1.2.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.flutter-io.cn" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + url: "https://pub.dev" source: hosted - version: "0.2.19-nullsafety.6" - typed_data: + version: "0.7.0" + vector_math: dependency: transitive description: - name: typed_data - url: "https://pub.flutter-io.cn" + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "1.3.0-nullsafety.5" - vector_math: + version: "2.1.4" + vm_service: dependency: transitive description: - name: vector_math - url: "https://pub.flutter-io.cn" + name: vm_service + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + url: "https://pub.dev" source: hosted - version: "2.1.0-nullsafety.5" + version: "14.2.1" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=3.4.3 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index c8b1ef4..c2a8063 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/JackJonson/flutter_animated_dialog email: yswing1@gmail.com environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=3.4.3 <4.0.0' dependencies: flutter: @@ -20,6 +20,7 @@ dev_dependencies: # The following section is specific to Flutter. flutter: + uses-material-design: true # To add assets to your package, add an assets section, like this: # assets: