Jaime Blasco

Add support for null safety

Showing 54 changed files with 479 additions and 1010 deletions
... ... @@ -5,3 +5,7 @@ gradle-wrapper.jar
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
... ...
... ... @@ -26,21 +26,17 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
compileSdkVersion 30
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
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
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
<application
android:label="example"
android:icon="@mipmap/ic_launcher">
<activity
... ...
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
... ... @@ -12,7 +12,7 @@
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@android:color/white</item>
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
... ... @@ -6,7 +6,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
... ...
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
... ...
... ... @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
... ...
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
... ...
... ... @@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
... ...
... ... @@ -10,81 +10,32 @@ project 'Runner', {
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_key_values = {}
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) do |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
generated_key_values[podname] = podpath
else
puts "Invalid plugin specification: #{line}"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
generated_key_values
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
# Flutter Pod
copied_flutter_dir = File.join(__dir__, 'Flutter')
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
unless File.exist?(generated_xcode_build_settings_path)
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
unless File.exist?(copied_framework_path)
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
end
unless File.exist?(copied_podspec_path)
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
end
end
# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'
# Plugin Pods
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.each do |name, path|
symlink = File.join('.symlinks', 'plugins', name)
File.symlink(path, symlink)
pod name, :path => File.join(symlink, 'ios')
end
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
flutter_additional_ios_build_settings(target)
end
end
... ...
PODS:
- Flutter (1.0.0)
- url_launcher (0.0.1):
- Flutter
- url_launcher_macos (0.0.1):
- Flutter
- url_launcher_web (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
- url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`)
- url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
url_launcher:
:path: ".symlinks/plugins/url_launcher/ios"
url_launcher_macos:
:path: ".symlinks/plugins/url_launcher_macos/ios"
url_launcher_web:
:path: ".symlinks/plugins/url_launcher_web/ios"
SPEC CHECKSUMS:
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
url_launcher: a1c0cc845906122c4784c542523d8cacbded5626
url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
COCOAPODS: 1.8.4
... ... @@ -8,7 +8,6 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
212D1E304840672EFB9BFFA7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D52A2E75CF34C7E6DC549F4 /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
... ... @@ -32,12 +31,10 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
248080BB287D735D5E630360 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8D52A2E75CF34C7E6DC549F4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
... ... @@ -45,8 +42,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B3E04C271E591BD1327CA5FF /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
BAB1D322E537D55B4325D2C3 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
... ... @@ -54,24 +49,12 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
212D1E304840672EFB9BFFA7 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7FA2A098790C5377E18FABC1 /* Pods */ = {
isa = PBXGroup;
children = (
BAB1D322E537D55B4325D2C3 /* Pods-Runner.debug.xcconfig */,
B3E04C271E591BD1327CA5FF /* Pods-Runner.release.xcconfig */,
248080BB287D735D5E630360 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
... ... @@ -89,8 +72,6 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
7FA2A098790C5377E18FABC1 /* Pods */,
9D90B19A7E12B9186516773E /* Frameworks */,
);
sourceTree = "<group>";
};
... ... @@ -109,7 +90,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
... ... @@ -118,21 +98,6 @@
path = Runner;
sourceTree = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
);
name = "Supporting Files";
sourceTree = "<group>";
};
9D90B19A7E12B9186516773E /* Frameworks */ = {
isa = PBXGroup;
children = (
8D52A2E75CF34C7E6DC549F4 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
... ... @@ -140,14 +105,12 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
00BBBB875F21B7EBEF944E13 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
87338F8232AE1406F5B9308C /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
... ... @@ -165,7 +128,7 @@
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "The Chromium Authors";
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
... ... @@ -174,7 +137,7 @@
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
... ... @@ -206,28 +169,6 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
00BBBB875F21B7EBEF944E13 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
... ... @@ -242,21 +183,6 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
87338F8232AE1406F5B9308C /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
... ... @@ -307,7 +233,6 @@
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
... ... @@ -347,7 +272,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
... ... @@ -364,16 +289,8 @@
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
... ... @@ -384,7 +301,6 @@
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
... ... @@ -430,7 +346,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
... ... @@ -440,7 +356,6 @@
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
... ... @@ -480,7 +395,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
... ... @@ -498,16 +413,8 @@
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
... ... @@ -525,16 +432,8 @@
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
... ...
... ... @@ -4,7 +4,4 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
... ...
#import "GeneratedPluginRegistrant.h"
\ No newline at end of file
#import "GeneratedPluginRegistrant.h"
... ...
import 'dart:ui';
import 'package:example/examples/sliver_container.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
... ... @@ -72,7 +71,7 @@ class CupertinoSharePage extends StatelessWidget {
}
class PhotoShareBottomSheet extends StatelessWidget {
const PhotoShareBottomSheet({Key key}) : super(key: key);
const PhotoShareBottomSheet({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ... @@ -150,6 +149,7 @@ class PhotoShareBottomSheet extends StatelessWidget {
margin: EdgeInsets.symmetric(horizontal: 4),
child: Column(
children: <Widget>[
if(app.imageUrl != null)
Material(
child: ClipRRect(
child: Container(
... ... @@ -157,7 +157,7 @@ class PhotoShareBottomSheet extends StatelessWidget {
width: 60,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(app.imageUrl),
image: AssetImage(app.imageUrl!),
fit: BoxFit.cover),
color: Colors.white,
borderRadius:
... ... @@ -186,11 +186,7 @@ class PhotoShareBottomSheet extends StatelessWidget {
),
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 6),
sliver: SliverContainer(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12)),
sliver: SliverList(
sliver: SliverList(
delegate: SliverChildListDelegate.fixed(
List<Widget>.from(actions.map(
(action) => Container(
... ... @@ -206,14 +202,10 @@ class PhotoShareBottomSheet extends StatelessWidget {
height: 1,
))),
)),
),
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 6),
sliver: SliverContainer(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12)),
sliver: SliverList(
sliver: SliverList(
delegate: SliverChildListDelegate.fixed(
List<Widget>.from(actions1.map(
(action) => Container(
... ... @@ -228,15 +220,11 @@ class PhotoShareBottomSheet extends StatelessWidget {
)).addItemInBetween(Divider(
height: 1,
))),
)),
)
),
SliverPadding(
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 4),
sliver: SliverContainer(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12)),
sliver: SliverList(
sliver: SliverList(
delegate: SliverChildListDelegate.fixed(
List<Widget>.from(actions2.map(
(action) => Container(
... ... @@ -251,7 +239,7 @@ class PhotoShareBottomSheet extends StatelessWidget {
)).addItemInBetween(Divider(
height: 1,
))),
)),
)
),
SliverSafeArea(
top: false,
... ... @@ -280,10 +268,11 @@ class PhotoShareBottomSheet extends StatelessWidget {
margin: EdgeInsets.symmetric(horizontal: 4),
child: Column(
children: <Widget>[
if(person.imageUrl != null)
Material(
child: CircleAvatar(
backgroundImage: AssetImage(
person.imageUrl,
person.imageUrl!,
),
radius: 30,
backgroundColor: Colors.white,
... ... @@ -406,7 +395,7 @@ class PhotoShareBottomSheet extends StatelessWidget {
class Item {
final String title;
final String imageUrl;
final String? imageUrl;
Item(this.title, this.imageUrl);
}
... ... @@ -453,10 +442,9 @@ final actions2 = [
];
extension ListUtils<T> on List<T> {
List<T> addItemInBetween<T>(T item) => this.length == 0
List<T> addItemInBetween<A extends T>(A item) => this.length == 0
? this
: (this.fold([], (r, element) => [...r, element as T, item])
..removeLast());
: (this.fold([], (r, element) => [...r, element, item])..removeLast());
}
class SimpleSliverDelegate extends SliverPersistentHeaderDelegate {
... ... @@ -464,8 +452,8 @@ class SimpleSliverDelegate extends SliverPersistentHeaderDelegate {
final double height;
SimpleSliverDelegate({
this.child,
this.height,
required this.child,
required this.height,
});
@override
... ...
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
@immutable
class SliverContainer extends RenderObjectWidget {
SliverContainer(
{Key key,
this.padding = EdgeInsets.zero,
this.margin = EdgeInsets.zero,
this.borderRadius,
this.decoration,
this.foregroundDecoration,
this.sliver})
: super(key: key);
final EdgeInsets margin;
final BorderRadius borderRadius;
final EdgeInsets padding;
final Decoration decoration;
final Decoration foregroundDecoration;
final Widget sliver;
Widget get child => SliverPadding(padding: padding + margin, sliver: sliver);
Container get backgroundDecorationBox => Container(decoration: decoration);
Container get foregroundDecorationBox =>
Container(decoration: foregroundDecoration);
@override
_RenderSliverGroup createRenderObject(BuildContext context) {
return _RenderSliverGroup(
margin: this.margin, borderRadius: this.borderRadius, padding: padding);
}
@override
_SliverGroupElement createElement() => _SliverGroupElement(this);
@override
void updateRenderObject(
BuildContext context, _RenderSliverGroup renderObject) {
renderObject
..margin = margin
..padding = padding
..borderRadius = borderRadius;
}
}
class _SliverGroupElement extends RenderObjectElement {
_SliverGroupElement(SliverContainer widget) : super(widget);
Element _backgroundDecoration;
Element _foregroundDecoration;
Element _sliver;
@override
SliverContainer get widget => super.widget;
@override
void visitChildren(ElementVisitor visitor) {
if (_backgroundDecoration != null) visitor(_backgroundDecoration);
if (_foregroundDecoration != null) visitor(_foregroundDecoration);
if (_sliver != null) visitor(_sliver);
}
@override
void forgetChild(Element child) {
if (child == _backgroundDecoration) _backgroundDecoration = null;
if (child == _foregroundDecoration) _foregroundDecoration = null;
if (child == _sliver) _sliver = null;
super.forgetChild(child);
}
@override
void mount(Element parent, newSlot) {
super.mount(parent, newSlot);
_backgroundDecoration =
updateChild(_backgroundDecoration, widget.backgroundDecorationBox, 0);
_foregroundDecoration =
updateChild(_foregroundDecoration, widget.foregroundDecorationBox, 1);
_sliver = updateChild(_sliver, widget.child, 2);
}
@override
void update(RenderObjectWidget newWidget) {
super.update(newWidget);
assert(widget == newWidget);
_backgroundDecoration =
updateChild(_backgroundDecoration, widget.backgroundDecorationBox, 0);
_foregroundDecoration =
updateChild(_foregroundDecoration, widget.foregroundDecorationBox, 1);
_sliver = updateChild(_sliver, widget.child, 2);
}
@override
void insertChildRenderObject(RenderObject child, int slot) {
final _RenderSliverGroup renderObject = this.renderObject;
if (slot == 0) renderObject.decoration = child;
if (slot == 1) renderObject.foregroundDecoration = child;
if (slot == 2) renderObject.child = child;
assert(renderObject == this.renderObject);
}
@override
void moveChildRenderObject(RenderObject child, slot) {
assert(false);
}
@override
void removeChildRenderObject(RenderObject child) {
final _RenderSliverGroup renderObject = this.renderObject;
if (renderObject.decoration == child) renderObject.decoration = null;
if (renderObject.foregroundDecoration == child)
renderObject.foregroundDecoration = null;
if (renderObject.child == child) renderObject.child = null;
assert(renderObject == this.renderObject);
}
}
class _RenderSliverGroup extends RenderSliver with RenderSliverHelpers {
_RenderSliverGroup(
{EdgeInsetsGeometry margin,
EdgeInsetsGeometry padding,
BorderRadius borderRadius,
RenderBox decoration,
RenderBox foregroundDecoration,
RenderSliver child}) {
this.margin = margin;
this.padding = padding;
this.borderRadius = borderRadius;
this.foregroundDecoration = foregroundDecoration;
this.decoration = decoration;
this.child = child;
}
RRect _clipRRect;
EdgeInsetsGeometry get padding => _padding;
EdgeInsetsGeometry _padding;
set padding(EdgeInsetsGeometry value) {
assert(value != null);
assert(value.isNonNegative);
if (_padding == value) return;
_padding = value;
markNeedsLayout();
}
EdgeInsetsGeometry get margin => _margin;
EdgeInsetsGeometry _margin;
set margin(EdgeInsetsGeometry value) {
assert(value != null);
assert(value.isNonNegative);
if (_margin == value) return;
_margin = value;
markNeedsLayout();
}
BorderRadiusGeometry get borderRadius => _borderRadius;
BorderRadiusGeometry _borderRadius;
set borderRadius(BorderRadiusGeometry value) {
if (value == _borderRadius) return;
_borderRadius = value;
markNeedsPaint();
}
RenderBox get decoration => _decoration;
RenderBox _decoration;
set decoration(RenderBox value) {
if (_decoration != null) dropChild(_decoration);
_decoration = value;
if (_decoration != null) adoptChild(_decoration);
}
RenderBox get foregroundDecoration => _foregroundDecoration;
RenderBox _foregroundDecoration;
set foregroundDecoration(RenderBox value) {
if (_foregroundDecoration != null) dropChild(_foregroundDecoration);
_foregroundDecoration = value;
if (_foregroundDecoration != null) adoptChild(_foregroundDecoration);
}
RenderSliver get child => _child;
RenderSliver _child;
set child(RenderSliver value) {
if (_child != null) dropChild(_child);
_child = value;
if (_child != null) adoptChild(_child);
}
@override
void setupParentData(RenderObject child) {
if (child.parentData is! SliverPhysicalParentData)
child.parentData = new SliverPhysicalParentData();
}
@override
void attach(PipelineOwner owner) {
super.attach(owner);
if (_decoration != null) _decoration.attach(owner);
if (_child != null) _child.attach(owner);
if (_foregroundDecoration != null) _foregroundDecoration.attach(owner);
}
@override
void detach() {
super.detach();
if (_decoration != null) _decoration.detach();
if (_child != null) _child.detach();
if (_foregroundDecoration != null) _foregroundDecoration.detach();
}
@override
void redepthChildren() {
if (_decoration != null) redepthChild(_decoration);
if (_child != null) redepthChild(_child);
if (_foregroundDecoration != null) redepthChild(_foregroundDecoration);
}
@override
void visitChildren(RenderObjectVisitor visitor) {
if (_decoration != null) visitor(_decoration);
if (_child != null) visitor(_child);
if (_foregroundDecoration != null) visitor(_foregroundDecoration);
}
@override
List<DiagnosticsNode> debugDescribeChildren() {
List<DiagnosticsNode> result = <DiagnosticsNode>[];
if (decoration != null) {
result.add(decoration.toDiagnosticsNode(name: 'decoration'));
}
if (foregroundDecoration != null) {
result.add(foregroundDecoration.toDiagnosticsNode(
name: 'foreground_decoration'));
}
if (child != null) {
result.add(child.toDiagnosticsNode(name: 'child'));
}
return result;
}
@override
bool hitTestChildren(HitTestResult result,
{double mainAxisPosition, double crossAxisPosition}) {
assert(geometry.hitTestExtent > 0.0);
return child.hitTest(result,
mainAxisPosition: mainAxisPosition,
crossAxisPosition: crossAxisPosition);
}
@override
void performLayout() {
if (child == null) {
geometry = SliverGeometry();
return;
}
// child not null
AxisDirection axisDirection = applyGrowthDirectionToAxisDirection(
constraints.axisDirection, constraints.growthDirection);
// layout sliver
child.layout(constraints, parentUsesSize: true);
final SliverGeometry childLayoutGeometry = child.geometry;
geometry = childLayoutGeometry;
// layout decoration with child size + margin
//Todo: Support rtl
EdgeInsets margin = this.margin.resolve(TextDirection.ltr);
final maxExtent = childLayoutGeometry.maxPaintExtent - margin.horizontal;
final crossAxisExtent = constraints.crossAxisExtent - margin.vertical;
if (decoration != null) {
decoration.layout(
constraints.asBoxConstraints(
maxExtent: maxExtent, crossAxisExtent: crossAxisExtent),
parentUsesSize: true);
}
if (foregroundDecoration != null) {
foregroundDecoration.layout(
constraints.asBoxConstraints(
maxExtent: maxExtent, crossAxisExtent: crossAxisExtent),
parentUsesSize: true);
}
// compute decoration offset
final SliverPhysicalParentData headerParentData = decoration.parentData;
final SliverPhysicalParentData foregroundParentData =
foregroundDecoration.parentData;
double scrollOffset = -constraints.scrollOffset;
Offset offset;
switch (axisDirection) {
case AxisDirection.up:
offset = Offset(0.0, geometry.paintExtent);
break;
case AxisDirection.down:
offset = Offset(0, scrollOffset);
break;
case AxisDirection.left:
offset = Offset(geometry.paintExtent, 0.0);
break;
case AxisDirection.right:
offset = Offset.zero;
break;
}
offset += Offset(margin.left, margin.top);
headerParentData.paintOffset = offset;
foregroundParentData.paintOffset = offset;
//compute child clip
if (this.borderRadius != null) {
BorderRadius borderRadius = this.borderRadius.resolve(TextDirection.ltr);
_clipRRect = borderRadius.toRRect(Rect.fromLTRB(
0, 0, constraints.crossAxisExtent, geometry.maxPaintExtent));
double offSetY = scrollOffset;
_clipRRect = _clipRRect.shift(Offset(0, offSetY));
}
}
@override
void applyPaintTransform(RenderObject child, Matrix4 transform) {
assert(child != null);
final SliverPhysicalParentData childParentData = child.parentData;
childParentData.applyPaintTransform(transform);
}
@override
void paint(PaintingContext context, Offset offset) {
if (geometry.visible) {
// paint decoration
if (decoration != null) {
final SliverPhysicalParentData childParentData = decoration.parentData;
context.paintChild(decoration, offset + childParentData.paintOffset);
}
// paint child
if (child != null && child.geometry.visible) {
final SliverPhysicalParentData childParentData = child.parentData;
final PaintingContextCallback painter =
(PaintingContext context, Offset offset) {
context.paintChild(child, offset);
};
if (_clipRRect != null && _clipRRect != RRect.zero) {
context.pushClipRRect(
needsCompositing,
offset + childParentData.paintOffset,
_clipRRect.outerRect,
_clipRRect,
painter,
);
} else {
painter(context, offset + childParentData.paintOffset);
}
}
if (foregroundDecoration != null) {
final SliverPhysicalParentData childParentData =
foregroundDecoration.parentData;
context.paintChild(
foregroundDecoration, offset + childParentData.paintOffset);
}
}
}
}
... ... @@ -25,8 +25,8 @@ class MyApp extends StatelessWidget {
return MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
title: 'BottomSheet Modals',
builder: (context, child) => WebFrame(
child: child,
builder: (context, Widget? child) => WebFrame(
child: child!,
),
onGenerateRoute: (RouteSettings settings) {
switch (settings.name) {
... ... @@ -84,7 +84,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);
final String title;
... ...
... ... @@ -9,7 +9,7 @@ class AvatarBottomSheet extends StatelessWidget {
final Widget child;
final Animation<double> animation;
const AvatarBottomSheet({Key key, this.child, this.animation})
const AvatarBottomSheet({Key? key, required this.child, required this.animation})
: super(key: key);
@override
... ... @@ -67,21 +67,21 @@ class AvatarBottomSheet extends StatelessWidget {
}
}
Future<T> showAvatarModalBottomSheet<T>({
@required BuildContext context,
@required WidgetBuilder builder,
Color backgroundColor,
double elevation,
ShapeBorder shape,
Clip clipBehavior,
Future<T?> showAvatarModalBottomSheet<T>({
required BuildContext context,
required WidgetBuilder builder,
Color? backgroundColor,
double? elevation,
ShapeBorder? shape,
Clip? clipBehavior,
Color barrierColor = Colors.black87,
bool bounce = true,
bool expand = false,
AnimationController secondAnimation,
AnimationController? secondAnimation,
bool useRootNavigator = false,
bool isDismissible = true,
bool enableDrag = true,
Duration duration,
Duration? duration,
}) async {
assert(context != null);
assert(builder != null);
... ...
... ... @@ -4,9 +4,9 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class FloatingModal extends StatelessWidget {
final Widget child;
final Color backgroundColor;
final Color? backgroundColor;
const FloatingModal({Key key, this.child, this.backgroundColor})
const FloatingModal({Key? key, required this.child, this.backgroundColor})
: super(key: key);
@override
... ... @@ -26,9 +26,9 @@ class FloatingModal extends StatelessWidget {
}
Future<T> showFloatingModalBottomSheet<T>({
@required BuildContext context,
@required WidgetBuilder builder,
Color backgroundColor,
required BuildContext context,
required WidgetBuilder builder,
Color? backgroundColor,
}) async {
final result = await showCustomModalBottomSheet(
context: context,
... ...
... ... @@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class ComplexModal extends StatelessWidget {
const ComplexModal({Key key}) : super(key: key);
const ComplexModal({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ModalFit extends StatelessWidget {
const ModalFit({Key key}) : super(key: key);
const ModalFit({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -5,7 +5,7 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class ModalInsideModal extends StatelessWidget {
final bool reverse;
const ModalInsideModal({Key key, this.reverse = false}) : super(key: key);
const ModalInsideModal({Key? key, this.reverse = false}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -2,9 +2,9 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SimpleModal extends StatelessWidget {
final ScrollController scrollController;
const SimpleModal({Key key, this.scrollController}) : super(key: key);
const SimpleModal({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ModalWillScope extends StatelessWidget {
const ModalWillScope({Key key}) : super(key: key);
const ModalWillScope({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class ModalWithNavigator extends StatelessWidget {
const ModalWithNavigator({Key key}) : super(key: key);
const ModalWithNavigator({Key? key}) : super(key: key);
@override
Widget build(BuildContext rootContext) {
... ...
... ... @@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class NestedScrollModal extends StatelessWidget {
const NestedScrollModal({Key key}) : super(key: key);
const NestedScrollModal({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class ModalWithPageView extends StatelessWidget {
const ModalWithPageView({Key key}) : super(key: key);
const ModalWithPageView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class ModalWithScroll extends StatelessWidget {
const ModalWithScroll({Key key}) : super(key: key);
const ModalWithScroll({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -7,7 +7,7 @@ import 'package:url_launcher/url_launcher.dart';
class WebFrame extends StatelessWidget {
final Widget child;
const WebFrame({Key key, this.child}) : super(key: key);
const WebFrame({Key? key, required this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -21,6 +21,7 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
07F1EEFF1D7280028D8E0815 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6785DE70E6CF5A12A3672D00 /* Pods_Runner.framework */; };
335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; };
33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; };
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
... ... @@ -28,7 +29,6 @@
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; };
33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
7750D706F7F4EF7A4673CFC3 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F36D136272EAF3C8E9406E8 /* Pods_Runner.framework */; };
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; };
D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
... ... @@ -59,8 +59,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1601E62CD620826356A7224C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
31540D3B1454E3935C2255AE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
123E850BF31901C0A1B9EDF9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
12CD678DD42B59A87A0100ED /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; };
... ... @@ -76,9 +76,9 @@
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
6F36D136272EAF3C8E9406E8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6785DE70E6CF5A12A3672D00 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
8C45A9FE6302E0520D92F872 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
956A1C59D4E7DF8845616D84 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
... ... @@ -90,7 +90,7 @@
files = (
D73912F022F37F9E000D13A0 /* App.framework in Frameworks */,
33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */,
7750D706F7F4EF7A4673CFC3 /* Pods_Runner.framework in Frameworks */,
07F1EEFF1D7280028D8E0815 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
... ... @@ -115,7 +115,7 @@
33CEB47122A05771004F2AC0 /* Flutter */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
9350091802CFC393284BD46E /* Pods */,
A1F7D023EEA811516CAA2CF1 /* Pods */,
);
sourceTree = "<group>";
};
... ... @@ -164,12 +164,12 @@
path = Runner;
sourceTree = "<group>";
};
9350091802CFC393284BD46E /* Pods */ = {
A1F7D023EEA811516CAA2CF1 /* Pods */ = {
isa = PBXGroup;
children = (
1601E62CD620826356A7224C /* Pods-Runner.debug.xcconfig */,
8C45A9FE6302E0520D92F872 /* Pods-Runner.release.xcconfig */,
31540D3B1454E3935C2255AE /* Pods-Runner.profile.xcconfig */,
12CD678DD42B59A87A0100ED /* Pods-Runner.debug.xcconfig */,
123E850BF31901C0A1B9EDF9 /* Pods-Runner.release.xcconfig */,
956A1C59D4E7DF8845616D84 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
... ... @@ -178,7 +178,7 @@
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
6F36D136272EAF3C8E9406E8 /* Pods_Runner.framework */,
6785DE70E6CF5A12A3672D00 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
... ... @@ -190,13 +190,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
84BD7313E5046A1EFFEE4684 /* [CP] Check Pods Manifest.lock */,
39807FAAEE6C2A7DC7608117 /* [CP] Check Pods Manifest.lock */,
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
3F31035F17BB50E98F3B6DB3 /* [CP] Embed Pods Frameworks */,
A477A0AC3B4E8DBC8C9DA73C /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
... ... @@ -216,7 +216,7 @@
attributes = {
LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 0930;
ORGANIZATIONNAME = "The Flutter Authors";
ORGANIZATIONNAME = "";
TargetAttributes = {
33CC10EC2044A3C60003C045 = {
CreatedOnToolsVersion = 9.2;
... ... @@ -235,7 +235,7 @@
};
};
buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 8.0";
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
... ... @@ -301,43 +301,43 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n";
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
3F31035F17BB50E98F3B6DB3 /* [CP] Embed Pods Frameworks */ = {
39807FAAEE6C2A7DC7608117 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
name = "[CP] Embed Pods Frameworks";
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
84BD7313E5046A1EFFEE4684 /* [CP] Check Pods Manifest.lock */ = {
A477A0AC3B4E8DBC8C9DA73C /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
... ...
... ... @@ -27,18 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00380F9121DF178D00097171"
BuildableName = "RunnerUITests.xctest"
BlueprintName = "RunnerUITests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
... ... @@ -75,7 +63,7 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
... ...
... ... @@ -11,4 +11,4 @@ PRODUCT_NAME = example
PRODUCT_BUNDLE_IDENTIFIER = com.example.example
// The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2020 com.example. All rights reserved.
PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved.
... ...
... ... @@ -7,42 +7,42 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0-nullsafety.2"
version: "2.5.0-nullsafety.3"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.2"
version: "2.1.0-nullsafety.3"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.4"
version: "1.1.0-nullsafety.5"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.2"
version: "1.2.0-nullsafety.3"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.2"
version: "1.1.0-nullsafety.3"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0-nullsafety.4"
version: "1.15.0-nullsafety.5"
cupertino_icons:
dependency: "direct main"
description:
... ... @@ -56,7 +56,7 @@ packages:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.2"
version: "1.2.0-nullsafety.3"
flutter:
dependency: "direct main"
description: flutter
... ... @@ -67,53 +67,41 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3-nullsafety.2"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10-nullsafety.2"
version: "0.12.10-nullsafety.3"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.5"
version: "1.3.0-nullsafety.6"
modal_bottom_sheet:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "1.0.0"
version: "1.0.0+1"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.2"
version: "1.8.0-nullsafety.3"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
version: "1.1.0-nullsafety.1"
sky_engine:
dependency: transitive
description: flutter
... ... @@ -125,98 +113,91 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.3"
version: "1.8.0-nullsafety.4"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0-nullsafety.5"
version: "1.10.0-nullsafety.6"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.2"
version: "2.1.0-nullsafety.3"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.2"
version: "1.1.0-nullsafety.3"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.2"
version: "1.2.0-nullsafety.3"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19-nullsafety.4"
version: "0.2.19-nullsafety.6"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.4"
version: "1.3.0-nullsafety.5"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "5.7.10"
version: "6.0.0-nullsafety.1"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+4"
version: "0.1.0-nullsafety.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+9"
version: "0.1.0-nullsafety.1"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.9"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5+1"
version: "2.0.0-nullsafety.1"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+3"
version: "0.1.0-nullsafety.1"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.4"
version: "2.1.0-nullsafety.5"
sdks:
dart: ">=2.11.0-0.0 <2.12.0"
flutter: ">=1.22.0 <2.0.0"
dart: ">=2.12.0-29.10.beta <3.0.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0"
... ...
... ... @@ -14,12 +14,12 @@ description: A new Flutter project.
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
sdk: ">=2.12.0-29.10.beta <3.0.0"
dependencies:
flutter:
sdk: flutter
url_launcher: ^5.4.2
url_launcher: 6.0.0-nullsafety.1
modal_bottom_sheet:
path: '../'
... ...
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<!-- Primary Meta Tags -->
<title>Flutter Modal Bottom Sheets</title>
<meta name="title" content="Flutter Modal Bottom Sheets">
<meta name="description" content="Build advanced modals. Cupertino, material or create your own">
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://jamesblasco.github.io/modal_bottom_sheet/">
<meta property="og:title" content="Flutter Modal Bottom Sheets">
<meta property="og:description" content="Build advanced modals. Cupertino, material or create your own">
<meta property="og:image" content="https://jamesblasco.github.io/modal_bottom_sheet/icons/image.png">
Fore more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
-->
<base href="/">
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image">
<meta property="twitter:url" content="https://jamesblasco.github.io/modal_bottom_sheet/">
<meta property="twitter:title" content="Flutter Modal Bottom Sheets">
<meta property="twitter:description" content="Build advanced modals. Cupertino, material or create your own">
<meta property="og:image" content="https://jamesblasco.github.io/modal_bottom_sheet/icons/image.png">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="example">
<link rel="apple-touch-icon" href="/icons/Icon-192.png">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="shortcut icon" type="image/png" href="/favicon.png"/>
<link rel="icon" type="image/png" href="favicon.png"/>
<link rel="manifest" href="/manifest.json">
<title>example</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
... ... @@ -39,10 +35,8 @@
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('flutter_service_worker.js', {
scope: './'
});
window.addEventListener('flutter-first-frame', function () {
navigator.serviceWorker.register('flutter_service_worker.js');
});
}
</script>
... ...
... ... @@ -2,7 +2,7 @@
"name": "example",
"short_name": "example",
"start_url": ".",
"display": "minimal-ui",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
... ...
... ... @@ -37,26 +37,26 @@ typedef WidgetWithChildBuilder = Widget Function(
class ModalBottomSheet extends StatefulWidget {
/// Creates a bottom sheet.
const ModalBottomSheet({
Key key,
Key? key,
this.closeProgressThreshold,
this.animationController,
required this.animationController,
this.animationCurve,
this.enableDrag = true,
this.containerBuilder,
this.bounce = true,
this.shouldClose,
this.scrollController,
this.expanded,
@required this.onClosing,
@required this.child,
}) : assert(enableDrag != null),
required this.scrollController,
required this.expanded,
required this.onClosing,
required this.child,
}) : assert(enableDrag != null),
assert(onClosing != null),
assert(child != null),
super(key: key);
/// The closeProgressThreshold parameter
/// specifies when the bottom sheet will be dismissed when user drags it.
final double closeProgressThreshold;
final double? closeProgressThreshold;
/// The animation controller that controls the bottom sheet's entrance and
/// exit animations.
... ... @@ -68,7 +68,7 @@ class ModalBottomSheet extends StatefulWidget {
/// The curve used by the animation showing and dismissing the bottom sheet.
///
/// If no curve is provided it falls back to `decelerateEasing`.
final Curve animationCurve;
final Curve? animationCurve;
/// Allows the bottom sheet to go beyond the top bound of the content,
/// but then bounce the content back to the edge of
... ... @@ -79,7 +79,7 @@ class ModalBottomSheet extends StatefulWidget {
// or if false it will fit to the content of the widget
final bool expanded;
final WidgetWithChildBuilder containerBuilder;
final WidgetWithChildBuilder? containerBuilder;
/// Called when the bottom sheet begins to close.
///
... ... @@ -93,7 +93,7 @@ class ModalBottomSheet extends StatefulWidget {
// If returns false => The dialog cancels close
// Notice that if shouldClose is not null, the dialog will go back to the
// previous position until the function is solved
final Future<bool> Function() shouldClose;
final Future<bool> Function()? shouldClose;
/// A builder for the contents of the sheet.
///
... ... @@ -118,7 +118,7 @@ class ModalBottomSheet extends StatefulWidget {
/// animation controller could be provided.
static AnimationController createAnimationController(
TickerProvider vsync, {
Duration duration,
Duration? duration,
}) {
return AnimationController(
duration: duration ?? _bottomSheetDuration,
... ... @@ -134,10 +134,11 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
ScrollController get _scrollController => widget.scrollController;
AnimationController _bounceDragController;
late AnimationController _bounceDragController;
double get _childHeight {
final renderBox = _childKey.currentContext.findRenderObject() as RenderBox;
double? get _childHeight {
final childContext = _childKey.currentContext;
final renderBox = childContext?.findRenderObject() as RenderBox;
return renderBox.size.height;
}
... ... @@ -176,14 +177,14 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
FutureOr<bool> shouldClose() async {
if (_isCheckingShouldClose) return false;
if (widget.shouldClose == null) return null;
if (widget.shouldClose == null) return false;
_isCheckingShouldClose = true;
final result = await widget.shouldClose();
final result = await widget.shouldClose?.call();
_isCheckingShouldClose = false;
return result;
return result ?? false;
}
ParametricCurve<double> animationCurve;
ParametricCurve<double> animationCurve = Curves.linear;
void _handleDragUpdate(double primaryDelta) async {
animationCurve = Curves.linear;
... ... @@ -230,7 +231,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
// ignore: unawaited_futures
_bounceDragController.reverse();
var canClose = true;
bool canClose = true;
if (widget.shouldClose != null && hasReachedWillPopThreshold) {
_cancelClose();
canClose = await shouldClose();
... ... @@ -257,10 +258,11 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
// we can not know the DragDownDetails and therefore the end velocity.
// VelocityTracker it is used to calculate the end velocity of the scroll
// when user is trying to close the modal by dragging
VelocityTracker _velocityTracker;
DateTime _startTime;
VelocityTracker? _velocityTracker;
DateTime? _startTime;
void _handleScrollUpdate(ScrollNotification notification) {
assert(notification.context != null);
//Check if scrollController is used
if (!_scrollController.hasClients) return;
//Check if there is more than 1 attached ScrollController e.g. swiping page in PageView
... ... @@ -268,7 +270,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
if (_scrollController.positions.length > 1) return;
if (_scrollController !=
Scrollable.of(notification.context).widget.controller) return;
Scrollable.of(notification.context!)!.widget.controller) return;
final scrollPosition = _scrollController.position;
... ... @@ -284,12 +286,14 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
// while Bouncing Scroll Physics or other physics that Overflow don't return a drag end info
// We use the velocity from DragEndDetail in case it is available
if (notification is ScrollEndNotification &&
notification.dragDetails != null) {
_handleDragEnd(notification.dragDetails.primaryVelocity);
_velocityTracker = null;
_startTime = null;
return;
if (notification is ScrollEndNotification) {
final dragDetails = notification.dragDetails;
if (dragDetails != null) {
_handleDragEnd(dragDetails.primaryVelocity ?? 0);
_velocityTracker = null;
_startTime = null;
return;
}
}
// Otherwise the calculate the velocity with a VelocityTracker
... ... @@ -299,19 +303,24 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
_velocityTracker = VelocityTracker();
_startTime = DateTime.now();
}
DragUpdateDetails dragDetails;
DragUpdateDetails? dragDetails;
if (notification is ScrollUpdateNotification) {
dragDetails = notification.dragDetails;
}
if (notification is OverscrollNotification) {
dragDetails = notification.dragDetails;
}
assert(_velocityTracker != null);
assert(_startTime != null);
final startTime = _startTime!;
final velocityTracker = _velocityTracker!;
if (dragDetails != null) {
final duration = _startTime.difference(DateTime.now());
_velocityTracker.addPosition(duration, Offset(0, offset));
final duration = startTime.difference(DateTime.now());
velocityTracker.addPosition(duration, Offset(0, offset));
_handleDragUpdate(dragDetails.delta.dy);
} else if (isDragging) {
final velocity = _velocityTracker.getVelocity().pixelsPerSecond.dy;
final velocity = velocityTracker.getVelocity().pixelsPerSecond.dy;
_velocityTracker = null;
_startTime = null;
_handleDragEnd(velocity);
... ... @@ -319,8 +328,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
}
}
ParametricCurve<double> get _defaultCurve =>
widget.animationCurve ?? _modalBottomSheetCurve;
Curve get _defaultCurve => widget.animationCurve ?? _modalBottomSheetCurve;
@override
void initState() {
... ... @@ -341,7 +349,7 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
var child = widget.child;
if (widget.containerBuilder != null) {
child = widget.containerBuilder(
child = widget.containerBuilder!(
context,
widget.animationController,
child,
... ... @@ -352,7 +360,8 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
child = AnimatedBuilder(
animation: widget.animationController,
builder: (context, child) {
builder: (context, Widget? child) {
assert(child != null);
final animationValue = animationCurve.transform(
mediaQuery.accessibleNavigation
? 1.0
... ... @@ -371,14 +380,14 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
_handleDragUpdate(details.delta.dy);
},
onVerticalDragEnd: (details) {
_handleDragEnd(details.primaryVelocity);
_handleDragEnd(details.primaryVelocity ?? 0);
},
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
_handleScrollUpdate(notification);
return false;
},
child: child,
child: child!,
),
),
),
... ... @@ -435,7 +444,7 @@ class _CustomBottomSheetLayout extends SingleChildLayoutDelegate {
_CustomBottomSheetLayout(this.progress);
final double progress;
double childHeight;
double? childHeight;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
... ... @@ -468,7 +477,7 @@ class _CustomBottomSheetLayout extends SingleChildLayoutDelegate {
// Used with VelocityTracker
// https://github.com/flutter/flutter/pull/64267#issuecomment-694196304
PointerDeviceKind defaultPointerDeviceKind(BuildContext context) {
final platform = Theme.of(context)?.platform ?? defaultTargetPlatform;
final platform = Theme.of(context).platform; // ?? defaultTargetPlatform;
switch (platform) {
case TargetPlatform.iOS:
case TargetPlatform.android:
... ...
... ... @@ -11,9 +11,9 @@ const Duration _bottomSheetDuration = Duration(milliseconds: 400);
class _ModalBottomSheet<T> extends StatefulWidget {
const _ModalBottomSheet({
Key key,
Key? key,
this.closeProgressThreshold,
this.route,
required this.route,
this.secondAnimationController,
this.bounce = false,
this.expanded = false,
... ... @@ -23,13 +23,13 @@ class _ModalBottomSheet<T> extends StatefulWidget {
assert(enableDrag != null),
super(key: key);
final double closeProgressThreshold;
final double? closeProgressThreshold;
final ModalBottomSheetRoute<T> route;
final bool expanded;
final bool bounce;
final bool enableDrag;
final AnimationController secondAnimationController;
final Curve animationCurve;
final AnimationController? secondAnimationController;
final Curve? animationCurve;
@override
_ModalBottomSheetState<T> createState() => _ModalBottomSheetState<T>();
... ... @@ -37,7 +37,7 @@ class _ModalBottomSheet<T> extends StatefulWidget {
class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
String _getRouteLabel() {
final platform = Theme.of(context)?.platform ?? defaultTargetPlatform;
final platform = Theme.of(context).platform; //?? defaultTargetPlatform;
switch (platform) {
case TargetPlatform.iOS:
case TargetPlatform.linux:
... ... @@ -52,39 +52,43 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
return DefaultMaterialLocalizations().dialogLabel;
}
}
return null;
}
ScrollController _scrollController;
ScrollController? _scrollController;
@override
void initState() {
widget.route.animation.addListener(updateController);
widget.route.animation?.addListener(updateController);
super.initState();
}
@override
void dispose() {
widget.route.animation.removeListener(updateController);
widget.route.animation?.removeListener(updateController);
_scrollController?.dispose();
super.dispose();
}
void updateController() {
widget.secondAnimationController?.value = widget.route.animation.value;
final animation = widget.route.animation;
if (animation != null) {
widget.secondAnimationController?.value = animation.value;
}
}
@override
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
assert(widget.route._animationController != null);
final scrollController = PrimaryScrollController.of(context) ??
(_scrollController ??= ScrollController());
return ModalScrollController(
controller: scrollController,
child: Builder(
builder: (context) => AnimatedBuilder(
animation: widget.route._animationController,
builder: (BuildContext context, Widget child) {
animation: widget.route._animationController!,
builder: (BuildContext context, final Widget? child) {
assert(child != null);
// Disable the initial animation when accessible navigation is on so
// that the semantics are added to the tree at the correct time.
return Semantics(
... ... @@ -95,7 +99,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
child: ModalBottomSheet(
expanded: widget.route.expanded,
containerBuilder: widget.route.containerBuilder,
animationController: widget.route._animationController,
animationController: widget.route._animationController!,
shouldClose: widget.route._hasScopedWillPopCallback
? () async {
final willPop = await widget.route.willPop();
... ... @@ -107,7 +111,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
Navigator.of(context).pop();
}
},
child: child,
child: child!,
enableDrag: widget.enableDrag,
bounce: widget.bounce,
scrollController: scrollController,
... ... @@ -126,37 +130,37 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> {
ModalBottomSheetRoute({
this.closeProgressThreshold,
this.containerBuilder,
this.builder,
required this.builder,
this.scrollController,
this.barrierLabel,
this.secondAnimationController,
this.modalBarrierColor,
this.isDismissible = true,
this.enableDrag = true,
@required this.expanded,
required this.expanded,
this.bounce = false,
this.animationCurve,
this.duration,
RouteSettings settings,
RouteSettings? settings,
}) : assert(expanded != null),
assert(isDismissible != null),
assert(enableDrag != null),
super(settings: settings);
final double closeProgressThreshold;
final WidgetWithChildBuilder containerBuilder;
final double? closeProgressThreshold;
final WidgetWithChildBuilder? containerBuilder;
final WidgetBuilder builder;
final bool expanded;
final bool bounce;
final Color modalBarrierColor;
final Color? modalBarrierColor;
final bool isDismissible;
final bool enableDrag;
final ScrollController scrollController;
final ScrollController? scrollController;
final Duration duration;
final Duration? duration;
final AnimationController secondAnimationController;
final Curve animationCurve;
final AnimationController? secondAnimationController;
final Curve? animationCurve;
@override
Duration get transitionDuration => duration ?? _bottomSheetDuration;
... ... @@ -165,21 +169,21 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> {
bool get barrierDismissible => isDismissible;
@override
final String barrierLabel;
final String? barrierLabel;
@override
Color get barrierColor => modalBarrierColor ?? Colors.black.withOpacity(0.35);
AnimationController _animationController;
AnimationController? _animationController;
@override
AnimationController createAnimationController() {
assert(_animationController == null);
_animationController = ModalBottomSheet.createAnimationController(
navigator.overlay,
duration: duration,
navigator!.overlay!,
duration: transitionDuration,
);
return _animationController;
return _animationController!;
}
bool get _hasScopedWillPopCallback => hasScopedWillPopCallback;
... ... @@ -223,23 +227,23 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> {
}
/// Shows a modal material design bottom sheet.
Future<T> showCustomModalBottomSheet<T>({
@required BuildContext context,
@required WidgetBuilder builder,
@required WidgetWithChildBuilder containerWidget,
Color backgroundColor,
double elevation,
ShapeBorder shape,
Clip clipBehavior,
Color barrierColor,
Future<T?> showCustomModalBottomSheet<T>({
required BuildContext context,
required WidgetBuilder builder,
required WidgetWithChildBuilder containerWidget,
Color? backgroundColor,
double? elevation,
ShapeBorder? shape,
Clip? clipBehavior,
Color? barrierColor,
bool bounce = false,
bool expand = false,
AnimationController secondAnimation,
Curve animationCurve,
AnimationController? secondAnimation,
Curve? animationCurve,
bool useRootNavigator = false,
bool isDismissible = true,
bool enableDrag = true,
Duration duration,
Duration? duration,
}) async {
assert(context != null);
assert(builder != null);
... ...
... ... @@ -10,19 +10,19 @@ const Radius _default_bar_top_radius = Radius.circular(15);
class BarBottomSheet extends StatelessWidget {
final Widget child;
final Widget control;
final Clip clipBehavior;
final double elevation;
final ShapeBorder shape;
final Widget? control;
final Clip? clipBehavior;
final double? elevation;
final ShapeBorder? shape;
const BarBottomSheet(
{Key key,
this.child,
this.control,
this.clipBehavior,
this.shape,
this.elevation})
: super(key: key);
const BarBottomSheet({
Key? key,
required this.child,
this.control,
this.clipBehavior,
this.shape,
this.elevation,
}) : super(key: key);
@override
Widget build(BuildContext context) {
... ... @@ -70,24 +70,24 @@ class BarBottomSheet extends StatelessWidget {
}
}
Future<T> showBarModalBottomSheet<T>({
@required BuildContext context,
@required WidgetBuilder builder,
Color backgroundColor,
double elevation,
ShapeBorder shape,
double closeProgressThreshold,
Clip clipBehavior,
Future<T?> showBarModalBottomSheet<T>({
required BuildContext context,
required WidgetBuilder builder,
Color? backgroundColor,
double? elevation,
ShapeBorder? shape,
double? closeProgressThreshold,
Clip? clipBehavior,
Color barrierColor = Colors.black87,
bool bounce = true,
bool expand = false,
AnimationController secondAnimation,
Curve animationCurve,
AnimationController? secondAnimation,
Curve? animationCurve,
bool useRootNavigator = false,
bool isDismissible = true,
bool enableDrag = true,
Widget topControl,
Duration duration,
Widget? topControl,
Duration? duration,
}) async {
assert(context != null);
assert(builder != null);
... ...
... ... @@ -30,12 +30,15 @@ const Radius _default_top_radius = Radius.circular(12);
/// is the height that will be displayed from previous route.
class _CupertinoBottomSheetContainer extends StatelessWidget {
final Widget child;
final Color backgroundColor;
final Color? backgroundColor;
final Radius topRadius;
const _CupertinoBottomSheetContainer(
{Key key, this.child, this.backgroundColor, @required this.topRadius})
: super(key: key);
const _CupertinoBottomSheetContainer({
Key? key,
required this.child,
this.backgroundColor,
required this.topRadius,
}) : super(key: key);
@override
Widget build(BuildContext context) {
... ... @@ -65,27 +68,27 @@ class _CupertinoBottomSheetContainer extends StatelessWidget {
}
}
Future<T> showCupertinoModalBottomSheet<T>({
@required BuildContext context,
@required WidgetBuilder builder,
Color backgroundColor,
double elevation,
double closeProgressThreshold,
ShapeBorder shape,
Clip clipBehavior,
Color barrierColor,
Future<T?> showCupertinoModalBottomSheet<T>({
required BuildContext context,
required WidgetBuilder builder,
Color? backgroundColor,
double? elevation,
double? closeProgressThreshold,
ShapeBorder? shape,
Clip? clipBehavior,
Color? barrierColor,
bool expand = false,
AnimationController secondAnimation,
Curve animationCurve,
Curve previousRouteAnimationCurve,
AnimationController? secondAnimation,
Curve? animationCurve,
Curve? previousRouteAnimationCurve,
bool useRootNavigator = false,
bool bounce = true,
bool isDismissible,
bool? isDismissible,
bool enableDrag = true,
Radius topRadius = _default_top_radius,
Duration duration,
RouteSettings settings,
Color transitionBackgroundColor,
Duration? duration,
RouteSettings? settings,
Color? transitionBackgroundColor,
}) async {
assert(context != null);
assert(builder != null);
... ... @@ -132,30 +135,30 @@ Future<T> showCupertinoModalBottomSheet<T>({
class CupertinoModalBottomSheetRoute<T> extends ModalBottomSheetRoute<T> {
final Radius topRadius;
final Curve previousRouteAnimationCurve;
final Curve? previousRouteAnimationCurve;
// Background color behind all routes
// Black by default
final Color transitionBackgroundColor;
final Color? transitionBackgroundColor;
CupertinoModalBottomSheetRoute({
WidgetBuilder builder,
WidgetWithChildBuilder containerBuilder,
double closeProgressThreshold,
String barrierLabel,
double elevation,
ShapeBorder shape,
Clip clipBehavior,
AnimationController secondAnimationController,
Curve animationCurve,
Color modalBarrierColor,
required WidgetBuilder builder,
WidgetWithChildBuilder? containerBuilder,
double? closeProgressThreshold,
String? barrierLabel,
double? elevation,
ShapeBorder? shape,
Clip? clipBehavior,
AnimationController? secondAnimationController,
Curve? animationCurve,
Color? modalBarrierColor,
bool bounce = true,
bool isDismissible = true,
bool enableDrag = true,
@required bool expanded,
Duration duration,
RouteSettings settings,
ScrollController scrollController,
required bool expanded,
Duration? duration,
RouteSettings? settings,
ScrollController? scrollController,
this.transitionBackgroundColor,
this.topRadius = _default_top_radius,
this.previousRouteAnimationCurve,
... ... @@ -221,16 +224,16 @@ class CupertinoModalBottomSheetRoute<T> extends ModalBottomSheetRoute<T> {
class _CupertinoModalTransition extends StatelessWidget {
final Animation<double> secondaryAnimation;
final Radius topRadius;
final Curve animationCurve;
final Curve? animationCurve;
final Color backgroundColor;
final Widget body;
const _CupertinoModalTransition({
Key key,
@required this.secondaryAnimation,
@required this.body,
@required this.topRadius,
Key? key,
required this.secondaryAnimation,
required this.body,
required this.topRadius,
this.backgroundColor = Colors.black,
this.animationCurve,
}) : super(key: key);
... ... @@ -283,16 +286,19 @@ class _CupertinoModalTransition extends StatelessWidget {
}
class _CupertinoScaffold extends InheritedWidget {
final AnimationController animation;
final AnimationController? animation;
final Radius topRadius;
final Radius? topRadius;
@override
final Widget child;
const _CupertinoScaffold(
{Key key, this.animation, this.child, this.topRadius})
: super(key: key, child: child);
const _CupertinoScaffold({
Key? key,
this.animation,
required this.child,
this.topRadius,
}) : super(key: key, child: child);
@override
bool updateShouldNotify(InheritedWidget oldWidget) {
... ... @@ -302,7 +308,7 @@ class _CupertinoScaffold extends InheritedWidget {
// Support
class CupertinoScaffold extends StatefulWidget {
static _CupertinoScaffold of(BuildContext context) =>
static _CupertinoScaffold? of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<_CupertinoScaffold>();
final Widget body;
... ... @@ -310,8 +316,8 @@ class CupertinoScaffold extends StatefulWidget {
final Color transitionBackgroundColor;
const CupertinoScaffold({
Key key,
this.body,
Key? key,
required this.body,
this.topRadius = _default_top_radius,
this.transitionBackgroundColor = Colors.black,
}) : super(key: key);
... ... @@ -319,21 +325,21 @@ class CupertinoScaffold extends StatefulWidget {
@override
State<StatefulWidget> createState() => _CupertinoScaffoldState();
static Future<T> showCupertinoModalBottomSheet<T>({
@required BuildContext context,
double closeProgressThreshold,
@required WidgetBuilder builder,
Curve animationCurve,
Curve previousRouteAnimationCurve,
Color backgroundColor,
Color barrierColor,
static Future<T?> showCupertinoModalBottomSheet<T>({
required BuildContext context,
double? closeProgressThreshold,
required WidgetBuilder builder,
Curve? animationCurve,
Curve? previousRouteAnimationCurve,
Color? backgroundColor,
Color? barrierColor,
bool expand = false,
bool useRootNavigator = false,
bool bounce = true,
bool isDismissible,
bool? isDismissible,
bool enableDrag = true,
Duration duration,
RouteSettings settings,
Duration? duration,
RouteSettings? settings,
}) async {
assert(context != null);
assert(builder != null);
... ... @@ -348,16 +354,16 @@ class CupertinoScaffold extends StatefulWidget {
assert(debugCheckHasMaterialLocalizations(context));
barrierLabel = MaterialLocalizations.of(context).modalBarrierDismissLabel;
}
final topRadius = CupertinoScaffold.of(context).topRadius;
final topRadius = CupertinoScaffold.of(context)!.topRadius;
final result = await Navigator.of(context, rootNavigator: useRootNavigator)
.push(CupertinoModalBottomSheetRoute<T>(
closeProgressThreshold: closeProgressThreshold,
builder: builder,
secondAnimationController: CupertinoScaffold.of(context).animation,
secondAnimationController: CupertinoScaffold.of(context)!.animation,
containerBuilder: (context, _, child) => _CupertinoBottomSheetContainer(
child: child,
backgroundColor: backgroundColor,
topRadius: topRadius,
topRadius: _default_top_radius,
),
expanded: expand,
barrierLabel: barrierLabel,
... ... @@ -365,7 +371,7 @@ class CupertinoScaffold extends StatefulWidget {
isDismissible: isDismissible ?? expand == false ? true : false,
modalBarrierColor: barrierColor ?? Colors.black12,
enableDrag: enableDrag,
topRadius: topRadius,
topRadius: topRadius ?? _default_top_radius,
animationCurve: animationCurve,
previousRouteAnimationCurve: previousRouteAnimationCurve,
duration: duration,
... ... @@ -377,9 +383,9 @@ class CupertinoScaffold extends StatefulWidget {
class _CupertinoScaffoldState extends State<CupertinoScaffold>
with TickerProviderStateMixin {
AnimationController animationController;
late AnimationController animationController;
SystemUiOverlayStyle lastStyle;
SystemUiOverlayStyle? lastStyle;
@override
void initState() {
... ...
... ... @@ -3,23 +3,23 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'dart:async';
/// Shows a modal material design bottom sheet.
Future<T> showMaterialModalBottomSheet<T>({
@required BuildContext context,
double closeProgressThreshold,
@required WidgetBuilder builder,
Color backgroundColor,
double elevation,
ShapeBorder shape,
Clip clipBehavior,
Color barrierColor,
Future<T?> showMaterialModalBottomSheet<T>({
required BuildContext context,
double? closeProgressThreshold,
required WidgetBuilder builder,
Color? backgroundColor,
double? elevation,
ShapeBorder? shape,
Clip? clipBehavior,
Color? barrierColor,
bool bounce = false,
bool expand = false,
AnimationController secondAnimation,
Curve animationCurve,
AnimationController? secondAnimation,
Curve? animationCurve,
bool useRootNavigator = false,
bool isDismissible = true,
bool enableDrag = true,
Duration duration,
Duration? duration,
}) async {
assert(context != null);
assert(builder != null);
... ... @@ -56,15 +56,15 @@ Future<T> showMaterialModalBottomSheet<T>({
//Default container builder is the Material Appearance
WidgetWithChildBuilder _materialContainerBuilder(BuildContext context,
{Color backgroundColor,
double elevation,
ThemeData theme,
Clip clipBehavior,
ShapeBorder shape}) {
{Color? backgroundColor,
double? elevation,
ThemeData? theme,
Clip? clipBehavior,
ShapeBorder? shape}) {
final bottomSheetTheme = Theme.of(context).bottomSheetTheme;
final color = backgroundColor ??
bottomSheetTheme?.modalBackgroundColor ??
bottomSheetTheme?.backgroundColor;
bottomSheetTheme.modalBackgroundColor ??
bottomSheetTheme.backgroundColor;
final _elevation = elevation ?? bottomSheetTheme.elevation ?? 0.0;
final _shape = shape ?? bottomSheetTheme.shape;
final _clipBehavior =
... ...
... ... @@ -11,8 +11,8 @@ class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
/// The values of [builder], [maintainState], and [fullScreenDialog] must not
/// be null.
MaterialWithModalsPageRoute({
@required WidgetBuilder builder,
RouteSettings settings,
required WidgetBuilder builder,
RouteSettings? settings,
bool maintainState = true,
bool fullscreenDialog = false,
}) : assert(builder != null),
... ... @@ -24,7 +24,7 @@ class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
builder: builder,
maintainState: maintainState);
ModalBottomSheetRoute _nextModalRoute;
ModalBottomSheetRoute? _nextModalRoute;
@override
bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
... ... @@ -37,7 +37,7 @@ class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
}
@override
void didChangeNext(Route nextRoute) {
void didChangeNext(Route? nextRoute) {
if (nextRoute is ModalBottomSheetRoute) {
_nextModalRoute = nextRoute;
}
... ... @@ -51,7 +51,7 @@ class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
}
@override
bool didPop(T result) {
bool didPop(T? result) {
_nextModalRoute = null;
return super.didPop(result);
}
... ... @@ -60,7 +60,8 @@ class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
Widget buildTransitions(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
final theme = Theme.of(context).pageTransitionsTheme;
if (_nextModalRoute != null) {
final nextRoute = _nextModalRoute;
if (nextRoute != null) {
if (!secondaryAnimation.isDismissed) {
// Avoid default transition theme to animate when a new modal view is pushed
final fakeSecondaryAnimation =
... ... @@ -68,7 +69,7 @@ class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
final defaultTransition = theme.buildTransitions<T>(
this, context, animation, fakeSecondaryAnimation, child);
return _nextModalRoute.getPreviousRouteTransition(
return nextRoute.getPreviousRouteTransition(
context, secondaryAnimation, defaultTransition);
} else {
_nextModalRoute = null;
... ...
... ... @@ -25,7 +25,7 @@ import 'package:flutter/foundation.dart';
/// animation at the time when the finger was released.
///
/// The [startingPoint] and [curve] arguments must not be null.
class BottomSheetSuspendedCurve extends ParametricCurve<double> {
class BottomSheetSuspendedCurve extends Curve {
/// Creates a suspended curve.
const BottomSheetSuspendedCurve(
this.startingPoint, {
... ... @@ -56,7 +56,7 @@ class BottomSheetSuspendedCurve extends ParametricCurve<double> {
final curveProgress = (t - startingPoint) / (1 - startingPoint);
final transformed = curve.transform(curveProgress);
return lerpDouble(startingPoint, 1, transformed);
return lerpDouble(startingPoint, 1, transformed)!;
}
@override
... ...
... ... @@ -13,9 +13,9 @@ import 'package:flutter/widgets.dart';
class ModalScrollController extends InheritedWidget {
/// Creates a widget that associates a [ScrollController] with a subtree.
ModalScrollController({
Key key,
@required this.controller,
@required Widget child,
Key? key,
required this.controller,
required Widget child,
}) : assert(controller != null),
super(
key: key,
... ... @@ -38,7 +38,7 @@ class ModalScrollController extends InheritedWidget {
///
/// Returns null if there is no [ScrollController] associated with the given
/// context.
static ScrollController of(BuildContext context) {
static ScrollController? of(BuildContext context) {
final result =
context.dependOnInheritedWidgetOfExactType<ModalScrollController>();
return result?.controller;
... ...
... ... @@ -9,9 +9,9 @@ class ScrollToTopStatusBarHandler extends StatefulWidget {
final ScrollController scrollController;
const ScrollToTopStatusBarHandler({
Key key,
@required this.child,
@required this.scrollController,
Key? key,
required this.child,
required this.scrollController,
}) : super(key: key);
@override
... ...
... ... @@ -7,49 +7,49 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0-nullsafety.2"
version: "2.5.0-nullsafety.3"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.2"
version: "2.1.0-nullsafety.3"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.4"
version: "1.1.0-nullsafety.5"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.2"
version: "1.2.0-nullsafety.3"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.2"
version: "1.1.0-nullsafety.3"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0-nullsafety.4"
version: "1.15.0-nullsafety.5"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.2"
version: "1.2.0-nullsafety.3"
flutter:
dependency: "direct main"
description: flutter
... ... @@ -66,21 +66,21 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10-nullsafety.2"
version: "0.12.10-nullsafety.3"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.5"
version: "1.3.0-nullsafety.6"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.2"
version: "1.8.0-nullsafety.3"
pedantic:
dependency: "direct dev"
description:
... ... @@ -99,56 +99,56 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0-nullsafety.3"
version: "1.8.0-nullsafety.4"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0-nullsafety.5"
version: "1.10.0-nullsafety.6"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.2"
version: "2.1.0-nullsafety.3"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0-nullsafety.2"
version: "1.1.0-nullsafety.3"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0-nullsafety.2"
version: "1.2.0-nullsafety.3"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19-nullsafety.4"
version: "0.2.19-nullsafety.6"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0-nullsafety.4"
version: "1.3.0-nullsafety.5"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0-nullsafety.4"
version: "2.1.0-nullsafety.5"
sdks:
dart: ">=2.11.0-0.0 <2.12.0"
dart: ">=2.12.0-29.10.beta <3.0.0"
flutter: ">=1.12.0 <2.0.0"
... ...
name: modal_bottom_sheet
description: 'Create awesome and powerful modal bottom sheets. Material, Cupertino iOS 13 or create your own style'
version: 1.0.0
version: 1.0.0+1
homepage: 'https://github.com/jamesblasco/modal_bottom_sheet'
environment:
sdk: ">=2.0.0 <3.0.0"
sdk: ">=2.12.0-29.10.beta <3.0.0"
flutter: ">=1.12.0 <2.0.0"
dependencies:
... ...