Jaime Blasco
Committed by GitHub

feat: add foldable example (#269)

1 # This file tracks properties of this Flutter project. 1 # This file tracks properties of this Flutter project.
2 # Used by Flutter tool to assess capabilities and perform upgrades etc. 2 # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 # 3 #
4 -# This file should be version controlled and should not be manually edited. 4 +# This file should be version controlled.
5 5
6 version: 6 version:
7 - revision: 8cb266511897d79e6d7d60c08c0e425f4cdaf433  
8 - channel: master 7 + revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  8 + channel: stable
9 9
10 project_type: app 10 project_type: app
  11 +
  12 +# Tracks metadata for the flutter migrate command
  13 +migration:
  14 + platforms:
  15 + - platform: root
  16 + create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  17 + base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  18 + - platform: android
  19 + create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  20 + base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  21 + - platform: ios
  22 + create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  23 + base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  24 + - platform: linux
  25 + create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  26 + base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  27 + - platform: macos
  28 + create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  29 + base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  30 + - platform: web
  31 + create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  32 + base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  33 + - platform: windows
  34 + create_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  35 + base_revision: 4f9d92fbbdf072a70a70d2179a9f87392b94104c
  36 +
  37 + # User provided section
  38 +
  39 + # List of Local paths (relative to this file) that should be
  40 + # ignored by the migrate tool.
  41 + #
  42 + # Files that are not part of the templates will be ignored by default.
  43 + unmanaged_files:
  44 + - 'lib/main.dart'
  45 + - 'ios/Runner.xcodeproj/project.pbxproj'
@@ -9,3 +9,5 @@ GeneratedPluginRegistrant.java @@ -9,3 +9,5 @@ GeneratedPluginRegistrant.java
9 # Remember to never publicly share your keystore. 9 # Remember to never publicly share your keystore.
10 # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 10 # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 key.properties 11 key.properties
  12 +**/*.keystore
  13 +**/*.jks
@@ -26,21 +26,29 @@ apply plugin: 'kotlin-android' @@ -26,21 +26,29 @@ apply plugin: 'kotlin-android'
26 apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 27
28 android { 28 android {
29 - compileSdkVersion 29 29 + compileSdkVersion flutter.compileSdkVersion
  30 + ndkVersion flutter.ndkVersion
30 31
31 - sourceSets {  
32 - main.java.srcDirs += 'src/main/kotlin' 32 + compileOptions {
  33 + sourceCompatibility JavaVersion.VERSION_1_8
  34 + targetCompatibility JavaVersion.VERSION_1_8
  35 + }
  36 +
  37 + kotlinOptions {
  38 + jvmTarget = '1.8'
33 } 39 }
34 40
35 - lintOptions {  
36 - disable 'InvalidPackage' 41 + sourceSets {
  42 + main.java.srcDirs += 'src/main/kotlin'
37 } 43 }
38 44
39 defaultConfig { 45 defaultConfig {
40 // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 46 // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 - applicationId "com.example.example"  
42 - minSdkVersion 16  
43 - targetSdkVersion 29 47 + applicationId "jb.example.example"
  48 + // You can update the following values to match your application needs.
  49 + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
  50 + minSdkVersion flutter.minSdkVersion
  51 + targetSdkVersion flutter.targetSdkVersion
44 versionCode flutterVersionCode.toInteger() 52 versionCode flutterVersionCode.toInteger()
45 versionName flutterVersionName 53 versionName flutterVersionName
46 } 54 }
1 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 - package="com.example.example">  
3 - <!-- Flutter needs it to communicate with the running application 2 + package="jb.example.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
4 to allow setting breakpoints, to provide hot reload, etc. 5 to allow setting breakpoints, to provide hot reload, etc.
5 --> 6 -->
6 <uses-permission android:name="android.permission.INTERNET"/> 7 <uses-permission android:name="android.permission.INTERNET"/>
1 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 - package="com.example.example"> 2 + package="jb.example.example">
3 <application 3 <application
4 android:label="example" 4 android:label="example"
  5 + android:name="${applicationName}"
5 android:icon="@mipmap/ic_launcher"> 6 android:icon="@mipmap/ic_launcher">
6 <activity 7 <activity
7 android:name=".MainActivity" 8 android:name=".MainActivity"
  9 + android:exported="true"
8 android:launchMode="singleTop" 10 android:launchMode="singleTop"
9 android:theme="@style/LaunchTheme" 11 android:theme="@style/LaunchTheme"
10 android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" 12 android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
@@ -18,15 +20,6 @@ @@ -18,15 +20,6 @@
18 android:name="io.flutter.embedding.android.NormalTheme" 20 android:name="io.flutter.embedding.android.NormalTheme"
19 android:resource="@style/NormalTheme" 21 android:resource="@style/NormalTheme"
20 /> 22 />
21 - <!-- Displays an Android View that continues showing the launch screen  
22 - Drawable until Flutter paints its first frame, then this splash  
23 - screen fades out. A splash screen is useful to avoid any visual  
24 - gap between the end of Android's launch screen and the painting of  
25 - Flutter's first frame. -->  
26 - <meta-data  
27 - android:name="io.flutter.embedding.android.SplashScreenDrawable"  
28 - android:resource="@drawable/launch_background"  
29 - />  
30 <intent-filter> 23 <intent-filter>
31 <action android:name="android.intent.action.MAIN"/> 24 <action android:name="android.intent.action.MAIN"/>
32 <category android:name="android.intent.category.LAUNCHER"/> 25 <category android:name="android.intent.category.LAUNCHER"/>
1 -package com.example.example 1 +package jb.example.example
2 2
3 import io.flutter.embedding.android.FlutterActivity 3 import io.flutter.embedding.android.FlutterActivity
4 4
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on --> 3 <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
4 <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> 4 <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
5 <!-- Show a splash screen on the activity. Automatically removed when 5 <!-- Show a splash screen on the activity. Automatically removed when
6 - Flutter draws its first frame --> 6 + the Flutter engine draws its first frame -->
7 <item name="android:windowBackground">@drawable/launch_background</item> 7 <item name="android:windowBackground">@drawable/launch_background</item>
8 </style> 8 </style>
9 <!-- Theme applied to the Android Window as soon as the process has started. 9 <!-- Theme applied to the Android Window as soon as the process has started.
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off --> 3 <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
4 <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar"> 4 <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
5 <!-- Show a splash screen on the activity. Automatically removed when 5 <!-- Show a splash screen on the activity. Automatically removed when
6 - Flutter draws its first frame --> 6 + the Flutter engine draws its first frame -->
7 <item name="android:windowBackground">@drawable/launch_background</item> 7 <item name="android:windowBackground">@drawable/launch_background</item>
8 </style> 8 </style>
9 <!-- Theme applied to the Android Window as soon as the process has started. 9 <!-- Theme applied to the Android Window as soon as the process has started.
1 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 1 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2 - package="com.example.example">  
3 - <!-- Flutter needs it to communicate with the running application 2 + package="jb.example.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
4 to allow setting breakpoints, to provide hot reload, etc. 5 to allow setting breakpoints, to provide hot reload, etc.
5 --> 6 -->
6 <uses-permission android:name="android.permission.INTERNET"/> 7 <uses-permission android:name="android.permission.INTERNET"/>
1 buildscript { 1 buildscript {
2 - ext.kotlin_version = '1.3.50' 2 + ext.kotlin_version = '1.6.10'
3 repositories { 3 repositories {
4 google() 4 google()
5 - jcenter() 5 + mavenCentral()
6 } 6 }
7 7
8 dependencies { 8 dependencies {
9 - classpath 'com.android.tools.build:gradle:3.5.0' 9 + classpath 'com.android.tools.build:gradle:7.1.2'
10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 } 11 }
12 } 12 }
@@ -14,7 +14,7 @@ buildscript { @@ -14,7 +14,7 @@ buildscript {
14 allprojects { 14 allprojects {
15 repositories { 15 repositories {
16 google() 16 google()
17 - jcenter() 17 + mavenCentral()
18 } 18 }
19 } 19 }
20 20
1 -#Fri Jun 23 08:50:38 CEST 2017  
2 distributionBase=GRADLE_USER_HOME 1 distributionBase=GRADLE_USER_HOME
3 distributionPath=wrapper/dists 2 distributionPath=wrapper/dists
4 zipStoreBase=GRADLE_USER_HOME 3 zipStoreBase=GRADLE_USER_HOME
5 zipStorePath=wrapper/dists 4 zipStorePath=wrapper/dists
6 -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 5 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
@@ -10,7 +10,11 @@ class FloatingModal extends StatelessWidget { @@ -10,7 +10,11 @@ class FloatingModal extends StatelessWidget {
10 10
11 @override 11 @override
12 Widget build(BuildContext context) { 12 Widget build(BuildContext context) {
13 - return SafeArea( 13 + // DisplayFeatureSubScreen allows to display the modal in just
  14 + // one sub-screen of a foldable device.
  15 + return DisplayFeatureSubScreen(
  16 + anchorPoint: Offset.infinite,
  17 + child: SafeArea(
14 minimum: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), 18 minimum: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
15 child: Material( 19 child: Material(
16 color: backgroundColor, 20 color: backgroundColor,
@@ -18,6 +22,7 @@ class FloatingModal extends StatelessWidget { @@ -18,6 +22,7 @@ class FloatingModal extends StatelessWidget {
18 borderRadius: BorderRadius.circular(12), 22 borderRadius: BorderRadius.circular(12),
19 child: child, 23 child: child,
20 ), 24 ),
  25 + ),
21 ); 26 );
22 } 27 }
23 } 28 }
  1 +import 'package:flutter/material.dart';
  2 +import 'package:sheet/sheet.dart';
  3 +
  4 +class FoldableScreenFloatingSheet extends StatefulWidget {
  5 + @override
  6 + _FitSheetState createState() => _FitSheetState();
  7 +}
  8 +
  9 +class _FitSheetState extends State<FoldableScreenFloatingSheet> {
  10 + final SheetController controller = SheetController();
  11 +
  12 + @override
  13 + void initState() {
  14 + Future<void>.delayed(const Duration(milliseconds: 400), animateSheet);
  15 +
  16 + super.initState();
  17 + }
  18 +
  19 + void animateSheet() {
  20 + controller.relativeAnimateTo(1,
  21 + duration: const Duration(milliseconds: 400), curve: Curves.easeOut);
  22 + }
  23 +
  24 + @override
  25 + void dispose() {
  26 + controller.dispose();
  27 + super.dispose();
  28 + }
  29 +
  30 + @override
  31 + Widget build(BuildContext context) {
  32 + return DisplayFeatureSubScreen(
  33 + anchorPoint: Offset.infinite,
  34 + child: Sheet.raw(
  35 + physics: const SnapSheetPhysics(
  36 + parent: BouncingSheetPhysics(overflowViewport: false),
  37 + stops: <double>[0, 1],
  38 + ),
  39 + padding: const EdgeInsets.all(20),
  40 + child: Container(
  41 + height: 200,
  42 + alignment: Alignment.topCenter,
  43 + child: Container(
  44 + height: 200,
  45 + width: double.infinity,
  46 + child: Material(
  47 + elevation: 1,
  48 + shape: RoundedRectangleBorder(
  49 + borderRadius: BorderRadius.circular(12),
  50 + ),
  51 + color: Colors.grey[900],
  52 + ),
  53 + ),
  54 + ),
  55 + controller: controller,
  56 + ),
  57 + );
  58 + }
  59 +}
@@ -270,6 +270,14 @@ class RouteExamplePage extends StatelessWidget { @@ -270,6 +270,14 @@ class RouteExamplePage extends StatelessWidget {
270 ), 270 ),
271 ), 271 ),
272 ListTile( 272 ListTile(
  273 + title: const Text('Foldable Screen - Fit'),
  274 + onTap: () => Navigator.of(context).push(
  275 + FloatingSheetRoute<void>(
  276 + builder: (BuildContext context) => const ModalFit(),
  277 + ),
  278 + ),
  279 + ),
  280 + ListTile(
273 title: const Text('Dialog Modal for tablet - Expanded'), 281 title: const Text('Dialog Modal for tablet - Expanded'),
274 onTap: () => Navigator.of(context).push( 282 onTap: () => Navigator.of(context).push(
275 DialogSheetRoute<void>( 283 DialogSheetRoute<void>(
@@ -12,6 +12,7 @@ import 'examples/sheet/fit_resizable_sheet.dart'; @@ -12,6 +12,7 @@ import 'examples/sheet/fit_resizable_sheet.dart';
12 import 'examples/sheet/fit_sheet.dart'; 12 import 'examples/sheet/fit_sheet.dart';
13 import 'examples/sheet/fit_sheet_snap.dart'; 13 import 'examples/sheet/fit_sheet_snap.dart';
14 import 'examples/sheet/floating_sheet.dart'; 14 import 'examples/sheet/floating_sheet.dart';
  15 +import 'examples/sheet/fold_screen_sheet.dart';
15 import 'examples/sheet/resizable_sheet.dart'; 16 import 'examples/sheet/resizable_sheet.dart';
16 import 'examples/sheet/scrollable_sheet.dart'; 17 import 'examples/sheet/scrollable_sheet.dart';
17 import 'examples/sheet/scrollable_snap_sheet.dart'; 18 import 'examples/sheet/scrollable_snap_sheet.dart';
@@ -55,6 +56,7 @@ class SheetExamplesPage extends StatelessWidget { @@ -55,6 +56,7 @@ class SheetExamplesPage extends StatelessWidget {
55 ExampleTile.sheet( 56 ExampleTile.sheet(
56 'Fit, Resizable and Bouncing sheet', FitResizableSheet()), 57 'Fit, Resizable and Bouncing sheet', FitResizableSheet()),
57 ExampleTile.sheet('Textfield sheet', TextFieldSheet()), 58 ExampleTile.sheet('Textfield sheet', TextFieldSheet()),
  59 + ExampleTile.sheet('Foldable screen', FoldableScreenFloatingSheet()),
58 const ExampleTile( 60 const ExampleTile(
59 title: 'Customizable sheet', page: SheetConfigurationPage()), 61 title: 'Customizable sheet', page: SheetConfigurationPage()),
60 const SectionTitle('SHOWCASE'), 62 const SectionTitle('SHOWCASE'),