Repository: Eajy/flutter_demo Branch: master Commit: 3f421bc42261 Files: 51 Total size: 116.9 KB Directory structure: gitextract_cc8j8zb2/ ├── .gitignore ├── .metadata ├── README.md ├── android/ │ ├── .gitignore │ ├── app/ │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── eajy/ │ │ │ └── flutterdemo/ │ │ │ └── MainActivity.java │ │ └── res/ │ │ ├── drawable/ │ │ │ └── launch_background.xml │ │ └── values/ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle/ │ │ └── wrapper/ │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradle.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── flutter_demo.iml ├── flutter_demo_android.iml ├── ios/ │ ├── .gitignore │ ├── Flutter/ │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner/ │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets/ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ └── LaunchImage.imageset/ │ │ │ ├── Contents.json │ │ │ └── README.md │ │ ├── Base.lproj/ │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── main.m │ ├── Runner.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── Runner.xcscheme │ └── Runner.xcworkspace/ │ └── contents.xcworkspacedata ├── lib/ │ ├── main.dart │ ├── route/ │ │ ├── about.dart │ │ ├── bottomNavigation.dart │ │ ├── fullscreen.dart │ │ ├── home.dart │ │ ├── homeCards.dart │ │ ├── homeDialogs.dart │ │ ├── homeWidgets.dart │ │ ├── list.dart │ │ ├── settings.dart │ │ └── sliverAppbar.dart │ └── widget/ │ ├── drawerWidget.dart │ └── tabWidget.dart ├── pubspec.yaml └── test/ └── widget_test.dart ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store .atom/ .dart_tool/ .idea .vscode/ .packages .pub/ build/ ios/.generated/ packages .flutter-plugins ================================================ FILE: .metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: b397406561f5e7a9c94e28f58d9e49fca0dd58b7 channel: beta ================================================ FILE: README.md ================================================ **This is a demo app designed with Material Design. It's created by using [Flutter](https://flutter.io/).** #### Google Play: https://play.google.com/store/apps/details?id=com.eajy.flutterdemo ![image](https://github.com/Eajy/flutter_demo/blob/master/android/pictures/1.png) ![image](https://github.com/Eajy/flutter_demo/blob/master/android/pictures/2.png) ![image](https://github.com/Eajy/flutter_demo/blob/master/android/pictures/3.png) --- #### Open Source Licenses: Copyright 2018 Eajy Licensed under the Apache License, Version 2.0. you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. [_**- Designed by Eajy in China.**_](https://sites.google.com/view/eajy) ================================================ FILE: android/.gitignore ================================================ *.iml *.class .gradle /local.properties /key.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures GeneratedPluginRegistrant.java ================================================ FILE: android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" def keystorePropertiesFile = rootProject.file("key.properties") def keystoreProperties = new Properties() keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) android { compileSdkVersion 28 lintOptions { disable 'InvalidPackage' } defaultConfig { applicationId "com.eajy.flutterdemo" minSdkVersion 21 targetSdkVersion 28 versionCode 3 versionName "1.2" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } signingConfigs { release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } buildTypes { release { signingConfig signingConfigs.release } } } flutter { source '../..' } dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } ================================================ FILE: android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: android/app/src/main/java/com/eajy/flutterdemo/MainActivity.java ================================================ package com.eajy.flutterdemo; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.widget.Toast; import io.flutter.app.FlutterActivity; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { private static final String CHANNEL = "com.eajy.flutterdemo/android"; private static final String SHARE_CONTENT = "A beautiful app designed with Material Design by using Flutter. \nhttps://play.google.com/store/apps/details?id=com.eajy.flutterdemo \n- Designed by Eajy in China"; private static final String EMAIL_ADDRESS = "mailto:eajy.zhangxiao@gmail.com"; private static final String EMAIL_SUBJECT = "Feedback:FlutterDemo"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { switch (call.method) { case "share": share(); result.success(null); break; case "getVersionName": result.success(getVersionName()); break; case "sendEmail": sendEmail(); result.success(null); break; default: result.notImplemented(); break; } } }); } private void share() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, SHARE_CONTENT); intent.setType("text/plain"); startActivity(Intent.createChooser(intent, "Share with")); } private String getVersionName() { try { PackageManager manager = getPackageManager(); PackageInfo info = manager.getPackageInfo(getPackageName(), 0); String version = info.versionName; return "Version: " + version; } catch (Exception e) { e.printStackTrace(); return "Version: 1.0"; } } private void sendEmail() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_SENDTO); intent.setData(Uri.parse(EMAIL_ADDRESS)); intent.putExtra(Intent.EXTRA_SUBJECT, EMAIL_SUBJECT); try { startActivity(intent); } catch (Exception e) { Toast.makeText(this, "Not found Email app.", Toast.LENGTH_SHORT).show(); } } } ================================================ FILE: android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: android/build.gradle ================================================ buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.2.1' } } allprojects { repositories { google() jcenter() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip ================================================ FILE: android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M ================================================ FILE: android/gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: android/gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: android/settings.gradle ================================================ include ':app' def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } ================================================ FILE: flutter_demo.iml ================================================ ================================================ FILE: flutter_demo_android.iml ================================================ ================================================ FILE: ios/.gitignore ================================================ .idea/ .vagrant/ .sconsign.dblite .svn/ .DS_Store *.swp profile DerivedData/ build/ GeneratedPluginRegistrant.h GeneratedPluginRegistrant.m *.pbxuser *.mode1v3 *.mode2v3 *.perspectivev3 !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 xcuserdata *.moved-aside *.pyc *sync/ Icon? .tags* /Flutter/app.flx /Flutter/app.zip /Flutter/flutter_assets/ /Flutter/App.framework /Flutter/Flutter.framework /Flutter/Generated.xcconfig /ServiceDefinitions.json Pods/ ================================================ FILE: ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 UIRequiredDeviceCapabilities arm64 MinimumOSVersion 8.0 ================================================ FILE: ios/Flutter/Debug.xcconfig ================================================ #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" ================================================ FILE: ios/Flutter/Release.xcconfig ================================================ #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" ================================================ FILE: ios/Podfile ================================================ # Uncomment this line to define a global platform for your project # platform :ios, '9.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' def parse_KV_file(file, separator='=') file_abs_path = File.expand_path(file) if !File.exists? file_abs_path return []; end pods_ary = [] skip_line_start_symbols = ["#", "/"] File.foreach(file_abs_path) { |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) pods_ary.push({:name => podname, :path => podpath}); else puts "Invalid plugin specification: #{line}" end } return pods_ary end target 'Runner' do # 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') # Flutter Pods generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') if generated_xcode_build_settings.empty? puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." end generated_xcode_build_settings.map { |p| if p[:name] == 'FLUTTER_FRAMEWORK_DIR' symlink = File.join('.symlinks', 'flutter') File.symlink(File.dirname(p[:path]), symlink) pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) end } # Plugin Pods plugin_pods = parse_KV_file('../.flutter-plugins') plugin_pods.map { |p| symlink = File.join('.symlinks', 'plugins', p[:name]) File.symlink(p[:path], symlink) pod p[:name], :path => File.join(symlink, 'ios') } end post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['ENABLE_BITCODE'] = 'NO' end end end ================================================ FILE: ios/Runner/AppDelegate.h ================================================ #import #import @interface AppDelegate : FlutterAppDelegate @end ================================================ FILE: ios/Runner/AppDelegate.m ================================================ #include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; // Override point for customization after application launch. return [super application:application didFinishLaunchingWithOptions:launchOptions]; } @end ================================================ FILE: ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@3x.png", "scale" : "3x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@3x.png", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@3x.png", "scale" : "3x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@1x.png", "scale" : "1x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@1x.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@1x.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@2x.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "Icon-App-83.5x83.5@2x.png", "scale" : "2x" }, { "size" : "1024x1024", "idiom" : "ios-marketing", "filename" : "Icon-App-1024x1024@1x.png", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # Launch Screen Assets You can customize the launch screen with your own desired assets by replacing the image files in this directory. You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. ================================================ FILE: ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName flutter_demo CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities arm64 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance ================================================ FILE: ios/Runner/main.m ================================================ #import #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; CB9D968E6FA25F9D39C29ABE /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DED9A1A75D33C5B076818C6E /* libPods-Runner.a */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; DED9A1A75D33C5B076818C6E /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, CB9D968E6FA25F9D39C29ABE /* libPods-Runner.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, ); name = Flutter; sourceTree = ""; }; 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, F0A69501B739B7210807AE75 /* Pods */, B349611CADCD4B927A041236 /* Frameworks */, ); sourceTree = ""; }; 97C146EF1CF9000F007C117D /* Products */ = { isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, ); name = Products; sourceTree = ""; }; 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, ); path = Runner; sourceTree = ""; }; 97C146F11CF9000F007C117D /* Supporting Files */ = { isa = PBXGroup; children = ( 97C146F21CF9000F007C117D /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; B349611CADCD4B927A041236 /* Frameworks */ = { isa = PBXGroup; children = ( DED9A1A75D33C5B076818C6E /* libPods-Runner.a */, ); name = Frameworks; sourceTree = ""; }; F0A69501B739B7210807AE75 /* Pods */ = { isa = PBXGroup; children = ( ); name = Pods; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( B3092390BC17D6B606432780 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, F14DAD73828DC392FCA11E30 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( ); name = Runner; productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0910; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; }; }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 97C146E51CF9000F007C117D; productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Run Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; B3092390BC17D6B606432780 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; 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; }; F14DAD73828DC392FCA11E30 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 97C146F31CF9000F007C117D /* main.m in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 97C146FB1CF9000F007C117D /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 97C147001CF9000F007C117D /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; 97C147061CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = 1; 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.eajy.flutterDemo; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; 97C147071CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ARCHS = arm64; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = 1; 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.eajy.flutterDemo; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147031CF9000F007C117D /* Debug */, 97C147041CF9000F007C117D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147061CF9000F007C117D /* Debug */, 97C147071CF9000F007C117D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } ================================================ FILE: ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: lib/main.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_demo/route/home.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, accentColor: Colors.amber, ), home: new HomePage(title: 'Flutter Demo Home Page'), ); } } ================================================ FILE: lib/route/about.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'dart:async'; import 'package:url_launcher/url_launcher.dart'; class About extends StatefulWidget { @override State createState() { return new AboutState(); } } class AboutState extends State { static const platform = const MethodChannel('com.eajy.flutterdemo/android'); static const app_url = 'https://play.google.com/store/apps/details?id=com.eajy.flutterdemo'; static const github_url = 'https://github.com/Eajy/flutter_demo'; static const me_url = 'https://sites.google.com/view/eajy'; String _version = 'Version:'; Future _getVersionName() async { try { _version = await platform.invokeMethod('getVersionName'); } on PlatformException catch (e) { print(e); _version = 'Version: 1.0'; } setState(() {}); } Future _share() async { try { platform.invokeMethod('share'); } on PlatformException catch (e) { print(e); } } Future _sendEmail() async { try { platform.invokeMethod('sendEmail'); } on PlatformException catch (e) { print(e); } } @override void initState() { _getVersionName(); super.initState(); } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('About'), ), body: new ListView( children: [ new ListTile( leading: new FlutterLogo(), title: new Text('This app is developed by using Flutter.'), subtitle: new Text(_version), ), new Divider(), new ListTile( leading: new Icon(Icons.shop), title: new Text('Rate on Google Play'), onTap: () { launch(app_url); }, ), new ListTile( leading: new Icon(Icons.code), title: new Text('Source code on GitHub'), onTap: () { launch(github_url); }, ), new ListTile( leading: new Icon(Icons.email), title: new Text('Feedback by E-mail'), onTap: () { _sendEmail(); }, ), new ListTile( leading: new Icon(Icons.web), title: new Text('View my website'), onTap: () { launch(me_url); }, ), new Divider(), new ListTile( leading: new Icon( Icons.info, color: Colors.transparent, ), title: new Text( 'Designed by Eajy in China.', style: new TextStyle(color: Colors.black54, fontSize: 14.0), ), ), ], ), floatingActionButton: new FloatingActionButton( onPressed: () { _share(); }, child: new Icon(Icons.share, color: Colors.white), ), ); } } ================================================ FILE: lib/route/bottomNavigation.dart ================================================ import 'package:flutter/material.dart'; class NavigationIconView { NavigationIconView({ Widget icon, String title, Color color, TickerProvider vsync, }) : _icon = icon, _color = color, _title = title, item = new BottomNavigationBarItem( icon: icon, title: new Text(title), backgroundColor: color, ), controller = new AnimationController( duration: kThemeAnimationDuration, vsync: vsync, ) { _animation = new CurvedAnimation( parent: controller, curve: const Interval(0.5, 1.0, curve: Curves.fastOutSlowIn), ); } final Widget _icon; final Color _color; final String _title; final BottomNavigationBarItem item; final AnimationController controller; CurvedAnimation _animation; FadeTransition transition( BottomNavigationBarType type, BuildContext context) { Color iconColor; if (type == BottomNavigationBarType.shifting) { iconColor = _color; } else { final ThemeData themeData = Theme.of(context); iconColor = themeData.brightness == Brightness.light ? themeData.primaryColor : themeData.accentColor; } return new FadeTransition( opacity: _animation, child: new SlideTransition( position: new Tween( begin: const Offset(0.0, 0.02), // Slightly down. end: Offset.zero, ).animate(_animation), child: new IconTheme( data: new IconThemeData( color: iconColor, size: 120.0, ), child: new Semantics( label: 'Placeholder for $_title tab', child: _icon, ), ), ), ); } } class CustomIcon extends StatelessWidget { @override Widget build(BuildContext context) { final IconThemeData iconTheme = IconTheme.of(context); return new Container( margin: const EdgeInsets.all(4.0), width: iconTheme.size - 8.0, height: iconTheme.size - 8.0, color: iconTheme.color, ); } } class BottomNavigationDemo extends StatefulWidget { @override _BottomNavigationDemoState createState() => new _BottomNavigationDemoState(); } class _BottomNavigationDemoState extends State with TickerProviderStateMixin { int _currentIndex = 0; BottomNavigationBarType _type = BottomNavigationBarType.fixed; List _navigationViews; @override void initState() { super.initState(); _navigationViews = [ new NavigationIconView( icon: const Icon(Icons.dashboard), title: 'Dashborad', color: Colors.blue, vsync: this, ), new NavigationIconView( icon: const Icon(Icons.image), title: 'Image', color: Colors.teal, vsync: this, ), new NavigationIconView( icon: const Icon(Icons.music_note), title: 'Music', color: Colors.orange, vsync: this, ), new NavigationIconView( icon: const Icon(Icons.movie), title: 'Movie', color: Colors.red, vsync: this, ) ]; for (NavigationIconView view in _navigationViews) view.controller.addListener(_rebuild); _navigationViews[_currentIndex].controller.value = 1.0; } @override void dispose() { for (NavigationIconView view in _navigationViews) view.controller.dispose(); super.dispose(); } void _rebuild() { setState(() { // Rebuild in order to animate views. }); } Widget _buildTransitionsStack() { final List transitions = []; for (NavigationIconView view in _navigationViews) transitions.add(view.transition(_type, context)); // We want to have the newly animating (fading in) views on top. transitions.sort((FadeTransition a, FadeTransition b) { final Animation aAnimation = a.opacity; final Animation bAnimation = b.opacity; final double aValue = aAnimation.value; final double bValue = bAnimation.value; return aValue.compareTo(bValue); }); return new Stack(children: transitions); } @override Widget build(BuildContext context) { final BottomNavigationBar botNavBar = new BottomNavigationBar( items: _navigationViews .map((NavigationIconView navigationView) => navigationView.item) .toList(), currentIndex: _currentIndex, type: _type, onTap: (int index) { setState(() { _navigationViews[_currentIndex].controller.reverse(); _currentIndex = index; _navigationViews[_currentIndex].controller.forward(); }); }, ); return new Scaffold( appBar: new AppBar( title: const Text('Bottom navigation'), actions: [ new PopupMenuButton( onSelected: (BottomNavigationBarType value) { setState(() { _type = value; }); }, itemBuilder: (BuildContext context) => >[ const PopupMenuItem( value: BottomNavigationBarType.fixed, child: const Text('Fixed'), ), const PopupMenuItem( value: BottomNavigationBarType.shifting, child: const Text('Shifting'), ) ], ) ], ), body: new Center(child: _buildTransitionsStack()), bottomNavigationBar: botNavBar, ); } } ================================================ FILE: lib/route/fullscreen.dart ================================================ import 'package:flutter/material.dart'; class Fullscreen extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( body: new Center( child: new Stack( children: [ new Image.asset( 'res/gif/material_design_flutter_1.gif', fit: BoxFit.fill, ), ], ), ), ); } } ================================================ FILE: lib/route/home.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_demo/widget/tabWidget.dart'; import 'package:flutter_demo/route/homeCards.dart'; import 'package:flutter_demo/route/homeDialogs.dart'; import 'homeWidgets.dart'; class HomePage extends StatefulWidget { HomePage({Key key, this.title}) : super(key: key); final String title; @override HomePageState createState() => new HomePageState(); } class HomePageState extends State { @override Widget build(BuildContext context) { final List tabs = ['Cards', 'Dialogs', 'Widgets']; final List widgets = [ new HomeCards(), new HomeDialogs(), new HomeWidgets(), ]; const List menus = const [ const Menu(title: 'item 1', icon: Icons.add), const Menu(title: 'item 2', icon: Icons.add), const Menu(title: 'item 3', icon: Icons.add), ]; return new TabbedScaffold( title: 'Flutter Demo', tabs: tabs, actions: [ new IconButton( icon: const Icon( Icons.search, color: Colors.white, ), tooltip: 'more', onPressed: () {}, ), new PopupMenuButton( itemBuilder: (BuildContext context) { return menus.skip(0).map((Menu menu) { return new PopupMenuItem( value: menu, child: new Text(menu.title), ); }).toList(); }, ), ], widgets: widgets, ); } } class Menu { const Menu({this.title, this.icon}); final String title; final IconData icon; } ================================================ FILE: lib/route/homeCards.dart ================================================ import 'package:flutter/material.dart'; class HomeCards extends StatelessWidget { @override Widget build(BuildContext context) { return new SingleChildScrollView( child: new Column( children: [ new Card( color: Color(0xFFFFF59D), child: new Column( mainAxisSize: MainAxisSize.min, children: [ const ListTile( leading: const Icon(Icons.image), title: const Text('This Is A Title'), subtitle: const Text('This is a subtitle in a list tile.'), ), new ButtonTheme.bar( // make buttons use the appropriate styles for cards child: new ButtonBar( children: [ new FlatButton( child: const Text('Button1'), onPressed: () {}, ), new FlatButton( child: const Text('Button2'), onPressed: () {}, ), ], ), ), ], ), ), new Card( child: new Column( mainAxisSize: MainAxisSize.min, children: [ new Image.asset( 'res/images/material_design_2.jpg', // height: 192.0, fit: BoxFit.fill, ), const ListTile( title: const Text('This Is A Title'), subtitle: const Text('This is a subtitle in a card.'), ), new ButtonTheme.bar( // make buttons use the appropriate styles for cards child: new ButtonBar( alignment: MainAxisAlignment.start, children: [ new FlatButton( child: const Text('Button1'), onPressed: () {}, ), new FlatButton( child: const Text('Button2'), onPressed: () {}, ), ], ), ), ], ), ), new Card( child: new Column( mainAxisSize: MainAxisSize.min, children: [ new Stack( alignment: AlignmentDirectional.bottomStart, children: [ new Image.asset( 'res/images/material_design_4.jpg', // height: 192.0, fit: BoxFit.fill, ), new ListTile( title: new Text( 'This Is A Title', style: new TextStyle(color: Colors.white, fontSize: 24.0), ), ), ], ), new ButtonTheme.bar( child: new ButtonBar( alignment: MainAxisAlignment.end, children: [ new IconButton( icon: new Icon(Icons.favorite, color: Colors.grey), onPressed: () {}, ), new IconButton( icon: new Icon(Icons.bookmark, color: Colors.grey), onPressed: () {}, ), new IconButton( icon: new Icon(Icons.share, color: Colors.grey), onPressed: () {}, ), ], ), ) ], ), ), ].map((Widget widget) { // Add a little space between the widgets return new Container( padding: const EdgeInsets.symmetric(vertical: 4.0), child: widget, ); }).toList(), ), ); } } ================================================ FILE: lib/route/homeDialogs.dart ================================================ import 'package:flutter/material.dart'; class HomeDialogs extends StatefulWidget { @override State createState() { return new HomeDialogsState(); } } class HomeDialogsState extends State { TimeOfDay _selectedTime; @override void initState() { super.initState(); final DateTime now = new DateTime.now(); _selectedTime = new TimeOfDay(hour: now.hour, minute: now.minute); } @override Widget build(BuildContext context) { final ThemeData theme = Theme.of(context); final TextStyle dialogTextStyle = theme.textTheme.subhead.copyWith(color: theme.textTheme.caption.color); return new ListView( padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0), children: [ new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Alert Dialog', style: new TextStyle(color: Colors.white), ), color: Colors.red, onPressed: () { showDialog( context: context, child: new AlertDialog( content: new Text('This is content', style: dialogTextStyle), actions: [ new FlatButton( onPressed: () { Navigator.pop(context, 'OK'); }, child: const Text('OK'), ) ], ), ).then((onValue) { if (onValue != null) { Scaffold.of(context).showSnackBar( new SnackBar(content: new Text('$onValue'))); } }); }), new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Alert Dialog', style: new TextStyle(color: Colors.white), ), color: Colors.purple, onPressed: () { showDialog( context: context, child: new AlertDialog( title: new Text('This Is Title'), content: new Text('This is content', style: dialogTextStyle), actions: [ new FlatButton( onPressed: () { Navigator.pop(context, 'Cancel'); }, child: const Text('Cancel')), new FlatButton( onPressed: () { Navigator.pop(context, 'OK'); }, child: const Text('OK'), ), ], ), ).then((onValue) { if (onValue != null) { Scaffold.of(context).showSnackBar( new SnackBar(content: new Text('$onValue'))); } }); }), new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Single Choice Dialog', style: new TextStyle(color: Colors.white), ), color: Colors.indigo, onPressed: () { showDialog( context: context, child: new SingleChoiceDialog(), ).then((onValue) { if (onValue != null) { Scaffold.of(context).showSnackBar( new SnackBar(content: new Text('$onValue'))); } }); }), new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Multi Choise Dialog', style: new TextStyle(color: Colors.white), ), color: Colors.blue, onPressed: () { showDialog( context: context, child: new MultiChoiceDialog(), ).then((onValue) { if (onValue != null) { Scaffold.of(context).showSnackBar( new SnackBar(content: new Text('$onValue'))); } }); }), new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Time Picker Dialog', style: new TextStyle(color: Colors.white), ), color: Colors.teal, onPressed: () { showTimePicker( context: context, initialTime: _selectedTime, ).then((TimeOfDay value) { if (value != null) { _selectedTime = value; Scaffold.of(context).showSnackBar(new SnackBar( content: new Text('${value.format(context)}'))); } }); }), new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Date Picker Dialog', style: new TextStyle(color: Colors.white), ), color: Colors.green, onPressed: () { showDatePicker( context: context, initialDate: new DateTime.now(), firstDate: new DateTime(1970), lastDate: new DateTime(2500), ).then((DateTime value) { if (value != null) { Scaffold.of(context).showSnackBar( new SnackBar(content: new Text('${value}'))); } }); }), new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Show modal Bottom Sheet', style: new TextStyle(color: Colors.white), ), color: Colors.orange, onPressed: () { showModalBottomSheet( context: context, builder: (BuildContext context) { return new Container( padding: EdgeInsets.only(top: 16.0), decoration: const BoxDecoration( border: const Border( top: const BorderSide(color: Colors.black12)), ), child: new ListView( shrinkWrap: true, primary: false, children: [ new ListTile( dense: true, title: const Text('This is a modal bottom sheet'), ), new ListTile( dense: true, title: const Text('Click anywhete to dismiss'), ), new ButtonTheme.bar( // make buttons use the appropriate styles for cards child: new ButtonBar( children: [ new FlatButton( child: const Text('OK'), onPressed: () { Navigator.pop(context); }, ), ], ), ), ], )); }); }), new RaisedButton( padding: EdgeInsets.symmetric(vertical: 14.0), child: new Text( 'Show Bottom Sheet', style: new TextStyle(color: Colors.white), ), color: Colors.blueGrey, onPressed: () { showBottomSheet( context: context, builder: (BuildContext context) { return new Container( padding: EdgeInsets.only(top: 16.0), decoration: const BoxDecoration( border: const Border( top: const BorderSide(color: Colors.black12)), ), child: new ListView( shrinkWrap: true, primary: false, children: [ new ListTile( dense: true, title: const Text('This is a bottom sheet'), ), new ListTile( dense: true, title: const Text('Click OK to dismiss'), ), new ButtonTheme.bar( // make buttons use the appropriate styles for cards child: new ButtonBar( children: [ new FlatButton( child: const Text('OK'), onPressed: () { Navigator.pop(context); }, ), ], ), ), ], )); }); }), ].map((Widget widget) { return new Container( padding: const EdgeInsets.symmetric(vertical: 12.0), child: widget, ); }).toList(), ); } } int singleItemSelected = 0; List checkboxSelected = [false, false, false, false]; class SingleChoiceDialog extends StatefulWidget { @override State createState() { return new SingleChoiceDialogState(); } } class SingleChoiceDialogState extends State { @override Widget build(BuildContext context) { return new SimpleDialog( contentPadding: EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 0.0), title: new Text('This Is Title'), children: [ new Column( children: [ new RadioListTile( title: const Text('item 0'), value: 0, groupValue: singleItemSelected, onChanged: (int value) { setState(() { singleItemSelected = value; }); Navigator.pop(context, value); }, ), new RadioListTile( title: const Text('item 1'), value: 1, groupValue: singleItemSelected, onChanged: (int value) { setState(() { singleItemSelected = value; }); Navigator.pop(context, value); }, ), new RadioListTile( title: const Text('item 2'), value: 2, groupValue: singleItemSelected, onChanged: (int value) { setState(() { singleItemSelected = value; }); Navigator.pop(context, value); }, ), new RadioListTile( title: const Text('item 3'), value: 3, groupValue: singleItemSelected, onChanged: (int value) { setState(() { singleItemSelected = value; }); Navigator.pop(context, value); }, ), ], ), new ButtonTheme.bar( padding: EdgeInsets.symmetric(horizontal: 16.0), child: new ButtonBar( children: [ new FlatButton( onPressed: () { Navigator.pop(context, 'Cancel'); }, child: const Text('Cancel')), ], ), ), ], ); } } class MultiChoiceDialog extends StatefulWidget { @override State createState() { return new MultiChoiceDialogState(); } } class MultiChoiceDialogState extends State { @override Widget build(BuildContext context) { return new SimpleDialog( contentPadding: EdgeInsets.fromLTRB(8.0, 12.0, 8.0, 0.0), title: new Text('This Is Title'), children: [ new Column( children: [ new CheckboxListTile( title: const Text('item 0'), value: checkboxSelected[0], onChanged: (bool value) { setState(() { checkboxSelected[0] = value; }); }, ), new CheckboxListTile( title: const Text('item 1'), value: checkboxSelected[1], onChanged: (bool value) { setState(() { checkboxSelected[1] = value; }); }), new CheckboxListTile( title: const Text('item 2'), value: checkboxSelected[2], onChanged: (bool value) { setState(() { checkboxSelected[2] = value; }); }), new CheckboxListTile( title: const Text('item 3'), value: checkboxSelected[3], onChanged: (bool value) { setState(() { checkboxSelected[3] = value; }); }), ], ), new ButtonTheme.bar( child: new ButtonBar( children: [ new FlatButton( onPressed: () { Navigator.pop(context, 'OK'); }, child: const Text('OK')), ], ), ), ], ); } } ================================================ FILE: lib/route/homeWidgets.dart ================================================ import 'package:flutter/material.dart'; import 'dart:math' as math; class HomeWidgets extends StatefulWidget { @override State createState() { return new HomeWidgetsState(); } } class HomeWidgetsState extends State { double _sliderValue_1 = 0.2; double _sliderValue_2 = 20.0; @override Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); final TextStyle categoryStyle = themeData.textTheme.body2.copyWith(color: themeData.primaryColor); final TextStyle accentColorText = themeData.textTheme.body1.copyWith(color: Colors.black54); return new ListView( padding: const EdgeInsets.symmetric(horizontal: 16.0), children: [ new Text('TextField', style: categoryStyle), new TextField(), new Text('Chips', style: categoryStyle), new Row( children: [ new Chip(label: new Text('Chip', style: accentColorText)), new Chip( avatar: new Icon(Icons.account_circle, color: Colors.black54), label: new Text('Chip', style: accentColorText), ), new Chip( deleteIcon: new Icon(Icons.cancel, size: 18.0, color: Colors.black54), label: new Text('Chip', style: accentColorText), onDeleted: () {}, ), ].map((Widget widget) { return new Container( padding: const EdgeInsets.symmetric(horizontal: 4.0), child: widget, ); }).toList(), ), new Text('ExpansionTile', style: categoryStyle), new ExpansionTile( title: const Text('Sublist'), backgroundColor: themeData.accentColor.withOpacity(0.025), children: const [ const ListTile(title: const Text('Item 1')), const ListTile(title: const Text('Item 2')), const ListTile(title: const Text('Item 3')), ]), new Text('Slider', style: categoryStyle), new Slider( value: _sliderValue_1, min: 0.0, max: 1.0, activeColor: themeData.accentColor, inactiveColor: Colors.black12, onChanged: (double value) { setState(() { _sliderValue_1 = value; }); }), new Text('Slider with Divisions and Label', style: categoryStyle), new Slider( value: _sliderValue_2, min: 0.0, max: 100.0, activeColor: themeData.accentColor, inactiveColor: Colors.black12, divisions: 5, label: '${_sliderValue_2.round()}', onChanged: (double value) { setState(() { _sliderValue_2 = value; }); }), new Text('LinearProgressIndicator', style: categoryStyle), new LinearProgressIndicator( backgroundColor: Colors.black12, ), new Text('CircularProgressIndicator', style: categoryStyle), new Stack( children: [ new CircularProgressIndicator(), ], ), ].map((Widget widget) { return new Container( padding: const EdgeInsets.symmetric(vertical: 16.0), child: widget, ); }).toList(), ); } } ================================================ FILE: lib/route/list.dart ================================================ import 'dart:async'; import 'package:flutter/material.dart'; class ListPage extends StatefulWidget { ListPage({Key key}) : super(key: key); List items = new List.generate(30, (i) => "Item ${(i + 1)}"); @override State createState() { return new ListPageState(items: items); } } class ListPageState extends State { ListPageState({this.items}); final List items; final GlobalKey _scaffoldKey = new GlobalKey(); final GlobalKey _refreshIndicatorKey = new GlobalKey(); Future _handleRefresh() { final Completer completer = new Completer(); new Timer(const Duration(seconds: 2), () { completer.complete(null); }); return completer.future.then((_) { _scaffoldKey.currentState?.showSnackBar( new SnackBar( content: const Text('Refresh complete'), action: new SnackBarAction( label: 'RETRY', onPressed: () { _refreshIndicatorKey.currentState.show(); }, ), ), ); }); } @override Widget build(BuildContext context) { return new Scaffold( key: _scaffoldKey, appBar: new AppBar( title: new Text('List'), ), body: new RefreshIndicator( color: Colors.amber, key: _refreshIndicatorKey, onRefresh: _handleRefresh, child: new ListView.builder( itemCount: items.length, itemBuilder: (context, index) { final item = items[index]; return new Dismissible( key: new Key(item), onDismissed: (direction) { setState(() { items.removeAt(index); Scaffold.of(context).showSnackBar( new SnackBar(content: new Text("$item dismissed")), ); }); }, background: new Container( color: Colors.red, child: const ListTile( leading: const Icon(Icons.delete, color: Colors.white)), ), secondaryBackground: new Container( color: Colors.red, child: const ListTile( trailing: const Icon(Icons.delete, color: Colors.white)), ), child: new ListTile( leading: new CircleAvatar( backgroundColor: Colors.amber, child: new Icon(Icons.fiber_manual_record, color: Colors.white), ), title: new Text('$item'), subtitle: new Text('Pull to refresh. Swipe to dismiss.'), onTap: () {}, ), ); }, ), ), ); } } ================================================ FILE: lib/route/settings.dart ================================================ import 'package:flutter/material.dart'; class Settings extends StatefulWidget { @override State createState() { return new SettingsState(); } } class SettingsState extends State { bool switchValue = true; bool checkboxValue = true; @override Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); final TextStyle categoryStyle = themeData.textTheme.body2.copyWith(color: themeData.accentColor); final TextStyle dialogTextStyle = themeData.textTheme.subhead .copyWith(color: themeData.textTheme.caption.color); return new Scaffold( appBar: new AppBar( title: new Text('Settings'), ), body: new ListView( children: [ new ListTile( title: new Text( 'Category 1', style: categoryStyle, ), ), new ListTile( title: new Text('Settings Item 1'), subtitle: new Text('This is a ListTile'), onTap: () { showDialog( context: context, child: new AlertDialog( content: new Text('Settings item clicked.', style: dialogTextStyle), actions: [ new FlatButton( onPressed: () { Navigator.pop(context, 'OK'); }, child: const Text('OK'), ) ], ), ); }, ), new Divider(height: 1.0), new ListTile( title: new Text('Settings Item 2'), subtitle: new Text('This is a ListTile'), onTap: () { showDialog( context: context, child: new AlertDialog( content: new Text('Settings item clicked.', style: dialogTextStyle), actions: [ new FlatButton( onPressed: () { Navigator.pop(context, 'OK'); }, child: const Text('OK'), ) ], ), ); }, ), new Divider(height: 1.0), new ListTile( title: new Text('Settings Item 3'), subtitle: new Text('This is a ListTile'), onTap: () { showDialog( context: context, child: new AlertDialog( content: new Text('Settings item clicked.', style: dialogTextStyle), actions: [ new FlatButton( onPressed: () { Navigator.pop(context, 'OK'); }, child: const Text('OK'), ) ], ), ); }, ), new ListTile( title: new Text( 'Category 2', style: categoryStyle, ), ), new CheckboxListTile( value: checkboxValue, onChanged: (bool value) { setState(() { checkboxValue = value; }); }, title: new Text('Checkbox Item'), subtitle: new Text('This is a CheckboxListTile'), ), new Divider(height: 1.0), new SwitchListTile( value: switchValue, onChanged: (bool value) { setState(() { switchValue = value; }); }, title: new Text('Switch Item'), subtitle: new Text('This is a SwitchListTile'), ), ], ), ); } } ================================================ FILE: lib/route/sliverAppbar.dart ================================================ import 'package:flutter/material.dart'; class _ContactCategory extends StatelessWidget { const _ContactCategory({Key key, this.icon, this.children}) : super(key: key); final IconData icon; final List children; @override Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); return new Container( padding: const EdgeInsets.symmetric(vertical: 16.0), decoration: new BoxDecoration( border: new Border( bottom: new BorderSide(color: themeData.dividerColor))), child: new DefaultTextStyle( style: Theme.of(context).textTheme.subhead, child: new SafeArea( top: false, bottom: false, child: new Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ new Container( padding: const EdgeInsets.symmetric(vertical: 24.0), width: 72.0, child: new Icon(icon, color: themeData.primaryColor)), new Expanded(child: new Column(children: children)) ], ), ), ), ); } } class _ContactItem extends StatelessWidget { _ContactItem({Key key, this.icon, this.lines, this.tooltip, this.onPressed}) : assert(lines.length > 1), super(key: key); final IconData icon; final List lines; final String tooltip; final VoidCallback onPressed; @override Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); final List columnChildren = lines .sublist(0, lines.length - 1) .map((String line) => new Text(line)) .toList(); columnChildren .add(new Text(lines.last, style: themeData.textTheme.caption)); final List rowChildren = [ new Expanded( child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: columnChildren)) ]; if (icon != null) { rowChildren.add(new SizedBox( width: 72.0, child: new IconButton( icon: new Icon(icon), color: themeData.primaryColor, onPressed: onPressed))); } return new MergeSemantics( child: new Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: new Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: rowChildren)), ); } } class ContactsDemo extends StatefulWidget { @override ContactsDemoState createState() => new ContactsDemoState(); } enum AppBarBehavior { normal, pinned, floating, snapping } class ContactsDemoState extends State { static final GlobalKey _scaffoldKey = new GlobalKey(); final double _appBarHeight = 220.0; AppBarBehavior _appBarBehavior = AppBarBehavior.pinned; @override Widget build(BuildContext context) { return new Theme( data: new ThemeData( brightness: Brightness.light, platform: Theme.of(context).platform, ), child: new Scaffold( key: _scaffoldKey, body: new CustomScrollView( slivers: [ new SliverAppBar( expandedHeight: _appBarHeight, pinned: _appBarBehavior == AppBarBehavior.pinned, floating: _appBarBehavior == AppBarBehavior.floating || _appBarBehavior == AppBarBehavior.snapping, snap: _appBarBehavior == AppBarBehavior.snapping, actions: [ new PopupMenuButton( onSelected: (AppBarBehavior value) { setState(() { _appBarBehavior = value; }); }, itemBuilder: (BuildContext context) => >[ const PopupMenuItem( value: AppBarBehavior.normal, child: const Text('App bar scrolls away')), const PopupMenuItem( value: AppBarBehavior.pinned, child: const Text('App bar stays put')), const PopupMenuItem( value: AppBarBehavior.floating, child: const Text('App bar floats')), const PopupMenuItem( value: AppBarBehavior.snapping, child: const Text('App bar snaps')), ], ), ], flexibleSpace: new FlexibleSpaceBar( title: const Text('User profile'), background: new Stack( fit: StackFit.expand, children: [ new Image.asset( 'res/images/material_design_3.png', fit: BoxFit.fill, height: _appBarHeight, ), // This gradient ensures that the toolbar icons are distinct against the background image. const DecoratedBox( decoration: const BoxDecoration( gradient: const LinearGradient( begin: const Alignment(0.0, -1.0), end: const Alignment(0.0, -0.4), colors: const [ const Color(0x60000000), const Color(0x00000000) ], ), ), ), ], ), ), ), new SliverList( delegate: new SliverChildListDelegate([ new _ContactCategory( icon: Icons.call, children: [ new _ContactItem( icon: Icons.message, tooltip: 'Send message', onPressed: () {}, lines: const [ '+1-234-5678901', 'Mobile', ], ), new _ContactItem( icon: Icons.message, tooltip: 'Send message', onPressed: () {}, lines: const [ '+1-234-5678902', 'Work', ], ), new _ContactItem( icon: Icons.message, tooltip: 'Send message', onPressed: () {}, lines: const [ '+1-234-5678903', 'Home', ], ), ], ), new _ContactCategory( icon: Icons.contact_mail, children: [ new _ContactItem( icon: Icons.email, tooltip: 'Send personal e-mail', onPressed: () {}, lines: const [ 'user.personal@email.com', 'Personal', ], ), new _ContactItem( icon: Icons.email, tooltip: 'Send work e-mail', onPressed: () {}, lines: const [ 'user.work@email.com', 'Work', ], ), ], ), new _ContactCategory( icon: Icons.location_on, children: [ new _ContactItem( icon: Icons.map, tooltip: 'Open map', onPressed: () {}, lines: const [ 'Home Street', 'San Francisco, CA', 'Home', ], ), new _ContactItem( icon: Icons.map, tooltip: 'Open map', onPressed: () {}, lines: const [ 'Work Parkway', 'Los Angeles, CA', 'Work', ], ), ], ), new _ContactCategory( icon: Icons.today, children: [ new _ContactItem( lines: const [ 'Birthday', 'November 27th, 1992', ], ), ], ), ]), ), ], ), ), ); } } ================================================ FILE: lib/widget/drawerWidget.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_demo/route/about.dart'; import 'package:flutter_demo/route/bottomNavigation.dart'; import 'package:flutter_demo/route/fullscreen.dart'; import 'package:flutter_demo/route/list.dart'; import 'package:flutter_demo/route/settings.dart'; import 'package:flutter_demo/route/sliverAppbar.dart'; class DrawerWidget extends StatelessWidget { @override Widget build(BuildContext context) { return new Drawer( child: new ListView( padding: EdgeInsets.all(0.0), children: [ // new MyDrawerHeader(), new UserAccountsDrawerHeader( accountName: new Text('User Name'), accountEmail: new Text('user.name@email.com'), currentAccountPicture: new CircleAvatar( backgroundColor: Colors.amber, child: new FlutterLogo(size: 42.0), ), ), new ListTile( leading: const Icon(Icons.list), title: const Text('List'), onTap: () { Navigator.pop(context); // close drawer Navigator.push(context, new MaterialPageRoute( builder: (BuildContext context) { return new ListPage(); }, )); }, ), new ListTile( leading: const Icon(Icons.vertical_align_top), title: const Text('Sliver Appbar'), onTap: () { Navigator.pop(context); Navigator.push(context, new MaterialPageRoute( builder: (BuildContext context) { return new ContactsDemo(); }, )); }, ), new ListTile( leading: const Icon(Icons.fullscreen), title: const Text('Full Screen'), onTap: () { Navigator.pop(context); Navigator.of(context).push(new MaterialPageRoute( builder: (BuildContext context) { return new Fullscreen(); }, )); }, ), new ListTile( leading: const Icon(Icons.more_horiz), title: const Text('Bottom Navigation'), onTap: () { Navigator.pop(context); Navigator.push(context, new MaterialPageRoute( builder: (BuildContext context) { return new BottomNavigationDemo(); }, )); }, ), new ListTile( leading: const Icon(Icons.settings), title: const Text('Settings'), onTap: () { Navigator.pop(context); Navigator.push(context, new MaterialPageRoute( builder: (BuildContext context) { return new Settings(); }, )); }, ), new Divider(), new ListTile( leading: const Icon(Icons.info), title: const Text('About'), onTap: () { Navigator.pop(context); Navigator.push(context, new MaterialPageRoute( builder: (BuildContext context) { return new About(); }, )); }, ), ], ), ); } } class MyDrawerHeader extends StatefulWidget { const MyDrawerHeader({Key key}) : super(key: key); @override _MyDrawerHeaderState createState() => new _MyDrawerHeaderState(); } class _MyDrawerHeaderState extends State { // bool _logoHasName = true; // bool _logoHorizontal = true; // MaterialColor _logoColor = Colors.blue; @override Widget build(BuildContext context) { final double statusBarHeight = MediaQuery.of(context).padding.top; return new Semantics( label: 'Flutter', child: new DrawerHeader( // decoration: new FlutterLogoDecoration( // margin: new EdgeInsets.fromLTRB( // 12.0, 12.0 + systemTopPadding, 12.0, 12.0), // style: _logoHasName // ? _logoHorizontal // ? FlutterLogoStyle.horizontal // : FlutterLogoStyle.stacked // : FlutterLogoStyle.markOnly, // lightColor: _logoColor.shade400, // darkColor: _logoColor.shade900, // textColor: const Color(0xFF616161), // ), // duration: const Duration(milliseconds: 500), // child: new GestureDetector( // onLongPress: () { // setState(() { // _logoHorizontal = !_logoHorizontal; // if (!_logoHasName) _logoHasName = true; // }); // }, // onTap: () { // setState(() { // _logoHasName = !_logoHasName; // }); // }, // onDoubleTap: () { // setState(() { // final List options = []; // if (_logoColor != Colors.blue) // options.addAll([Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue, Colors.blue]); // if (_logoColor != Colors.amber) // options.addAll([Colors.amber, Colors.amber, Colors.amber]); // if (_logoColor != Colors.red) // options.addAll([Colors.red, Colors.red, Colors.red]); // if (_logoColor != Colors.indigo) // options.addAll([Colors.indigo, Colors.indigo, Colors.indigo]); // if (_logoColor != Colors.pink) // options.addAll([Colors.pink]); // if (_logoColor != Colors.purple) // options.addAll([Colors.purple]); // if (_logoColor != Colors.cyan) // options.addAll([Colors.cyan]); // _logoColor = options[new math.Random().nextInt(options.length)]; // }); // } // ), padding: const EdgeInsets.all(0.0), child: new Container( color: Color(0x33000000), padding: const EdgeInsets.all(16.0), child: new Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ new FlutterLogo( size: 64.0, ), new Text( 'To Start Login', style: new TextStyle(color: Colors.white), ) ], ), ), ), ); } } ================================================ FILE: lib/widget/tabWidget.dart ================================================ import 'package:flutter/material.dart'; import 'drawerWidget.dart'; class TabbedScaffold extends StatelessWidget { TabbedScaffold({this.title, this.tabs, this.actions, this.widgets}); final String title; final List tabs; final List actions; final List widgets; @override Widget build(BuildContext context) { return new DefaultTabController( length: widgets.length, child: new Scaffold( appBar: new AppBar( title: new Text(title), actions: (actions ?? null), bottom: new TabBar( isScrollable: false, tabs: tabs.map((String s) => new Tab(text: s)).toList(), ), ), drawer: new DrawerWidget(), body: new TabBarView( children: widgets.map((Widget widget) { return new SafeArea( top: false, bottom: false, child: new Padding( padding: const EdgeInsets.all(8.0), child: widget, ), ); }).toList(), ), floatingActionButton: new FloatingActionButton( onPressed: () { Scaffold .of(context) .showSnackBar(new SnackBar(content: new Text('Show Snackbar'))); }, child: new Icon(Icons.add, color: Colors.white), ), ), ); } } ================================================ FILE: pubspec.yaml ================================================ name: flutter_demo description: A new Flutter application. dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: 0.1.0 url_launcher: 3.0.0 dev_dependencies: flutter_test: sdk: flutter # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: assets: - res/images/material_design_2.jpg - res/images/material_design_3.png - res/images/material_design_4.jpg - res/gif/material_design_flutter_1.gif # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.io/assets-and-images/#resolution-aware. # For details regarding adding assets from package dependencies, see # https://flutter.io/assets-and-images/#from-packages # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.io/custom-fonts/#from-packages ================================================ FILE: test/widget_test.dart ================================================ // This is a basic Flutter widget test. // To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter // provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to // find child widgets in the widget tree, read text, and verify that the values of widget properties // are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_demo/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(new MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); }