├── demo1 ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── demo1 │ │ │ │ │ └── MainActivity.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── images │ ├── 2.0x │ │ └── demo.png │ ├── 3.0X │ │ └── demo.png │ ├── demo.png │ └── loading.gif ├── ios │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── main.m ├── lib │ ├── bak │ │ ├── main.1.dart │ │ ├── main.10-动态渲染ListView.dart │ │ ├── main.11-ListView-builder().dart │ │ ├── main.12-ListView分隔符.dart │ │ ├── main.13-GridView.dart │ │ ├── main.14-GridView.builder&双列流.dart │ │ ├── main.15-Padding.dart │ │ ├── main.16-Row.dart │ │ ├── main.17-Row Expanded.dart │ │ ├── main.18-Column 和 Row组合布局.dart │ │ ├── main.19-Stack Align 组件.dart │ │ ├── main.2.dart │ │ ├── main.20-Stack Positioned.dart │ │ ├── main.21-AspectRatio.dart │ │ ├── main.22-Card 实现列表.dart │ │ ├── main.23-Wrap 实现流式布局.dart │ │ ├── main.24-StatefulWidget 实现计数器.dart │ │ ├── main.25-StatefulWidget&ListView.dart │ │ ├── main.26-BottomNavigationBar顶部导航.dart │ │ ├── main.27-基础路由&基础路由传值.dart │ │ ├── main.28命名路由-routes表和onGenerateRoute.dart │ │ ├── main.29-替换路由&返回根.dart │ │ ├── main.3-EchoWidegt.dart │ │ ├── main.30-自定义AppBar.dart │ │ ├── main.31-TabBar.dart │ │ ├── main.32-TabController 实现Tab.dart │ │ ├── main.33-Drawer DrawerHeader.dart │ │ ├── main.34-UserAccountsDrawerHeader.dart │ │ ├── main.35-RasiedButton.dart │ │ ├── main.36-FlatButton-IconButton-自定义按钮.dart │ │ ├── main.37-FloatingActionButton&闲鱼.dart │ │ ├── main.38-表单样式.dart │ │ ├── main.39-获取设置表单值.dart │ │ ├── main.4-Route.dart │ │ ├── main.40-checkbox&CheckboxListTile.dart │ │ ├── main.41-Radio&RadioListTile.dart │ │ ├── main.42-Switch.dart │ │ ├── main.43.2-表单验证.dart │ │ ├── main.43.3-FocusNode-表单聚焦.dart │ │ ├── main.43.表单模拟.dart │ │ ├── main.44日期选择&国际化.dart │ │ ├── main.45-2-渐变关注按钮.dart │ │ ├── main.45-颜色渐变-follow组件.dart │ │ ├── main.46-AnimatedContainer.dart │ │ ├── main.46.2.AnimatedOpacity & AnimatedContainer.dart │ │ ├── main.47-SnackBar及列表应用.dart │ │ ├── main.48-Dimissable-滑动删除.dart │ │ ├── main.49-CustomSrollView.dart │ │ ├── main.5-RouteArguments.dart │ │ ├── main.50-Sentry-错误上报.dart │ │ ├── main.51-Hero组件转场动画.dart │ │ ├── main.52-Isolates-compute.dart │ │ ├── main.53-WebSocket.dart │ │ ├── main.54-SharedPreference-键值存储.dart │ │ ├── main.55-io 文件读写.dart │ │ ├── main.56-Camera.dart │ │ ├── main.57-VideoPlayer.dart │ │ ├── main.6-container和Text Wdget.dart │ │ ├── main.7-Image.dart │ │ ├── main.8-ListView.dart │ │ ├── main.9-横向列表和列表嵌套.dart │ │ └── main.dart │ ├── main.dart │ ├── mock │ │ └── list.dart │ └── widegts │ │ └── EchoWidegt.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart └── demo2 ├── .gitignore ├── .metadata ├── README.md ├── android ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── demo2 │ │ │ │ └── MainActivity.java │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── ios ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ └── contents.xcworkspacedata └── Runner │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── main.m ├── lib ├── main.dart ├── mock │ └── products.dart ├── pages │ ├── Login.dart │ └── Products.dart ├── supplemental │ ├── asymmetric_view.dart │ ├── cut_corners_border.dart │ ├── product_card.dart │ └── product_columns.dart └── themes │ ├── colors.dart │ └── light.dart ├── pubspec.lock ├── pubspec.yaml └── test └── widget_test.dart /demo1/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /demo1/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 91213e2ed6b2aaab14ab40e03b3ba984b9a8bab4 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /demo1/README.md: -------------------------------------------------------------------------------- 1 | # demo1 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /demo1/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.demo1" 37 | minSdkVersion 21 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /demo1/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo1/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /demo1/android/app/src/main/java/com/example/demo1/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo1; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /demo1/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /demo1/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo1/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo1/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo1/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo1/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo1/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /demo1/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo1/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /demo1/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | -------------------------------------------------------------------------------- /demo1/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /demo1/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /demo1/images/2.0x/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/images/2.0x/demo.png -------------------------------------------------------------------------------- /demo1/images/3.0X/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/images/3.0X/demo.png -------------------------------------------------------------------------------- /demo1/images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/images/demo.png -------------------------------------------------------------------------------- /demo1/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/images/loading.gif -------------------------------------------------------------------------------- /demo1/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /demo1/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /demo1/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /demo1/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 37 | # referring to absolute paths on developers' machines. 38 | system('rm -rf .symlinks') 39 | system('mkdir -p .symlinks/plugins') 40 | 41 | # Flutter Pods 42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 43 | if generated_xcode_build_settings.empty? 44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first." 45 | end 46 | generated_xcode_build_settings.map { |p| 47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 48 | symlink = File.join('.symlinks', 'flutter') 49 | File.symlink(File.dirname(p[:path]), symlink) 50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 51 | end 52 | } 53 | 54 | # Plugin Pods 55 | plugin_pods = parse_KV_file('../.flutter-plugins') 56 | plugin_pods.map { |p| 57 | symlink = File.join('.symlinks', 'plugins', p[:name]) 58 | File.symlink(p[:path], symlink) 59 | pod p[:name], :path => File.join(symlink, 'ios') 60 | } 61 | end 62 | 63 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 64 | install! 'cocoapods', :disable_input_output_paths => true 65 | 66 | post_install do |installer| 67 | installer.pods_project.targets.each do |target| 68 | target.build_configurations.each do |config| 69 | config.build_settings['ENABLE_BITCODE'] = 'NO' 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /demo1/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - camera (0.0.1): 3 | - Flutter 4 | - Flutter (1.0.0) 5 | - FMDB (2.7.5): 6 | - FMDB/standard (= 2.7.5) 7 | - FMDB/standard (2.7.5) 8 | - path_provider (0.0.1): 9 | - Flutter 10 | - shared_preferences (0.0.1): 11 | - Flutter 12 | - sqflite (0.0.1): 13 | - Flutter 14 | - FMDB (~> 2.7.2) 15 | - video_player (0.0.1): 16 | - Flutter 17 | 18 | DEPENDENCIES: 19 | - camera (from `.symlinks/plugins/camera/ios`) 20 | - Flutter (from `.symlinks/flutter/ios`) 21 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 22 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) 23 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 24 | - video_player (from `.symlinks/plugins/video_player/ios`) 25 | 26 | SPEC REPOS: 27 | https://github.com/cocoapods/specs.git: 28 | - FMDB 29 | 30 | EXTERNAL SOURCES: 31 | camera: 32 | :path: ".symlinks/plugins/camera/ios" 33 | Flutter: 34 | :path: ".symlinks/flutter/ios" 35 | path_provider: 36 | :path: ".symlinks/plugins/path_provider/ios" 37 | shared_preferences: 38 | :path: ".symlinks/plugins/shared_preferences/ios" 39 | sqflite: 40 | :path: ".symlinks/plugins/sqflite/ios" 41 | video_player: 42 | :path: ".symlinks/plugins/video_player/ios" 43 | 44 | SPEC CHECKSUMS: 45 | camera: d56ad165545ae5a0ffb892376033760a969c68c8 46 | Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a 47 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 48 | path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259 49 | shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523 50 | sqflite: ff1d9da63c06588cc8d1faf7256d741f16989d5a 51 | video_player: 3964090a33353060ed7f58aa6427c7b4b208ec21 52 | 53 | PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932 54 | 55 | COCOAPODS: 1.7.2 56 | -------------------------------------------------------------------------------- /demo1/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo1/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /demo1/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /demo1/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /demo1/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /demo1/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | 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. -------------------------------------------------------------------------------- /demo1/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /demo1/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /demo1/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | demo1 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | NSCameraUsageDescription 26 | Can I use the camera please? 27 | NSMicrophoneUsageDescription 28 | Can I use the mic please? 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UIViewControllerBasedStatusBarAppearance 47 | 48 | NSAppTransportSecurity 49 | 50 | NSAllowsArbitraryLoads 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /demo1/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.1.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(MyApp()); 5 | } 6 | 7 | // 自定义组件 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return HomeContent(); 12 | } 13 | } 14 | 15 | class HomeContent extends StatelessWidget { 16 | @override 17 | Widget build(BuildContext context) { 18 | return Center( 19 | child: Text( 20 | 'Postbird 自定义 Widget!', 21 | textDirection: TextDirection.ltr, 22 | style: TextStyle(fontSize: 40, color: Colors.yellow), 23 | )); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.10-动态渲染ListView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'https://cdn.pixabay.com/photo/2019/05/20/13/22/portugal-4216645_1280.jpg'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('ListView Widget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | @override 30 | Widget build(BuildContext context) { 31 | return Center( 32 | child: ListViewDemo(), 33 | ); 34 | } 35 | } 36 | 37 | class ListViewDemo extends StatelessWidget { 38 | // 生成列表 39 | List _getData([int count = 20]) { 40 | List list = new List(); 41 | for (int i = 0; i < count; i++) { 42 | list.add(ListItem( 43 | title: '${TITLE}_${i}', 44 | subTitle: '${SUB_TITLE}_${i}', 45 | )); 46 | } 47 | return list; 48 | } 49 | 50 | // 读取文件 mock 数据 51 | List _getNewsList() { 52 | return newsList.news.map((item) { 53 | return ListItem( 54 | title: '${item['title']}', 55 | subTitle: '${item['time']}', 56 | cover: '${item['imgurl']}', 57 | ); 58 | }).toList(); 59 | } 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return ListView( 64 | // children: this._getData(20), 65 | children: this._getNewsList(), 66 | ); 67 | } 68 | } 69 | 70 | class ListItem extends StatelessWidget { 71 | ListItem({this.title, this.subTitle, this.cover}); 72 | 73 | final String title; 74 | final String subTitle; 75 | final String cover; 76 | 77 | @override 78 | Widget build(BuildContext context) { 79 | return ListTile( 80 | leading: Container( 81 | child: Image.network(this.cover, fit: BoxFit.cover), 82 | width: 60, 83 | height: 60, 84 | color: Colors.grey), 85 | trailing: Icon(Icons.chevron_right), 86 | title: Text(this.title), 87 | subtitle: Text(this.subTitle), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.11-ListView-builder().dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'https://cdn.pixabay.com/photo/2019/05/20/13/22/portugal-4216645_1280.jpg'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('ListView Widget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | 30 | // item build 方法 31 | Widget _buildListItem(BuildContext context, int index) { 32 | Map newsItem = newsList.news[index]; 33 | return ListItem( 34 | title: newsItem['title'], 35 | subTitle: newsItem['time'], 36 | ); 37 | } 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return ListView.builder( 42 | itemCount: newsList.news.length, 43 | itemBuilder: this._buildListItem); // 接收的两个参数 44 | } 45 | } 46 | 47 | class ListItem extends StatelessWidget { 48 | ListItem({this.title, this.subTitle, this.cover}); 49 | 50 | final String title; 51 | final String subTitle; 52 | final String cover; 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | return ListTile( 57 | trailing: Icon(Icons.chevron_right), 58 | title: Text(this.title), 59 | subtitle: Text(this.subTitle), 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.12-ListView分隔符.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'https://cdn.pixabay.com/photo/2019/05/20/13/22/portugal-4216645_1280.jpg'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('ListView Widget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | // item build 方法 30 | Widget _buildListItem(BuildContext context, int index) { 31 | Map newsItem = newsList.news[index]; 32 | return ListItem( 33 | title: newsItem['title'], 34 | subTitle: newsItem['time'], 35 | cover: newsItem['imgurl']); 36 | } 37 | 38 | // 无分割线的列表 39 | // @override 40 | // Widget build(BuildContext context) { 41 | // return ListView.builder( 42 | // itemCount: newsList.news.length, 43 | // itemBuilder: this._buildListItem); // 接收的两个参数 44 | 45 | // } 46 | 47 | // 能够生成下划线的列表 48 | @override 49 | Widget build(BuildContext context) { 50 | return ListView.separated( 51 | itemCount: newsList.news.length, 52 | itemBuilder: this._buildListItem, 53 | separatorBuilder: (BuildContext context, int index) { 54 | return Divider( 55 | color: Colors.grey[350], 56 | ); 57 | }, 58 | ); // 接收的两个参数 59 | } 60 | } 61 | 62 | class ListItem extends StatelessWidget { 63 | ListItem({this.title, this.subTitle, this.cover}); 64 | 65 | final String title; 66 | final String subTitle; 67 | final String cover; 68 | 69 | @override 70 | Widget build(BuildContext context) { 71 | return ListTile( 72 | leading: Container( 73 | child: Image.network(cover), 74 | color: Colors.grey, 75 | width: 80, 76 | height: 80, 77 | ), 78 | trailing: Icon(Icons.chevron_right), 79 | title: Text(this.title), 80 | subtitle: Text(this.subTitle), 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.13-GridView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'https://cdn.pixabay.com/photo/2019/05/20/13/22/portugal-4216645_1280.jpg'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('GridView Widget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | // 生成一个列表 30 | List _getGridList() { 31 | return newsList.news.map((item) { 32 | return GridViewItem(); 33 | }).toList(); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return GridView.count( 39 | children: _getGridList(), 40 | crossAxisCount: 3, 41 | padding: EdgeInsets.all(10), 42 | crossAxisSpacing: 20, // 水平距离 43 | mainAxisSpacing: 20, // 垂直距离 44 | childAspectRatio: 1.3, // 宽高比例 45 | ); 46 | } 47 | } 48 | 49 | class GridViewItem extends StatelessWidget { 50 | @override 51 | Widget build(BuildContext context) { 52 | return Container( 53 | child: Text('文本'), 54 | color: Colors.pink[200], 55 | ); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.15-Padding.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('Padding Widget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | // 生成一个列表 30 | List _getGridList() { 31 | return newsList.news.map((item) { 32 | return GridViewItem(); 33 | }).toList(); 34 | } 35 | 36 | // builder 37 | Widget _itemBuilderFunc(BuildContext context, int index) { 38 | final Map news = newsList.news[index]; 39 | return GridViewItem(); 40 | } 41 | 42 | // GridView.builder 43 | @override 44 | Widget build(BuildContext context) { 45 | return GridView.builder( 46 | itemCount: newsList.news.length, 47 | itemBuilder: this._itemBuilderFunc, 48 | // padding: EdgeInsets.fromLTRB(12, 12, 12, 0), 49 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 50 | crossAxisCount: 2, 51 | // crossAxisSpacing: 10, 52 | // mainAxisSpacing: 10, 53 | childAspectRatio: 1.4), 54 | ); 55 | } 56 | } 57 | 58 | class GridViewItem extends StatelessWidget { 59 | @override 60 | Widget build(BuildContext context) { 61 | return Padding( 62 | child: Image.network( 63 | IMAGE_SRC, 64 | fit: BoxFit.cover, 65 | ), 66 | padding: EdgeInsets.fromLTRB(5, 5, 5, 0)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.16-Row.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('Row Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return RowDemo(); 31 | } 32 | } 33 | 34 | class RowDemo extends StatelessWidget { 35 | @override 36 | Widget build(BuildContext context) { 37 | return Container( 38 | child: Row( 39 | children: [ 40 | IconContainer(color: Colors.white, icon: Icons.home), 41 | IconContainer(color: Colors.blue, icon: Icons.search), 42 | IconContainer(color: Colors.yellow, icon: Icons.settings), 43 | IconContainer(color: Colors.white, icon: Icons.track_changes), 44 | ], 45 | // mainAxisAlignment: MainAxisAlignment.center, 46 | mainAxisAlignment: MainAxisAlignment.spaceAround, 47 | // mainAxisAlignment: MainAxisAlignment.center, 48 | crossAxisAlignment: CrossAxisAlignment.center, 49 | ), 50 | width: 600, 51 | height: 800, 52 | color: Colors.grey); 53 | } 54 | } 55 | 56 | class IconContainer extends StatelessWidget { 57 | IconContainer({ 58 | @required this.icon, 59 | this.color = Colors.white, 60 | this.size = 32, 61 | }); 62 | 63 | final IconData icon; 64 | final double size; 65 | final Color color; 66 | 67 | @override 68 | Widget build(BuildContext context) { 69 | return Container( 70 | child: Center( 71 | child: Icon(this.icon, size: this.size, color: this.color), 72 | ), 73 | width: 50, 74 | height: 50, 75 | color: Colors.red, 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.17-Row Expanded.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('Row Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Column( 31 | children: [ 32 | RowDemo(), 33 | RowDemo1(), 34 | ], 35 | ); 36 | } 37 | } 38 | 39 | class RowDemo extends StatelessWidget { 40 | @override 41 | Widget build(BuildContext context) { 42 | return Row( 43 | children: [ 44 | Expanded(flex: 1, child: IconContainer(icon: Icons.home)), 45 | Expanded( 46 | flex: 2, 47 | child: IconContainer(icon: Icons.settings, bgColor: Colors.blue)), 48 | Expanded(flex: 1, child: IconContainer(icon: Icons.search)), 49 | ], 50 | ); 51 | } 52 | } 53 | 54 | class RowDemo1 extends StatelessWidget { 55 | @override 56 | Widget build(BuildContext context) { 57 | return Row( 58 | children: [ 59 | Expanded( 60 | flex: 1, 61 | child: IconContainer(icon: Icons.home, bgColor: Colors.pink), 62 | ), 63 | IconContainer(icon: Icons.settings, bgColor: Colors.blue), 64 | ], 65 | ); 66 | } 67 | } 68 | 69 | class IconContainer extends StatelessWidget { 70 | IconContainer( 71 | {@required this.icon, 72 | this.color = Colors.white, 73 | this.size = 32, 74 | this.bgColor = Colors.yellow}); 75 | 76 | final IconData icon; 77 | final double size; 78 | final Color color; 79 | final Color bgColor; 80 | 81 | @override 82 | Widget build(BuildContext context) { 83 | return Container( 84 | child: Center( 85 | child: Icon(this.icon, size: this.size, color: this.color), 86 | ), 87 | width: 50, 88 | height: 50, 89 | color: this.bgColor, 90 | ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.18-Column 和 Row组合布局.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('Row Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Column( 31 | children: [ColumnDemo()], 32 | ); 33 | } 34 | } 35 | 36 | class ColumnDemo extends StatelessWidget { 37 | @override 38 | Widget build(BuildContext context) { 39 | return Column( 40 | children: [ 41 | Container( 42 | color: Colors.grey[350], 43 | height: 150, 44 | ), 45 | SizedBox(height: 5), 46 | Row( 47 | children: [ 48 | Expanded( 49 | flex: 2, 50 | child: ImageContainer(imgSrc: IMAGE_SRC, height: 150), 51 | ), 52 | SizedBox(width: 5), 53 | Expanded( 54 | child: Column( 55 | children: [ 56 | ImageContainer(imgSrc: IMAGE_SRC, height: 72.5), 57 | SizedBox(height: 5), 58 | ImageContainer(imgSrc: IMAGE_SRC, height: 72.5) 59 | ], 60 | )), 61 | ], 62 | ) 63 | ], 64 | ); 65 | } 66 | } 67 | 68 | class ImageContainer extends StatelessWidget { 69 | final double height; 70 | final String imgSrc; 71 | ImageContainer({@required this.imgSrc, this.height = 100}); 72 | @override 73 | Widget build(BuildContext context) { 74 | return Container( 75 | child: Image.network(this.imgSrc, fit: BoxFit.cover), 76 | height: this.height, 77 | color: Colors.grey[350], 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.19-Stack Align 组件.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('Stack Align Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Center( 31 | child: Container( 32 | child: Stack( 33 | children: [ 34 | Align( 35 | child: Icon(Icons.home, size: 40, color: Colors.white), 36 | alignment: Alignment.topCenter), 37 | Align( 38 | child: Icon(Icons.search, size: 40, color: Colors.pink), 39 | alignment: Alignment.bottomLeft), 40 | Icon(Icons.settings, size: 40, color: Colors.blue), 41 | ], 42 | alignment: Alignment.center, 43 | ), 44 | height: 400, 45 | width: 300, 46 | color: Colors.yellow, 47 | ), 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.2.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(MyApp()); 5 | } 6 | 7 | 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | home: Scaffold( 13 | appBar: AppBar( 14 | title: Text('Postbird Flutter') 15 | ), 16 | body: HomeContent(), 17 | ), 18 | // theme: ThemeData.dark(), 19 | theme: ThemeData( 20 | primaryColor: Colors.yellow 21 | ) 22 | ); 23 | } 24 | } 25 | 26 | class HomeContent extends StatelessWidget { 27 | @override 28 | Widget build(BuildContext context) { 29 | return Center( 30 | child: Text( 31 | 'Postbird 自定义 Widget!', 32 | textDirection: TextDirection.ltr, 33 | style: TextStyle(fontSize: 40, color: Colors.blue), 34 | )); 35 | } 36 | } -------------------------------------------------------------------------------- /demo1/lib/bak/main.20-Stack Positioned.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('Stack Positioned Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Center( 31 | child: Container( 32 | child: Stack( 33 | children: [ 34 | Positioned( 35 | child: Icon(Icons.home, size: 40, color: Colors.white), 36 | left: 0, 37 | top: 0), 38 | Positioned( 39 | child: Icon(Icons.search, size: 40, color: Colors.pink), 40 | left: 0.4), 41 | Positioned( 42 | child: Icon(Icons.settings, size: 40, color: Colors.blue), 43 | bottom: 1), 44 | ], 45 | alignment: Alignment.center, 46 | ), 47 | height: 400, 48 | width: 300, 49 | color: Colors.yellow, 50 | ), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.21-AspectRatio.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('AspectRatio Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Center( 31 | child: AspectRatio( 32 | aspectRatio: 4 / 3, 33 | child: Container( 34 | color: Colors.pink, 35 | ), 36 | ), 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.22-Card 实现列表.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('Card Widget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | Widget buildItem(BuildContext context, int index) { 30 | Map news = newsList.news[index]; 31 | return CardItem2( 32 | title: news['title'], 33 | subTitle: news['docurl'], 34 | cover: news['imgurl'], 35 | ); 36 | } 37 | 38 | @override 39 | Widget build(BuildContext context) { 40 | return ListView.builder( 41 | itemCount: newsList.news.length, 42 | itemBuilder: buildItem, 43 | ); 44 | // return ListView( 45 | // children: [ 46 | // CardItem(), 47 | // CardItem2(), 48 | // CardItem2(), 49 | // ], 50 | // padding: EdgeInsets.only(top: 20), 51 | // ); 52 | } 53 | } 54 | 55 | class CardItem extends StatelessWidget { 56 | @override 57 | Widget build(BuildContext context) { 58 | return Card( 59 | child: Column( 60 | children: [ 61 | ListTile( 62 | title: Text(TITLE), 63 | subtitle: Text(SUB_TITLE), 64 | ), 65 | ListTile( 66 | title: Text('地址:上海市'), 67 | ), 68 | ListTile( 69 | title: Text('电话:12345678901'), 70 | ) 71 | ], 72 | ), 73 | ); 74 | } 75 | } 76 | 77 | class CardItem2 extends StatelessWidget { 78 | CardItem2({ 79 | this.title, 80 | this.subTitle, 81 | this.cover, 82 | }); 83 | final String title; 84 | final String subTitle; 85 | final String cover; 86 | @override 87 | Widget build(BuildContext context) { 88 | return Card( 89 | child: Column( 90 | children: [ 91 | AspectRatio( 92 | child: Container( 93 | decoration: BoxDecoration( 94 | image: DecorationImage( 95 | image: NetworkImage(this.cover), 96 | fit: BoxFit.cover, 97 | ), 98 | borderRadius: BorderRadius.vertical( 99 | top: Radius.circular(4), 100 | ), 101 | ), 102 | ), 103 | aspectRatio: 16 / 9, 104 | ), 105 | ListTile( 106 | title: 107 | Text(this.title, maxLines: 1, overflow: TextOverflow.ellipsis), 108 | subtitle: Text(this.subTitle, 109 | maxLines: 1, overflow: TextOverflow.ellipsis), 110 | leading: ClipOval( 111 | child: CircleAvatar(backgroundImage: NetworkImage(this.cover)), 112 | ), 113 | ) 114 | ], 115 | ), 116 | margin: EdgeInsets.all(10), 117 | ); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.23-Wrap 实现流式布局.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('Wrap RaisedButton Widget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | @override 30 | Widget build(BuildContext context) { 31 | return Padding( 32 | child: Wrap( 33 | children: [ 34 | ButtonItem(text: '盗墓笔记'), 35 | ButtonItem(text: '鬼吹灯'), 36 | ButtonItem(text: '这个书名是凑的'), 37 | ButtonItem(text: '藏海花'), 38 | ButtonItem(text: '沙海'), 39 | ButtonItem(text: '鬼吹灯'), 40 | ButtonItem(text: '这个书名是凑的'), 41 | ButtonItem(text: '沙海'), 42 | ButtonItem(text: '鬼吹灯'), 43 | ButtonItem(text: '这个书名是凑的'), 44 | ButtonItem(text: '藏海花'), 45 | ButtonItem(text: '沙海'), 46 | ButtonItem(text: '藏海花'), 47 | ButtonItem(text: '沙海'), 48 | ], 49 | spacing: 12, 50 | runSpacing: 13, 51 | alignment: WrapAlignment.start, 52 | runAlignment: WrapAlignment.end, 53 | ), 54 | padding: EdgeInsets.fromLTRB(10, 0, 10, 0), 55 | ); 56 | } 57 | } 58 | 59 | class ButtonItem extends StatelessWidget { 60 | ButtonItem({ 61 | Key key, 62 | @required this.text, 63 | }) : super(key: key); 64 | 65 | final String text; 66 | 67 | @override 68 | Widget build(BuildContext context) { 69 | return RaisedButton( 70 | child: Text(this.text), 71 | color: Theme.of(context).buttonColor, 72 | onPressed: () {}, 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.24-StatefulWidget 实现计数器.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('StatefulWidget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | @override 30 | Widget build(BuildContext context) { 31 | return NumberCounter(); 32 | } 33 | } 34 | 35 | class NumberCounter extends StatefulWidget { 36 | @override 37 | _NumberCounterState createState() => _NumberCounterState(); 38 | } 39 | 40 | class _NumberCounterState extends State { 41 | int num = 0; 42 | // num set state 43 | numSetState([bool flag = true]) { 44 | return () => setState(() { 45 | flag ? this.num++ : this.num--; 46 | }); 47 | } 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return Center( 52 | child: Column( 53 | children: [ 54 | SizedBox(height: 20), 55 | Text( 56 | this.num.toString(), 57 | style: TextStyle( 58 | color: Colors.pink, 59 | fontSize: 40, 60 | ), 61 | ), 62 | SizedBox(height: 20), 63 | Row( 64 | children: [ 65 | FlatButton( 66 | child: Text('+'), 67 | onPressed: numSetState(true), 68 | color: Theme.of(context).buttonColor, 69 | ), 70 | SizedBox(width: 10), 71 | FlatButton( 72 | child: Text('-'), 73 | onPressed: numSetState(false), 74 | color: Theme.of(context).buttonColor, 75 | ) 76 | ], 77 | mainAxisAlignment: MainAxisAlignment.center, 78 | ) 79 | ], 80 | ), 81 | ); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.25-StatefulWidget&ListView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | home: Scaffold( 18 | appBar: AppBar( 19 | title: Text('StatefulWidget'), 20 | backgroundColor: Colors.pink, 21 | ), 22 | body: HomeContent(), 23 | ), 24 | ); 25 | } 26 | } 27 | 28 | class HomeContent extends StatelessWidget { 29 | @override 30 | Widget build(BuildContext context) { 31 | return NewsList(); 32 | } 33 | } 34 | 35 | class NewsList extends StatefulWidget { 36 | NewsList({Key key}) : super(key: key); 37 | 38 | _NewsListState createState() => _NewsListState(); 39 | } 40 | 41 | class _NewsListState extends State { 42 | List _newsList = [ 43 | { 44 | 'title': TITLE, 45 | 'subTitle': SUB_TITLE, 46 | 'cover': IMAGE_SRC, 47 | } 48 | ]; 49 | 50 | List _buildNewsList() { 51 | return this._newsList.map((item) { 52 | return NewsItem( 53 | title: item['title'], 54 | subTitle: item['subTitle'], 55 | cover: item['cover'], 56 | ); 57 | }).toList(); 58 | } 59 | 60 | _onPressedHandle() { 61 | setState(() { 62 | this._newsList.add({ 63 | 'title': TITLE, 64 | 'subTitle': SUB_TITLE, 65 | 'cover': IMAGE_SRC, 66 | }); 67 | }); 68 | } 69 | 70 | @override 71 | Widget build(BuildContext context) { 72 | return ListView( 73 | children: [ 74 | FlatButton( 75 | child: Text('add'), 76 | color: Theme.of(context).buttonColor, 77 | onPressed: this._onPressedHandle, 78 | ), 79 | SizedBox(height: 30), 80 | Column( 81 | children: this._buildNewsList(), 82 | ) 83 | ], 84 | ); 85 | } 86 | } 87 | 88 | class NewsItem extends StatelessWidget { 89 | NewsItem({Key key, this.title, this.subTitle, this.cover}) : super(key: key); 90 | 91 | final String title; 92 | final String subTitle; 93 | final String cover; 94 | 95 | @override 96 | Widget build(BuildContext context) { 97 | return ListTile( 98 | leading: Image.network( 99 | this.cover, 100 | width: 80, 101 | height: 80, 102 | fit: BoxFit.cover, 103 | ), 104 | title: Text(this.title), 105 | subtitle: Text(this.subTitle), 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.26-BottomNavigationBar顶部导航.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatefulWidget { 14 | MyApp({Key key}) : super(key: key); 15 | 16 | _MyAppState createState() => _MyAppState(); 17 | } 18 | 19 | class _MyAppState extends State { 20 | 21 | int _currentIndex = 0; 22 | 23 | List _pageList = [ 24 | HomePage(), 25 | NewsPage(), 26 | MyPage(), 27 | ]; 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return MaterialApp( 32 | home: Scaffold( 33 | appBar: AppBar( 34 | title: Text('BottomNavigationBar'), 35 | backgroundColor: Colors.pink, 36 | ), 37 | body: this._pageList[this._currentIndex], 38 | bottomNavigationBar: BottomNavigationBar( 39 | onTap: (int index) { 40 | setState(() { 41 | this._currentIndex = index; 42 | }); 43 | }, 44 | currentIndex: this._currentIndex, 45 | fixedColor: Colors.pink, 46 | selectedFontSize: 12, 47 | type: BottomNavigationBarType.fixed, 48 | items: [ 49 | BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('首页')), 50 | BottomNavigationBarItem(icon: Icon(Icons.list), title: Text('新闻')), 51 | BottomNavigationBarItem( 52 | icon: Icon(Icons.people), title: Text('我的')), 53 | ], 54 | ), 55 | ), 56 | ); 57 | } 58 | } 59 | 60 | // 首页页面 61 | class HomePage extends StatelessWidget { 62 | const HomePage({Key key}) : super(key: key); 63 | 64 | @override 65 | Widget build(BuildContext context) { 66 | return PageContent(title: '首页'); 67 | } 68 | } 69 | 70 | // 新闻页面 71 | class NewsPage extends StatelessWidget { 72 | const NewsPage({Key key}) : super(key: key); 73 | 74 | @override 75 | Widget build(BuildContext context) { 76 | return PageContent(title: '新闻'); 77 | } 78 | } 79 | 80 | // 我的页面 81 | class MyPage extends StatelessWidget { 82 | const MyPage({Key key}) : super(key: key); 83 | 84 | @override 85 | Widget build(BuildContext context) { 86 | return PageContent(title: '我的'); 87 | } 88 | } 89 | 90 | // 页面内容 91 | class PageContent extends StatelessWidget { 92 | PageContent({Key key, this.title}) : super(key: key); 93 | final String title; 94 | @override 95 | Widget build(BuildContext context) { 96 | return Center( 97 | child: Text( 98 | this.title, 99 | style: TextStyle( 100 | color: Colors.pink, 101 | fontSize: 60, 102 | ), 103 | ), 104 | ); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.27-基础路由&基础路由传值.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | const MyApp({Key key}) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | home: Scaffold( 20 | appBar: AppBar( 21 | title: Text('路由'), 22 | backgroundColor: Colors.pink, 23 | ), 24 | body: HomeContent(), 25 | ), 26 | ); 27 | } 28 | } 29 | 30 | class HomeContent extends StatelessWidget { 31 | const HomeContent({Key key}) : super(key: key); 32 | 33 | @override 34 | Widget build(BuildContext context) { 35 | return Center( 36 | child: Column( 37 | children: [ 38 | FlatButton( 39 | child: Row( 40 | children: [Icon(Icons.search), Text('搜索')], 41 | ), 42 | onPressed: () { 43 | Navigator.push(context, 44 | MaterialPageRoute(builder: (context) => SearchPage())); 45 | }, 46 | color: Theme.of(context).buttonColor, 47 | ), 48 | FlatButton( 49 | child: Row( 50 | children: [Icon(Icons.person), Text('登录 传值')], 51 | ), 52 | onPressed: () { 53 | Navigator.of(context).push( 54 | MaterialPageRoute( 55 | builder: (context) => LoginPage( 56 | title: 'NewName', 57 | id: 2, 58 | ), 59 | ), 60 | ); 61 | }, 62 | color: Theme.of(context).buttonColor, 63 | ) 64 | ], 65 | ), 66 | ); 67 | } 68 | } 69 | 70 | // 搜索页面 71 | class SearchPage extends StatelessWidget { 72 | @override 73 | Widget build(BuildContext context) { 74 | return Scaffold( 75 | appBar: AppBar( 76 | title: Text('搜索'), 77 | ), 78 | ); 79 | } 80 | } 81 | 82 | // 登录 83 | class LoginPage extends StatelessWidget { 84 | final String title; 85 | final int id; 86 | const LoginPage({Key key, this.title = '表单', this.id}) : super(key: key); 87 | 88 | Text _getTitle() { 89 | return Text(id != null ? '${this.title} - ID:${this.id}' : this.title); 90 | } 91 | 92 | @override 93 | Widget build(BuildContext context) { 94 | return Scaffold( 95 | appBar: AppBar( 96 | title: this._getTitle(), 97 | ), 98 | ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.3-EchoWidegt.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import './widegts/EchoWidegt.dart'; 3 | 4 | void main() { 5 | runApp(MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | home: Scaffold( 13 | appBar: AppBar(title: Text('Postbird Flutter')), 14 | body: HomeContent(), 15 | ), 16 | // theme: ThemeData.dark(), 17 | theme: ThemeData(primaryColor: Colors.yellow)); 18 | } 19 | } 20 | 21 | class HomeContent extends StatelessWidget { 22 | @override 23 | Widget build(BuildContext context) { 24 | return Center( 25 | child: EchoWidegt(text: '啊啊啊啊', backgroundColor: Colors.pink,), 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.30-自定义AppBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | MyApp({Key key}) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | home: Scaffold( 20 | appBar: AppBar( 21 | title: Text('自定义 AppBar'), 22 | centerTitle: true, 23 | backgroundColor: Colors.pink, 24 | leading: IconButton( 25 | icon: Icon(Icons.home), 26 | onPressed: () { 27 | print('home app bar'); 28 | }, 29 | ), 30 | actions: [ 31 | Center( 32 | child: Text('所有订单'), 33 | ), 34 | IconButton( 35 | icon: Icon(Icons.more_horiz), 36 | onPressed: () {}, 37 | ), 38 | ], 39 | ), 40 | body: HomeContent(), 41 | ), 42 | ); 43 | } 44 | } 45 | 46 | class HomeContent extends StatelessWidget { 47 | const HomeContent({Key key}) : super(key: key); 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return Center( 52 | child: Column( 53 | children: [ 54 | FlatButton( 55 | color: Theme.of(context).buttonColor, 56 | child: Text('login'), 57 | onPressed: () { 58 | Navigator.of(context).pushNamed('/login'); 59 | }, 60 | ), 61 | FlatButton( 62 | color: Theme.of(context).buttonColor, 63 | child: Text('sign'), 64 | onPressed: () { 65 | Navigator.of(context).pushNamed('/sign'); 66 | }, 67 | ) 68 | ], 69 | ), 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.31-TabBar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | MyApp({Key key}) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | home: Scaffold( 20 | appBar: AppBar( 21 | title: Text('自定义 AppBar'), 22 | centerTitle: true, 23 | backgroundColor: Colors.pink, 24 | leading: IconButton( 25 | icon: Icon(Icons.home), 26 | onPressed: () { 27 | print('home app bar'); 28 | }, 29 | ), 30 | actions: [ 31 | Center( 32 | child: Text('所有订单'), 33 | ), 34 | IconButton( 35 | icon: Icon(Icons.more_horiz), 36 | onPressed: () {}, 37 | ), 38 | ], 39 | ), 40 | body: HomeContent(), 41 | ), 42 | ); 43 | } 44 | } 45 | 46 | class HomeContent extends StatelessWidget { 47 | const HomeContent({Key key}) : super(key: key); 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return DefaultTabController( 52 | length: 9, 53 | child: Scaffold( 54 | appBar: AppBar( 55 | title: TabBar( 56 | labelColor: Colors.yellow, 57 | unselectedLabelColor: Colors.white, 58 | indicatorWeight: 1, 59 | isScrollable: true, 60 | // labelPadding: EdgeInsets.fromLTRB(10, 0, 0, 0), 61 | labelStyle: TextStyle(fontSize: 14), 62 | tabs: [ 63 | Tab(text: 'Tab1'), 64 | Tab(text: 'Tab1'), 65 | Tab(text: 'Tab1'), 66 | Tab(text: 'Tab1'), 67 | Tab(text: 'Tab1'), 68 | Tab(text: 'Tab1'), 69 | Tab(text: 'Tab1'), 70 | Tab(text: 'Tab1'), 71 | Tab(text: 'Tab1'), 72 | ], 73 | ), 74 | ), 75 | body: TabBarView( 76 | children: [ 77 | ListViewContnet(), 78 | ListViewContnet(), 79 | ListViewContnet(), 80 | ListViewContnet(), 81 | ListViewContnet(), 82 | ListViewContnet(), 83 | ListViewContnet(), 84 | ListViewContnet(), 85 | ListViewContnet(), 86 | ], 87 | ), 88 | ), 89 | ); 90 | } 91 | } 92 | 93 | class ListViewContnet extends StatelessWidget { 94 | const ListViewContnet({Key key}) : super(key: key); 95 | 96 | @override 97 | Widget build(BuildContext context) { 98 | return ListView( 99 | children: [ 100 | ListTile(title: Text(TITLE)), 101 | ListTile(title: Text(TITLE)), 102 | ListTile(title: Text(TITLE)), 103 | ListTile(title: Text(TITLE)), 104 | ListTile(title: Text(TITLE)), 105 | ListTile(title: Text(TITLE)), 106 | ListTile(title: Text(TITLE)), 107 | ListTile(title: Text(TITLE)), 108 | ListTile(title: Text(TITLE)), 109 | ListTile(title: Text(TITLE)), 110 | ], 111 | ); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.32-TabController 实现Tab.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://cms-bucket.ws.126.net/2019/06/20/68fa7f186ffe4479ab27efabd4d94246.png'; 8 | 9 | void main() { 10 | runApp(MyApp()); 11 | } 12 | 13 | class MyApp extends StatelessWidget { 14 | MyApp({Key key}) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return MaterialApp( 19 | home: Scaffold( 20 | appBar: AppBar( 21 | title: Text('TabController'), 22 | backgroundColor: Colors.pink, 23 | ), 24 | body: TabControllerDemo(), 25 | ), 26 | ); 27 | } 28 | } 29 | 30 | class TabControllerDemo extends StatefulWidget { 31 | TabControllerDemo({Key key}) : super(key: key); 32 | 33 | _TabControllerDemoState createState() => _TabControllerDemoState(); 34 | } 35 | 36 | class _TabControllerDemoState extends State 37 | with SingleTickerProviderStateMixin { 38 | TabController _tabController; 39 | 40 | @override 41 | void initState() { 42 | super.initState(); 43 | this._tabController = new TabController(vsync: this, length: 5); 44 | this._tabController.addListener(() { 45 | print(this._tabController.toString()); 46 | print(this._tabController.index); 47 | print(this._tabController.length); 48 | print(this._tabController.previousIndex); 49 | }); 50 | } 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return Scaffold( 55 | appBar: AppBar( 56 | backgroundColor: Colors.black, 57 | title: TabBar( 58 | controller: this._tabController, 59 | tabs: [ 60 | Tab(text: '女装'), 61 | Tab(text: '男装'), 62 | Tab(text: '童装'), 63 | Tab(text: '夏装'), 64 | Tab(text: '冬装'), 65 | ], 66 | ), 67 | ), 68 | body: TabBarView( 69 | controller: this._tabController, 70 | children: [ 71 | ListViewContnet(), 72 | ListViewContnet(), 73 | ListViewContnet(), 74 | ListViewContnet(), 75 | ListViewContnet(), 76 | ], 77 | )); 78 | } 79 | } 80 | 81 | class ListViewContnet extends StatelessWidget { 82 | const ListViewContnet({Key key}) : super(key: key); 83 | 84 | @override 85 | Widget build(BuildContext context) { 86 | return ListView( 87 | children: [ 88 | ListTile(title: Text(TITLE)), 89 | ListTile(title: Text(TITLE)), 90 | ListTile(title: Text(TITLE)), 91 | ListTile(title: Text(TITLE)), 92 | ListTile(title: Text(TITLE)), 93 | ListTile(title: Text(TITLE)), 94 | ListTile(title: Text(TITLE)), 95 | ListTile(title: Text(TITLE)), 96 | ListTile(title: Text(TITLE)), 97 | ListTile(title: Text(TITLE)), 98 | ], 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.33-Drawer DrawerHeader.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://imgcdn.ph.126.net/UQhSl0NAkp9wsn0keF-rLA==/3084402794814350820.jpg'; 8 | const IMAGE_SRC_2 = 9 | 'http://imglf.nosdn.127.net/img/NVc1cHVseFhyWFcwdHhpdjJydFRvcWJSa0NNbGlRbGN2TXNOS3NwQVdET042YmpmemdjUm5RPT0.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('Drawer'), 24 | backgroundColor: Colors.pink, 25 | ), 26 | body: Center(child: Text('Drawer')), 27 | drawer: Drawer( 28 | child: ListView( 29 | padding: EdgeInsets.all(0), 30 | children: [ 31 | DrawerHeaderDemo(), 32 | ListItem(), 33 | Divider(), 34 | ListItem(), 35 | Divider(), 36 | ListItem(), 37 | Divider(), 38 | ], 39 | ), 40 | ), 41 | ), 42 | ); 43 | } 44 | } 45 | 46 | class DrawerHeaderDemo extends StatelessWidget { 47 | const DrawerHeaderDemo({Key key}) : super(key: key); 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return DrawerHeader( 52 | child: Column( 53 | children: [ 54 | ClipOval( 55 | child: Image.network( 56 | IMAGE_SRC, 57 | width: 65, 58 | height: 65, 59 | fit: BoxFit.cover, 60 | ), 61 | ), 62 | SizedBox(height: 20), 63 | Center( 64 | child: Text( 65 | 'Postbird', 66 | style: TextStyle(color: Colors.white), 67 | ), 68 | ), 69 | SizedBox(height: 10), 70 | Center( 71 | child: Text( 72 | '没有任何描述~', 73 | style: TextStyle(color: Colors.white), 74 | ), 75 | ), 76 | ], 77 | ), 78 | decoration: BoxDecoration( 79 | color: Colors.grey[350], 80 | image: DecorationImage( 81 | image: NetworkImage(IMAGE_SRC_2), 82 | fit: BoxFit.cover, 83 | ), 84 | ), 85 | ); 86 | } 87 | } 88 | 89 | class ListItem extends StatelessWidget { 90 | const ListItem({Key key}) : super(key: key); 91 | 92 | @override 93 | Widget build(BuildContext context) { 94 | return Container( 95 | child: ListTile( 96 | leading: CircleAvatar( 97 | backgroundColor: Colors.pink, 98 | child: Icon(Icons.home), 99 | ), 100 | title: Text('首页'), 101 | ), 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.34-UserAccountsDrawerHeader.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://imgcdn.ph.126.net/UQhSl0NAkp9wsn0keF-rLA==/3084402794814350820.jpg'; 8 | const IMAGE_SRC_2 = 9 | 'http://imglf.nosdn.127.net/img/NVc1cHVseFhyWFcwdHhpdjJydFRvcWJSa0NNbGlRbGN2TXNOS3NwQVdET042YmpmemdjUm5RPT0.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('Drawer'), 24 | backgroundColor: Colors.pink, 25 | ), 26 | body: Center(child: Text('Drawer')), 27 | drawer: Drawer( 28 | child: ListView( 29 | padding: EdgeInsets.all(0), 30 | children: [ 31 | DrawerHeaderDemo(), 32 | ListItem(), 33 | Divider(), 34 | ListItem(), 35 | Divider(), 36 | ListItem(), 37 | Divider(), 38 | ], 39 | ), 40 | ), 41 | ), 42 | ); 43 | } 44 | } 45 | 46 | class DrawerHeaderDemo extends StatelessWidget { 47 | const DrawerHeaderDemo({Key key}) : super(key: key); 48 | 49 | @override 50 | Widget build(BuildContext context) { 51 | return UserAccountsDrawerHeader( 52 | accountName: Text('postbird'), 53 | accountEmail: Text('没有任何描述~'), 54 | currentAccountPicture: CircleAvatar( 55 | backgroundImage: NetworkImage(IMAGE_SRC), 56 | backgroundColor: Colors.grey[350], 57 | ), 58 | otherAccountsPictures: [ 59 | CircleAvatar( 60 | backgroundImage: NetworkImage(IMAGE_SRC), 61 | backgroundColor: Colors.grey[350], 62 | ), 63 | ], 64 | decoration: BoxDecoration( 65 | image: DecorationImage( 66 | image: NetworkImage(IMAGE_SRC_2), 67 | fit: BoxFit.cover, 68 | ), 69 | color: Colors.grey[350], 70 | ), 71 | ); 72 | } 73 | } 74 | 75 | class ListItem extends StatelessWidget { 76 | const ListItem({Key key}) : super(key: key); 77 | 78 | @override 79 | Widget build(BuildContext context) { 80 | return Container( 81 | child: ListTile( 82 | leading: CircleAvatar( 83 | backgroundColor: Colors.pink, 84 | child: Icon(Icons.home), 85 | ), 86 | title: Text('首页'), 87 | onTap: () { 88 | Navigator.of(context).pop(); 89 | Navigator.of(context) 90 | .push(MaterialPageRoute(builder: (context) => UserPage())); 91 | }), 92 | ); 93 | } 94 | } 95 | 96 | class UserPage extends StatelessWidget { 97 | const UserPage({Key key}) : super(key: key); 98 | 99 | @override 100 | Widget build(BuildContext context) { 101 | return Scaffold( 102 | appBar: AppBar( 103 | title: Text('用户中心'), 104 | ), 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.37-FloatingActionButton&闲鱼.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://imgcdn.ph.126.net/UQhSl0NAkp9wsn0keF-rLA==/3084402794814350820.jpg'; 8 | const IMAGE_SRC_2 = 9 | 'http://imglf.nosdn.127.net/img/NVc1cHVseFhyWFcwdHhpdjJydFRvcWJSa0NNbGlRbGN2TXNOS3NwQVdET042YmpmemdjUm5RPT0.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('Button'), 24 | backgroundColor: Colors.pink, 25 | ), 26 | bottomNavigationBar: BottomNavigationBar( 27 | selectedFontSize: 12, 28 | unselectedFontSize: 12, 29 | unselectedItemColor: Colors.black, 30 | selectedItemColor: Colors.blue, 31 | items: [ 32 | BottomNavigationBarItem( 33 | icon: Icon(Icons.home), 34 | title: Text('首页'), 35 | ), 36 | BottomNavigationBarItem(icon: Icon(Icons.add), title: Text('发布')), 37 | BottomNavigationBarItem( 38 | icon: Icon(Icons.settings), title: Text('设置')), 39 | ], 40 | ), 41 | floatingActionButton: FloatingActionButtonDemo(), 42 | floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, 43 | body: HomeContent(), 44 | ), 45 | ); 46 | } 47 | } 48 | 49 | class HomeContent extends StatelessWidget { 50 | const HomeContent({Key key}) : super(key: key); 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return Center(); 55 | } 56 | } 57 | 58 | class FloatingActionButtonDemo extends StatelessWidget { 59 | const FloatingActionButtonDemo({Key key}) : super(key: key); 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return Container( 64 | padding: EdgeInsets.all(4), 65 | margin: EdgeInsets.only(top: 5), 66 | height: 50, 67 | width: 50, 68 | decoration: BoxDecoration( 69 | borderRadius: BorderRadius.circular(60), 70 | color: Colors.white, 71 | // border: Border( 72 | // top: BorderSide( 73 | // width: 1, 74 | // color: Colors.grey, 75 | // ), 76 | // ), 77 | ), 78 | child: FloatingActionButton( 79 | elevation: 0, 80 | backgroundColor: Colors.yellow, 81 | child: Icon( 82 | Icons.add, 83 | color: Colors.black, 84 | size: 30, 85 | ), 86 | onPressed: () {}, 87 | ), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.38-表单样式.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://imgcdn.ph.126.net/UQhSl0NAkp9wsn0keF-rLA==/3084402794814350820.jpg'; 8 | const IMAGE_SRC_2 = 9 | 'http://imglf.nosdn.127.net/img/NVc1cHVseFhyWFcwdHhpdjJydFRvcWJSa0NNbGlRbGN2TXNOS3NwQVdET042YmpmemdjUm5RPT0.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('表单'), 24 | backgroundColor: Colors.pink, 25 | ), 26 | body: HomeContent(), 27 | ), 28 | ); 29 | } 30 | } 31 | 32 | class HomeContent extends StatelessWidget { 33 | const HomeContent({Key key}) : super(key: key); 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return TextFieldDemo(); 38 | } 39 | } 40 | 41 | class TextFieldDemo extends StatefulWidget { 42 | TextFieldDemo({Key key}) : super(key: key); 43 | 44 | _TextFieldDemoState createState() => _TextFieldDemoState(); 45 | } 46 | 47 | class _TextFieldDemoState extends State { 48 | @override 49 | Widget build(BuildContext context) { 50 | return Padding( 51 | padding: EdgeInsets.all(10), 52 | child: Column( 53 | children: [ 54 | TextField(), 55 | SizedBox(height: 10), 56 | TextField( 57 | decoration: InputDecoration( 58 | labelText: '表单label', 59 | labelStyle: TextStyle( 60 | color: Colors.pink, 61 | fontSize: 12, 62 | ), 63 | helperText: 'helperText', 64 | hintText: 'Placeholder...', 65 | border: OutlineInputBorder( 66 | borderSide: BorderSide( 67 | color: Colors.pink, 68 | ), 69 | ), 70 | ), 71 | ), 72 | SizedBox(height: 10), 73 | TextField( 74 | maxLines: 4, 75 | decoration: InputDecoration(hintText: '多行文本'), 76 | ), 77 | SizedBox(height: 10), 78 | TextField( 79 | obscureText: true, 80 | decoration: InputDecoration(hintText: '密码框'), 81 | ), 82 | SizedBox(height: 10), 83 | TextField( 84 | obscureText: true, 85 | decoration: 86 | InputDecoration(hintText: '图标', icon: Icon(Icons.palette)), 87 | ), 88 | ], 89 | ), 90 | ); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.39-获取设置表单值.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'http://imgcdn.ph.126.net/UQhSl0NAkp9wsn0keF-rLA==/3084402794814350820.jpg'; 8 | const IMAGE_SRC_2 = 9 | 'http://imglf.nosdn.127.net/img/NVc1cHVseFhyWFcwdHhpdjJydFRvcWJSa0NNbGlRbGN2TXNOS3NwQVdET042YmpmemdjUm5RPT0.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('表单取值设置值'), 24 | backgroundColor: Colors.pink, 25 | ), 26 | body: HomeContent(), 27 | ), 28 | ); 29 | } 30 | } 31 | 32 | class HomeContent extends StatelessWidget { 33 | const HomeContent({Key key}) : super(key: key); 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return TextFieldDemo(); 38 | } 39 | } 40 | 41 | class TextFieldDemo extends StatefulWidget { 42 | TextFieldDemo({Key key}) : super(key: key); 43 | 44 | _TextFieldDemoState createState() => _TextFieldDemoState(); 45 | } 46 | 47 | class _TextFieldDemoState extends State { 48 | TextEditingController _name = TextEditingController(); 49 | TextEditingController _pass = TextEditingController(); 50 | 51 | @override 52 | void initState() { 53 | super.initState(); 54 | this._name.text = 'ptbird'; // 设置初始值 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | return Padding( 60 | padding: EdgeInsets.all(10), 61 | child: Column( 62 | children: [ 63 | TextField( 64 | decoration: InputDecoration( 65 | hintText: '账户', 66 | hintStyle: TextStyle( 67 | fontSize: 12, 68 | color: Colors.grey[300], 69 | ), 70 | ), 71 | controller: this._name, 72 | onChanged: (value) { 73 | this.setState(() { 74 | this._name.text = value; 75 | }); 76 | }, 77 | ), 78 | SizedBox(height: 10), 79 | TextField( 80 | obscureText: true, 81 | decoration: InputDecoration( 82 | hintText: '密码', 83 | hintStyle: TextStyle( 84 | fontSize: 12, 85 | color: Colors.grey[300], 86 | ), 87 | ), 88 | controller: this._pass, 89 | onChanged: (value) { 90 | this.setState(() { 91 | this._pass.text = value; 92 | }); 93 | }, 94 | ), 95 | SizedBox(height: 10), 96 | Container( 97 | width: double.infinity, 98 | height: 40, 99 | child: RaisedButton( 100 | child: Text('Login'), 101 | onPressed: () { 102 | print(this._name); 103 | print(this._pass); 104 | }, 105 | ), 106 | ), 107 | SizedBox(height: 10), 108 | Container( 109 | width: double.infinity, 110 | child: Text('${this._name.text} - ${this._pass.text}'), 111 | ), 112 | ], 113 | ), 114 | ); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.4-Route.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(MyApp()); 5 | } 6 | 7 | class MyApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | home: HomeContent(), 12 | // theme: ThemeData.dark(), 13 | theme: ThemeData(primaryColor: Colors.yellow)); 14 | } 15 | } 16 | 17 | class HomeContent extends StatelessWidget { 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar(title: Text('路由')), 22 | body: Center( 23 | child: Column( 24 | children: [ 25 | Text('Home'), 26 | FlatButton( 27 | child: Text('open new route'), 28 | color: Colors.yellow, 29 | onPressed: () { 30 | Navigator.of(context).push(new MaterialPageRoute( 31 | builder: (context) { 32 | return NewRouteWidget(); 33 | }, 34 | settings: 35 | RouteSettings(arguments: {'name': 'postbird'}), // 传参 36 | fullscreenDialog: true)); 37 | }, 38 | ) 39 | ], 40 | ))); 41 | } 42 | } 43 | 44 | // 新路由页面 45 | class NewRouteWidget extends StatelessWidget { 46 | @override 47 | Widget build(BuildContext context) { 48 | Map args = ModalRoute.of(context).settings.arguments; 49 | return Scaffold( 50 | appBar: AppBar(title: Text('获取参数')), 51 | body: Center( 52 | child: Column( 53 | children: [ 54 | Text(args.toString()), 55 | FlatButton( 56 | child: Text('pop'), 57 | onPressed: () { 58 | Navigator.pop(context); 59 | }, 60 | ) 61 | ], 62 | ))); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.40-checkbox&CheckboxListTile.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'https://cdn.pixabay.com/photo/2019/06/17/07/47/madeira-4279303__240.jpg'; 8 | const IMAGE_SRC_2 = 9 | 'https://cdn.pixabay.com/photo/2019/06/20/05/51/squirrel-4286247__480.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('CheckBox 组件'), 24 | backgroundColor: Colors.pink, 25 | ), 26 | body: HomeContent(), 27 | ), 28 | ); 29 | } 30 | } 31 | 32 | class HomeContent extends StatelessWidget { 33 | const HomeContent({Key key}) : super(key: key); 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return CheckBoxDemo(); 38 | } 39 | } 40 | 41 | class CheckBoxDemo extends StatefulWidget { 42 | CheckBoxDemo({Key key}) : super(key: key); 43 | 44 | _CheckBoxDemoState createState() => _CheckBoxDemoState(); 45 | } 46 | 47 | class _CheckBoxDemoState extends State { 48 | bool _flag = true; 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return Container( 53 | padding: EdgeInsets.all(10), 54 | child: Column( 55 | children: [ 56 | Row( 57 | crossAxisAlignment: CrossAxisAlignment.center, 58 | children: [ 59 | Checkbox( 60 | activeColor: Colors.pink, 61 | checkColor: Colors.blue, 62 | value: this._flag, 63 | onChanged: (value) { 64 | setState(() { 65 | this._flag = value; 66 | }); 67 | }, 68 | ), 69 | Container( 70 | child: Text(this._flag ? '选中' : '未选中'), 71 | ), 72 | ], 73 | ), 74 | SizedBox(height: 10), 75 | CheckboxListTile( 76 | title: Text('标题'), 77 | subtitle: Text('二级标题'), 78 | activeColor: Colors.pink, 79 | secondary: Image.network( 80 | IMAGE_SRC, 81 | fit: BoxFit.cover, 82 | // color: Colors.grey[200], 83 | width: 60, 84 | ), 85 | value: this._flag, 86 | onChanged: (value) { 87 | setState(() { 88 | this._flag = value; 89 | }); 90 | }, 91 | ), 92 | Divider(), 93 | CheckboxListTile( 94 | title: Text('标题'), 95 | subtitle: Text('二级标题'), 96 | activeColor: Colors.pink, 97 | secondary: Icon(Icons.panorama), 98 | selected: this._flag, 99 | value: this._flag, 100 | onChanged: (value) { 101 | setState(() { 102 | this._flag = value; 103 | }); 104 | }, 105 | ), 106 | Divider(), 107 | ], 108 | ), 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.42-Switch.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | // import 'mock/list.dart' as newsList; 3 | 4 | const TITLE = '标题标题标题标题标题标题标题'; 5 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 6 | const IMAGE_SRC = 7 | 'https://cdn.pixabay.com/photo/2019/06/17/07/47/madeira-4279303__240.jpg'; 8 | const IMAGE_SRC_2 = 9 | 'https://cdn.pixabay.com/photo/2019/06/20/05/51/squirrel-4286247__480.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('Switch 组件'), 24 | backgroundColor: Colors.pink, 25 | ), 26 | body: HomeContent(), 27 | ), 28 | ); 29 | } 30 | } 31 | 32 | class HomeContent extends StatelessWidget { 33 | const HomeContent({Key key}) : super(key: key); 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return CheckBoxDemo(); 38 | } 39 | } 40 | 41 | class CheckBoxDemo extends StatefulWidget { 42 | CheckBoxDemo({Key key}) : super(key: key); 43 | 44 | _CheckBoxDemoState createState() => _CheckBoxDemoState(); 45 | } 46 | 47 | class _CheckBoxDemoState extends State { 48 | bool _flag = true; 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return Container( 53 | padding: EdgeInsets.all(10), 54 | child: Column( 55 | children: [ 56 | Switch( 57 | activeColor: Colors.pink, 58 | value: this._flag, 59 | onChanged: (value) { 60 | setState(() { 61 | this._flag = value; 62 | }); 63 | }, 64 | ), 65 | ], 66 | ), 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.43.2-表单验证.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | home: Scaffold( 14 | appBar: AppBar( 15 | title: Text('表单验证'), 16 | backgroundColor: Colors.pink, 17 | ), 18 | body: HomeContent(), 19 | ), 20 | ); 21 | } 22 | } 23 | 24 | class HomeContent extends StatefulWidget { 25 | HomeContent({Key key}) : super(key: key); 26 | 27 | _HomeContentState createState() => _HomeContentState(); 28 | } 29 | 30 | class _HomeContentState extends State { 31 | final GlobalKey _formKey = GlobalKey(); 32 | 33 | @override 34 | Widget build(BuildContext context) { 35 | return Padding( 36 | padding: EdgeInsets.all(10), 37 | child: Column( 38 | children: [ 39 | Form( 40 | key: _formKey, 41 | child: Column( 42 | children: [ 43 | TextFormField( 44 | decoration: InputDecoration( 45 | hintText: '电话号码', 46 | ), 47 | validator: (value) { 48 | RegExp reg = new RegExp(r'^\d{11}$'); 49 | if (!reg.hasMatch(value)) { 50 | return '请输入11位手机号码'; 51 | } 52 | return null; 53 | }, 54 | ), 55 | TextFormField( 56 | decoration: InputDecoration( 57 | hintText: '用户名', 58 | ), 59 | validator: (value) { 60 | if (value.isEmpty) { 61 | return '请输入用户名'; 62 | } 63 | return null; 64 | }, 65 | ), 66 | ], 67 | ), 68 | ), 69 | SizedBox(height: 10), 70 | Row( 71 | children: [ 72 | Expanded( 73 | child: RaisedButton( 74 | child: Text('提交'), 75 | onPressed: () { 76 | if (_formKey.currentState.validate()) { 77 | Scaffold.of(context).showSnackBar(SnackBar( 78 | content: Text('提交成功...'), 79 | )); 80 | } 81 | }, 82 | ), 83 | ) 84 | ], 85 | ), 86 | ], 87 | ), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.43.3-FocusNode-表单聚焦.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | home: Scaffold( 14 | appBar: AppBar( 15 | title: Text('表单聚焦'), 16 | backgroundColor: Colors.pink, 17 | ), 18 | body: HomeContent(), 19 | ), 20 | ); 21 | } 22 | } 23 | 24 | class HomeContent extends StatefulWidget { 25 | HomeContent({Key key}) : super(key: key); 26 | 27 | _HomeContentState createState() => _HomeContentState(); 28 | } 29 | 30 | class _HomeContentState extends State { 31 | final GlobalKey _formKey = GlobalKey(); 32 | FocusNode _focusNode = FocusNode(); 33 | @override 34 | Widget build(BuildContext context) { 35 | return Stack( 36 | children: [ 37 | Padding( 38 | padding: EdgeInsets.all(10), 39 | child: Column( 40 | children: [ 41 | Form( 42 | key: _formKey, 43 | child: Column( 44 | children: [ 45 | TextFormField( 46 | focusNode: _focusNode, 47 | decoration: InputDecoration( 48 | hintText: '电话号码', 49 | ), 50 | ), 51 | TextFormField( 52 | autofocus: true, 53 | decoration: InputDecoration( 54 | hintText: '用户名', 55 | ), 56 | ), 57 | ], 58 | ), 59 | ), 60 | ], 61 | ), 62 | ), 63 | Positioned( 64 | child: InkWell( 65 | child: Icon(Icons.edit), 66 | onTap: () => FocusScope.of(context).requestFocus(_focusNode)), 67 | bottom: 30, 68 | right: 40, 69 | ), 70 | ], 71 | ); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.45-2-渐变关注按钮.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(MyApp()); 5 | } 6 | 7 | class MyApp extends StatelessWidget { 8 | const MyApp({Key key}) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | home: Scaffold( 14 | appBar: AppBar( 15 | title: Text('AnimatedContainer Follow'), 16 | ), 17 | body: FollowWidget(), 18 | ), 19 | ); 20 | } 21 | } 22 | 23 | class FollowWidget extends StatefulWidget { 24 | FollowWidget({Key key}) : super(key: key); 25 | 26 | _FollowWidgetState createState() => _FollowWidgetState(); 27 | } 28 | 29 | class _FollowWidgetState extends State { 30 | bool _followStatus = false; 31 | 32 | void _followClickHandle() { 33 | setState(() { 34 | this._followStatus = !this._followStatus; 35 | }); 36 | } 37 | 38 | List _getGradient() { 39 | if (this._followStatus) { 40 | return [Colors.grey, Colors.grey]; 41 | } else { 42 | return [const Color(0xFFFF5000), const Color(0xFFFF9000)]; 43 | } 44 | } 45 | 46 | List _getContent() { 47 | List defaultContent = [ 48 | Text( 49 | this._followStatus ? '已关注' : '关注', 50 | style: TextStyle( 51 | fontSize: 16, 52 | color: Colors.white, 53 | letterSpacing: 1.2, 54 | ), 55 | ) 56 | ]; 57 | List prefixContent = [ 58 | Image.network( 59 | 'https://gw.alicdn.com/tfs/TB1OC0TXMMPMeJjy1XcXXXpppXa-108-84.png', 60 | height: 16, 61 | ), 62 | SizedBox(width: 3) 63 | ]; 64 | if (!this._followStatus) { 65 | defaultContent.insertAll(0, prefixContent); 66 | } 67 | return defaultContent; 68 | } 69 | 70 | @override 71 | Widget build(BuildContext context) { 72 | return InkWell( 73 | child: AnimatedContainer( 74 | width: 90, 75 | height: 40, 76 | duration: Duration(milliseconds: 500), 77 | decoration: BoxDecoration( 78 | borderRadius: BorderRadius.all(Radius.circular(20)), 79 | gradient: LinearGradient( 80 | begin: Alignment(-1, 0), 81 | end: Alignment(1.0, 0), 82 | colors: this._getGradient(), 83 | ), 84 | ), 85 | child: Row( 86 | mainAxisAlignment: MainAxisAlignment.center, 87 | crossAxisAlignment: CrossAxisAlignment.center, 88 | children: this._getContent(), 89 | ), 90 | ), 91 | onTap: this._followClickHandle, 92 | ); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.46-AnimatedContainer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | home: Scaffold( 14 | appBar: AppBar( 15 | title: Text('AnimatedContainer Widget'), 16 | backgroundColor: Colors.pink, 17 | ), 18 | body: HomeContent(), 19 | ), 20 | ); 21 | } 22 | } 23 | 24 | class HomeContent extends StatefulWidget { 25 | HomeContent({Key key}) : super(key: key); 26 | 27 | _HomeContentState createState() => _HomeContentState(); 28 | } 29 | 30 | class _HomeContentState extends State { 31 | double _width = 60; 32 | double _height = 60; 33 | Color _color = Colors.pink; 34 | Matrix4 _transform = null; 35 | BorderRadius _borderRadius = BorderRadius.circular(8); 36 | 37 | void _onTapHandle() { 38 | Random random = new Random(); 39 | setState(() { 40 | _width = random.nextInt(300).toDouble(); 41 | _height = random.nextInt(300).toDouble(); 42 | _borderRadius = BorderRadius.circular(random.nextInt(300).toDouble()); 43 | _color = Color.fromARGB( 44 | 255, random.nextInt(256), random.nextInt(256), random.nextInt(256)); 45 | _transform = Matrix4.translationValues(random.nextInt(50).toDouble(), 46 | random.nextInt(50).toDouble(), random.nextInt(50).toDouble()); 47 | }); 48 | } 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return Stack( 53 | children: [ 54 | Center( 55 | child: AnimatedContainer( 56 | width: _width, 57 | height: _height, 58 | decoration: BoxDecoration( 59 | borderRadius: _borderRadius, 60 | color: _color, 61 | ), 62 | transform: _transform, 63 | duration: Duration( 64 | milliseconds: 500, 65 | ), 66 | ), 67 | ), 68 | Positioned( 69 | bottom: 1, 70 | right: 1, 71 | child: GestureDetector( 72 | child: Container( 73 | width: 50, 74 | height: 50, 75 | margin: EdgeInsets.fromLTRB(0, 0, 10, 10), 76 | decoration: BoxDecoration( 77 | borderRadius: BorderRadius.circular(50), 78 | color: Colors.pink, 79 | ), 80 | child: Icon( 81 | Icons.play_arrow, 82 | color: Colors.white, 83 | ), 84 | ), 85 | onTap: _onTapHandle, 86 | ), 87 | ) 88 | ], 89 | ); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.46.2.AnimatedOpacity & AnimatedContainer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | home: Scaffold( 14 | appBar: AppBar( 15 | title: Text('AnimatedOpacity Widget'), 16 | backgroundColor: Colors.pink, 17 | ), 18 | body: HomeContent(), 19 | ), 20 | ); 21 | } 22 | } 23 | 24 | class HomeContent extends StatefulWidget { 25 | HomeContent({Key key}) : super(key: key); 26 | 27 | _HomeContentState createState() => _HomeContentState(); 28 | } 29 | 30 | class _HomeContentState extends State { 31 | double _opacity = 1.0; 32 | Matrix4 _transform = Matrix4.translationValues(0, 0, 0); 33 | 34 | void _onTapHandle() { 35 | setState(() { 36 | _opacity = _opacity == 1.0 ? 0.0 : 1.0; 37 | _transform = _opacity == 0.0 38 | ? Matrix4.translationValues(-300, 0, 0) 39 | : Matrix4.translationValues(0, 0, 0); 40 | }); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return Stack( 46 | children: [ 47 | Center( 48 | child: Column( 49 | children: [ 50 | AnimatedContainer( 51 | duration: Duration(milliseconds: 500), 52 | transform: _transform, 53 | child: AnimatedOpacity( 54 | opacity: _opacity, 55 | duration: Duration(milliseconds: 500), 56 | child: Container( 57 | alignment: Alignment.center, 58 | width: 100, 59 | height: 50, 60 | color: Colors.pink, 61 | ), 62 | ), 63 | ), 64 | SizedBox(height: 10), 65 | Container( 66 | alignment: Alignment.center, 67 | width: 100, 68 | height: 50, 69 | color: Colors.blue, 70 | ), 71 | ], 72 | ), 73 | ), 74 | Positioned( 75 | bottom: 1, 76 | right: 1, 77 | child: InkWell( 78 | child: Container( 79 | width: 50, 80 | height: 50, 81 | margin: EdgeInsets.fromLTRB(0, 0, 10, 10), 82 | decoration: BoxDecoration( 83 | borderRadius: BorderRadius.circular(50), 84 | color: Colors.pink, 85 | ), 86 | child: Icon( 87 | Icons.play_arrow, 88 | color: Colors.white, 89 | ), 90 | ), 91 | onTap: _onTapHandle, 92 | ), 93 | ) 94 | ], 95 | ); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.47-SnackBar及列表应用.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | home: Scaffold( 14 | appBar: AppBar( 15 | title: Text('SnackBar Widget'), 16 | ), 17 | body: HomeContent(), 18 | ), 19 | ); 20 | } 21 | } 22 | 23 | class HomeContent extends StatefulWidget { 24 | HomeContent({Key key}) : super(key: key); 25 | 26 | _HomeContentState createState() => _HomeContentState(); 27 | } 28 | 29 | class _HomeContentState extends State { 30 | List _list = [ 31 | {'title': '标题1', 'subTitle': '二级标题1'}, 32 | {'title': '标题2', 'subTitle': '二级标题2'}, 33 | {'title': '标题3', 'subTitle': '二级标题3'}, 34 | ]; 35 | 36 | Map _deleteCache; 37 | 38 | Function _onDeleteHandle(i) { 39 | return () { 40 | _deleteCache = {'index': i, 'data': _list[i]}; 41 | setState(() { 42 | _list.removeAt(i); 43 | }); 44 | // show snackBar 45 | SnackBar snackBar = SnackBar( 46 | content: Text('已经删除'), 47 | action: SnackBarAction( 48 | label: '撤销', 49 | onPressed: () { 50 | if (_deleteCache != null) { 51 | setState(() { 52 | _list.insert(_deleteCache['index'], _deleteCache['data']); 53 | }); 54 | 55 | _deleteCache = null; 56 | } 57 | }), 58 | ); 59 | Scaffold.of(context).hideCurrentSnackBar(); 60 | Scaffold.of(context).showSnackBar(snackBar); 61 | }; 62 | } 63 | 64 | List _getList() { 65 | List list = []; 66 | for (int i = 0; i < _list.length; i++) { 67 | list.add(ListItem( 68 | title: _list[i]['title'], 69 | subTtitle: _list[i]['subTitle'], 70 | onDelete: _onDeleteHandle(i), 71 | )); 72 | } 73 | return list; 74 | } 75 | 76 | @override 77 | Widget build(BuildContext context) { 78 | return ListView( 79 | children: _getList(), 80 | ); 81 | } 82 | } 83 | 84 | class ListItem extends StatelessWidget { 85 | final Function onDelete; 86 | final String title; 87 | final String subTtitle; 88 | const ListItem({Key key, this.onDelete, this.title, this.subTtitle}) 89 | : super(key: key); 90 | 91 | @override 92 | Widget build(BuildContext context) { 93 | return ListTile( 94 | title: Text(title), 95 | subtitle: Text(subTtitle), 96 | trailing: InkWell( 97 | child: Icon(Icons.delete), 98 | onTap: this.onDelete, 99 | )); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.48-Dimissable-滑动删除.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/gestures.dart'; 4 | import 'package:flutter/material.dart'; 5 | 6 | void main() { 7 | runApp(MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | home: Scaffold( 15 | appBar: AppBar( 16 | title: Text('表单聚焦'), 17 | backgroundColor: Colors.pink, 18 | ), 19 | body: HomeContent(), 20 | ), 21 | ); 22 | } 23 | } 24 | 25 | class HomeContent extends StatefulWidget { 26 | HomeContent({Key key}) : super(key: key); 27 | 28 | _HomeContentState createState() => _HomeContentState(); 29 | } 30 | 31 | class _HomeContentState extends State { 32 | List _list = List.generate( 33 | 20, 34 | (i) => {'title': '标题$i', 'subTitle': '二级标题$i'}, 35 | ); 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return ListView.builder( 40 | itemCount: _list.length, 41 | itemBuilder: (BuildContext context, int index) { 42 | final item = _list[index]; 43 | return Dismissible( 44 | key: Key(item.toString()), 45 | // crossAxisEndOffset: 1.0, 46 | // secondaryBackground: Container(color: Colors.pink), 47 | dragStartBehavior: DragStartBehavior.down, 48 | direction: DismissDirection.endToStart, 49 | background: Container(color: Colors.red), 50 | child: ListTile( 51 | title: Text(item['title']), 52 | subtitle: Text(item['subTitle']), 53 | ), 54 | onDismissed: (direction) { 55 | setState(() { 56 | _list.removeAt(index); 57 | print(_list.length); 58 | }); 59 | Scaffold.of(context).hideCurrentSnackBar(); 60 | Scaffold.of(context).showSnackBar(SnackBar( 61 | content: Text('删除成功...'), 62 | )); 63 | }, 64 | confirmDismiss: (direction) { 65 | 66 | }, 67 | ); 68 | }, 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.49-CustomSrollView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const IMAGE_SRC = 'https://picsum.photos/id/142/600/400'; 4 | 5 | void main() { 6 | runApp(MyApp()); 7 | } 8 | 9 | class MyApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return MaterialApp( 13 | home: Scaffold( 14 | body: HomeContent(), 15 | ), 16 | ); 17 | } 18 | } 19 | 20 | class HomeContent extends StatelessWidget { 21 | HomeContent({Key key}) : super(key: key); 22 | 23 | List _list = List.generate(20, (index) => 'Item - $index'); 24 | 25 | Widget _builder(context, index) { 26 | return ListTile(title: Text(_list[index])); 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return CustomScrollView(slivers: [ 32 | SliverAppBar( 33 | title: Text('CustomScrollView'), 34 | backgroundColor: Colors.pink, 35 | // https://flutter.github.io/assets-for-api-docs/assets/material/app_bar_pinned.mp4 36 | floating: true, 37 | snap: false, 38 | pinned: true, 39 | expandedHeight: 200, 40 | actions: [ 41 | Container( 42 | margin: EdgeInsets.only(right: 16), 43 | child: Icon(Icons.list), 44 | ), 45 | ], 46 | leading: Icon(Icons.home), 47 | flexibleSpace: Row( 48 | children: [ 49 | Expanded( 50 | child: Image.network(IMAGE_SRC, fit: BoxFit.cover), 51 | ) 52 | ], 53 | ), 54 | ), 55 | SliverList( 56 | delegate: SliverChildBuilderDelegate( 57 | _builder, 58 | childCount: _list.length, 59 | ), 60 | ), 61 | ]); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.5-RouteArguments.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(MyApp()); 5 | } 6 | 7 | class MyApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | home: HomeContent(), 12 | // theme: ThemeData.dark(), 13 | theme: ThemeData(primaryColor: Colors.yellow), 14 | routes: { 15 | 'newRoute': (context) => NewRouteWidget(), // 路由表 16 | }, 17 | ); 18 | } 19 | } 20 | 21 | class HomeContent extends StatelessWidget { 22 | @override 23 | Widget build(BuildContext context) { 24 | return Scaffold( 25 | appBar: AppBar(title: Text('命名路由')), 26 | body: Center( 27 | child: Column( 28 | children: [ 29 | Text('Home'), 30 | FlatButton( 31 | child: Text('pushNamed 方法'), 32 | color: Colors.yellow, 33 | onPressed: () { 34 | Navigator.pushNamed(context, 'newRoute', 35 | arguments: {'name': 'postbird'}); 36 | }, 37 | ) 38 | ], 39 | ))); 40 | } 41 | } 42 | 43 | // 新路由页面 44 | class NewRouteWidget extends StatelessWidget { 45 | @override 46 | Widget build(BuildContext context) { 47 | Map args = ModalRoute.of(context).settings.arguments; 48 | return Scaffold( 49 | appBar: AppBar(title: Text('获取路由参数')), 50 | body: Center( 51 | child: Column( 52 | children: [ 53 | Text(args.toString()), 54 | FlatButton( 55 | color: Colors.yellow, 56 | child: Text('pop'), 57 | onPressed: () { 58 | Navigator.pop(context); 59 | }, 60 | ) 61 | ], 62 | ))); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.50-Sentry-错误上报.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:sentry/sentry.dart'; 3 | 4 | const IMAGE_SRC = 'https://picsum.photos/id/142/600/400'; 5 | 6 | void main() { 7 | runApp(MyApp()); 8 | } 9 | 10 | class MyApp extends StatefulWidget { 11 | MyApp({Key key}) : super(key: key); 12 | 13 | _MyAppState createState() => _MyAppState(); 14 | } 15 | 16 | class _MyAppState extends State { 17 | static String _dsn = 18 | 'https://89822c1cf16f4dfa9871720840ed20a6:ab5ab20e43af4f66a8d0ab05600f23ad@sentry.io/1490965'; 19 | final SentryClient _sentry = SentryClient(dsn: _dsn); 20 | 21 | // _MyAppState() { 22 | // try { 23 | // double name = 1 / 0; 24 | // } catch (err, stack) { 25 | // _sentry.captureException( 26 | // exception: err, 27 | // stackTrace: stack, 28 | // ); 29 | // } 30 | // } 31 | 32 | @override 33 | Widget build(BuildContext context) { 34 | return MaterialApp( 35 | home: Scaffold( 36 | appBar: AppBar( 37 | title: Text('Sentry'), 38 | ), 39 | body: Center( 40 | child: RaisedButton( 41 | child: Text('Report Error'), 42 | onPressed: () { 43 | _sentry.captureException( 44 | exception: Error(), 45 | ); 46 | }, 47 | ), 48 | ), 49 | ), 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.51-Hero组件转场动画.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const IMAGE_SRC = 4 | 'http://imglf3.nosdn.127.net/img/Mm9KQTVTN2NLSmxOdXp0Q3pRMTYycm1IakVPcERLOTNPVjRTcEJrZ2M5ZUpuMk1WMXJGNEhBPT0.jpg'; 5 | 6 | void main() { 7 | runApp(MyApp()); 8 | } 9 | 10 | class MyApp extends StatelessWidget { 11 | const MyApp({Key key}) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: HomeContent(), 17 | ); 18 | } 19 | } 20 | 21 | class HomeContent extends StatelessWidget { 22 | const HomeContent({Key key}) : super(key: key); 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return Scaffold( 27 | appBar: AppBar(title: Text('Home')), 28 | body: Center( 29 | child: Row( 30 | children: [ 31 | GestureDetector( 32 | child: Hero( 33 | tag: 'imgHero', 34 | child: Image.network( 35 | IMAGE_SRC, 36 | fit: BoxFit.cover, 37 | width: 300, 38 | ), 39 | ), 40 | onTap: () { 41 | Navigator.push( 42 | context, 43 | MaterialPageRoute( 44 | builder: (_) => NewPage(), 45 | // settings: RouteSettings(isInitialRoute: true), 46 | fullscreenDialog: true, 47 | ), 48 | ); 49 | }, 50 | ), 51 | ], 52 | ), 53 | ), 54 | ); 55 | } 56 | } 57 | 58 | class NewPage extends StatelessWidget { 59 | const NewPage({Key key}) : super(key: key); 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return Scaffold( 64 | // appBar: AppBar(title: Text('NewPage')), 65 | body: Column( 66 | children: [ 67 | Row( 68 | children: [ 69 | Expanded( 70 | child: GestureDetector( 71 | child: Hero( 72 | tag: 'imgHero', 73 | child: Image.network( 74 | IMAGE_SRC, 75 | fit: BoxFit.cover, 76 | ), 77 | ), 78 | onTap: () { 79 | Navigator.pop(context); 80 | }, 81 | ), 82 | ), 83 | ], 84 | ), 85 | SizedBox(height: 30), 86 | Text('阿斯达大所大所多'), 87 | SizedBox(height: 30), 88 | Text('阿斯达大所大所多'), 89 | SizedBox(height: 30), 90 | Text('阿斯达大所大所多'), 91 | SizedBox(height: 30), 92 | Text('阿斯达大所大所多'), 93 | SizedBox(height: 30), 94 | ], 95 | ), 96 | ); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.52-Isolates-compute.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:async'; 3 | 4 | import 'package:flutter/foundation.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:http/http.dart' as http; 7 | 8 | const IMAGE_SRC = 9 | 'http://imglf3.nosdn.127.net/img/Mm9KQTVTN2NLSmxOdXp0Q3pRMTYycm1IakVPcERLOTNPVjRTcEJrZ2M5ZUpuMk1WMXJGNEhBPT0.jpg'; 10 | 11 | void main() { 12 | runApp(MyApp()); 13 | } 14 | 15 | class MyApp extends StatelessWidget { 16 | const MyApp({Key key}) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | home: Scaffold( 22 | appBar: AppBar( 23 | title: Text('Isolates'), 24 | ), 25 | body: HttpRequestDemo()), 26 | ); 27 | } 28 | } 29 | 30 | class Photo { 31 | final String thumbnailUrl; 32 | 33 | Photo({this.thumbnailUrl}); 34 | 35 | factory Photo.fromJson(Map data) { 36 | return Photo( 37 | thumbnailUrl: data['tcover'] as String, 38 | ); 39 | } 40 | } 41 | 42 | List generatorPhoto(String body) { 43 | List list = json.decode(body); 44 | return list.map((item) => Photo.fromJson(item)).toList(); 45 | } 46 | 47 | Future> _fetchPhotos(http.Client client) async { 48 | http.Response response = await client.get( 49 | 'https://3g.163.com/photocenter/api/list/0001/00AP0001,3R710001,4T8E0001/30/100.json'); 50 | return compute(generatorPhoto, response.body); 51 | } 52 | 53 | class HttpRequestDemo extends StatelessWidget { 54 | const HttpRequestDemo({Key key}) : super(key: key); 55 | 56 | // Future> _fetchPhotos(http.Client client) async { 57 | // http.Response res = 58 | // await client.get('https://3g.163.com/photocenter/api/list/0001/00AP0001,3R710001,4T8E0001/30/100.json'); 59 | // List list = json.decode(res.body); 60 | // return list.map((item) { 61 | // return Photo.fromJson(item); 62 | // }).toList(); 63 | // } 64 | 65 | @override 66 | Widget build(BuildContext context) { 67 | return FutureBuilder>( 68 | future: _fetchPhotos(http.Client()), 69 | builder: (context, snapshot) { 70 | if (snapshot.hasError) { 71 | print(snapshot.error); 72 | } 73 | if (snapshot.hasData) { 74 | return PhotoListView(list: snapshot.data); 75 | } else { 76 | return Center(child: CircularProgressIndicator()); 77 | } 78 | }, 79 | ); 80 | } 81 | } 82 | 83 | class PhotoListView extends StatelessWidget { 84 | final List list; 85 | 86 | PhotoListView({Key key, this.list}) : super(key: key); 87 | 88 | @override 89 | Widget build(BuildContext context) { 90 | return GridView.builder( 91 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 92 | crossAxisCount: 2, 93 | ), 94 | itemCount: list.length, 95 | itemBuilder: (context, i) { 96 | return Image.network(list[i].thumbnailUrl); 97 | }, 98 | ); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.53-WebSocket.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:web_socket_channel/io.dart'; 4 | 5 | const IMAGE_SRC = 6 | 'http://imglf3.nosdn.127.net/img/Mm9KQTVTN2NLSmxOdXp0Q3pRMTYycm1IakVPcERLOTNPVjRTcEJrZ2M5ZUpuMk1WMXJGNEhBPT0.jpg'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | const MyApp({Key key}) : super(key: key); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | home: Scaffold( 19 | appBar: AppBar( 20 | title: Text('WebSocketDemo'), 21 | ), 22 | body: WebSocketDemo()), 23 | ); 24 | } 25 | } 26 | 27 | class WebSocketDemo extends StatefulWidget { 28 | WebSocketDemo({Key key}) : super(key: key); 29 | 30 | _WebSocketDemoState createState() => _WebSocketDemoState(); 31 | } 32 | 33 | class _WebSocketDemoState extends State { 34 | List _list = new List(); 35 | String _message; 36 | IOWebSocketChannel _channel = 37 | IOWebSocketChannel.connect("ws://echo.websocket.org"); 38 | 39 | void _onChangedHandle(value) { 40 | setState(() { 41 | _message = value.toString(); 42 | }); 43 | } 44 | 45 | _WebSocketDemoState() { 46 | print(_channel); 47 | } 48 | @override 49 | void initState() { 50 | super.initState(); 51 | setState(() { 52 | _list.add('[Info] Connected Successed!'); 53 | }); 54 | 55 | // 监听消息 56 | _channel.stream.listen((message) { 57 | print(message); 58 | setState(() { 59 | _list.add('[Received] ${message.toString()}'); 60 | }); 61 | }); 62 | } 63 | 64 | void _sendHandle() { 65 | if (_message.isNotEmpty) { 66 | _list.add('[Sended] $_message'); 67 | _channel.sink.add(_message); 68 | } 69 | } 70 | 71 | Widget _generatorForm() { 72 | return Column( 73 | children: [ 74 | TextField(onChanged: _onChangedHandle), 75 | SizedBox(height: 10), 76 | Row( 77 | mainAxisAlignment: MainAxisAlignment.spaceAround, 78 | children: [ 79 | RaisedButton( 80 | child: Text('Send'), 81 | onPressed: _sendHandle, 82 | ) 83 | ], 84 | ) 85 | ], 86 | ); 87 | } 88 | 89 | List _generatorList() { 90 | List tmpList = _list.map((item) => ListItem(msg: item)).toList(); 91 | List prefix = [_generatorForm()]; 92 | prefix.addAll(tmpList); 93 | return prefix; 94 | } 95 | 96 | @override 97 | Widget build(BuildContext context) { 98 | return ListView( 99 | padding: EdgeInsets.all(10), 100 | children: _generatorList(), 101 | ); 102 | } 103 | 104 | @override 105 | void dispose() { 106 | super.dispose(); 107 | _channel.sink.close(); 108 | } 109 | } 110 | 111 | class ListItem extends StatelessWidget { 112 | final String msg; 113 | ListItem({Key key, this.msg}) : super(key: key); 114 | 115 | @override 116 | Widget build(BuildContext context) { 117 | return Text(msg); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.54-SharedPreference-键值存储.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:shared_preferences/shared_preferences.dart'; 4 | 5 | const IMAGE_SRC = 6 | 'http://imglf3.nosdn.127.net/img/Mm9KQTVTN2NLSmxOdXp0Q3pRMTYycm1IakVPcERLOTNPVjRTcEJrZ2M5ZUpuMk1WMXJGNEhBPT0.jpg'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | const MyApp({Key key}) : super(key: key); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | home: Scaffold( 19 | appBar: AppBar( 20 | title: Text('Preferences Demo'), 21 | ), 22 | body: PreferencesDemo()), 23 | ); 24 | } 25 | } 26 | 27 | class PreferencesDemo extends StatefulWidget { 28 | PreferencesDemo({Key key}) : super(key: key); 29 | _PreferencesDemoState createState() => _PreferencesDemoState(); 30 | } 31 | 32 | class _PreferencesDemoState extends State { 33 | String _key; 34 | String _value; 35 | SharedPreferences _prefs; 36 | 37 | _PreferencesDemoState() { 38 | _key = 'name'; 39 | _value = 'postbird-value'; 40 | _getInstance(); 41 | } 42 | 43 | void _getInstance() async { 44 | _prefs = await SharedPreferences.getInstance(); 45 | } 46 | 47 | void _savePressedHandle() { 48 | _value = DateTime.now().toString(); 49 | _prefs.setString(_key, _value); 50 | print(_prefs); 51 | Scaffold.of(context).hideCurrentSnackBar(); 52 | Scaffold.of(context).showSnackBar(SnackBar(content: Text('set succssed'))); 53 | } 54 | 55 | void _getPressedHandle() { 56 | final name = _prefs.getString(_key); 57 | print(name); 58 | Scaffold.of(context).hideCurrentSnackBar(); 59 | Scaffold.of(context).showSnackBar(SnackBar(content: Text('get $name'))); 60 | } 61 | 62 | void _removePressedHandle() { 63 | final res = _prefs.remove(_key); 64 | print(res); 65 | Scaffold.of(context).hideCurrentSnackBar(); 66 | Scaffold.of(context).showSnackBar(SnackBar(content: Text('remove $_key'))); 67 | } 68 | 69 | @override 70 | Widget build(BuildContext context) { 71 | return Column( 72 | children: [ 73 | Row( 74 | mainAxisAlignment: MainAxisAlignment.center, 75 | children: [ 76 | RaisedButton( 77 | child: Text('setString'), 78 | onPressed: _savePressedHandle, 79 | ) 80 | ], 81 | ), 82 | Row( 83 | mainAxisAlignment: MainAxisAlignment.center, 84 | children: [ 85 | RaisedButton( 86 | child: Text('getString'), 87 | onPressed: _getPressedHandle, 88 | ) 89 | ], 90 | ), 91 | Row( 92 | mainAxisAlignment: MainAxisAlignment.center, 93 | children: [ 94 | RaisedButton( 95 | child: Text('remove'), 96 | onPressed: _removePressedHandle, 97 | ) 98 | ], 99 | ) 100 | ], 101 | ); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.55-io 文件读写.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:path_provider/path_provider.dart'; 6 | 7 | const IMAGE_SRC = 8 | 'http://imglf3.nosdn.127.net/img/Mm9KQTVTN2NLSmxOdXp0Q3pRMTYycm1IakVPcERLOTNPVjRTcEJrZ2M5ZUpuMk1WMXJGNEhBPT0.jpg'; 9 | 10 | void main() { 11 | runApp(MyApp()); 12 | } 13 | 14 | class MyApp extends StatelessWidget { 15 | const MyApp({Key key}) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return MaterialApp( 20 | home: Scaffold( 21 | appBar: AppBar( 22 | title: Text('文件读写 Demo'), 23 | ), 24 | body: FileIODemo()), 25 | ); 26 | } 27 | } 28 | 29 | class FileIODemo extends StatefulWidget { 30 | FileIODemo({Key key}) : super(key: key); 31 | 32 | _FileIODemoState createState() => _FileIODemoState(); 33 | } 34 | 35 | class _FileIODemoState extends State { 36 | int _counter = 0; 37 | File _file; 38 | 39 | _FileIODemoState() { 40 | _initFile(); 41 | } 42 | @override 43 | void initState() { 44 | super.initState(); 45 | _initCounter(); 46 | } 47 | 48 | _initCounter() async { 49 | final File file = await _localFile; 50 | final String res = await file.readAsString(); 51 | setState(() { 52 | _counter = int.parse(res ?? 0); 53 | }); 54 | } 55 | 56 | _initFile() async { 57 | _file = await _localFile; 58 | } 59 | 60 | Future get _localPath async { 61 | final directory = await getApplicationDocumentsDirectory(); 62 | print(directory.path); 63 | return directory.path; 64 | } 65 | 66 | Future get _localFile async { 67 | if (_file is File) { 68 | return _file; 69 | } else { 70 | final String path = await _localPath; 71 | _file = File('$path/counter.txt'); 72 | return _file; 73 | } 74 | } 75 | 76 | _saveCounter() async { 77 | final File file = await _localFile; 78 | file.writeAsString(_counter.toString()); 79 | } 80 | 81 | @override 82 | Widget build(BuildContext context) { 83 | return Column( 84 | children: [ 85 | SizedBox(height: 20), 86 | Row( 87 | mainAxisAlignment: MainAxisAlignment.center, 88 | children: [ 89 | Text(_counter.toString()), 90 | ], 91 | ), 92 | SizedBox(height: 20), 93 | Row( 94 | mainAxisAlignment: MainAxisAlignment.spaceAround, 95 | children: [ 96 | RaisedButton( 97 | child: Text('-'), 98 | onPressed: () { 99 | setState(() { 100 | _counter -= 1; 101 | _saveCounter(); 102 | }); 103 | }, 104 | ), 105 | RaisedButton( 106 | child: Text('+'), 107 | onPressed: () { 108 | setState(() { 109 | _counter += 1; 110 | _saveCounter(); 111 | }); 112 | }, 113 | ), 114 | ], 115 | ) 116 | ], 117 | ); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.57-VideoPlayer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:video_player/video_player.dart'; 4 | 5 | const String VIDEO_URL = 'https://www.runoob.com/try/demo_source/mov_bbb.mp4'; 6 | 7 | void main() => runApp(MyApp()); 8 | 9 | class MyApp extends StatelessWidget { 10 | const MyApp({Key key}) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return MaterialApp( 15 | home: Scaffold( 16 | appBar: AppBar( 17 | title: Text('video_player'), 18 | ), 19 | body: HomeContent()), 20 | ); 21 | } 22 | } 23 | 24 | class HomeContent extends StatefulWidget { 25 | HomeContent({Key key}) : super(key: key); 26 | 27 | _HomeContentState createState() => _HomeContentState(); 28 | } 29 | 30 | class _HomeContentState extends State { 31 | VideoPlayerController _controller; 32 | Future _initializeVideoPlayerFuture; 33 | @override 34 | void initState() { 35 | super.initState(); 36 | _controller = VideoPlayerController.network(VIDEO_URL); 37 | _controller.setLooping(true); 38 | _initializeVideoPlayerFuture = _controller.initialize(); 39 | } 40 | 41 | @override 42 | void dispose() { 43 | super.dispose(); 44 | _controller.dispose(); 45 | } 46 | 47 | @override 48 | Widget build(BuildContext context) { 49 | return Column( 50 | children: [ 51 | FutureBuilder( 52 | future: _initializeVideoPlayerFuture, 53 | builder: (context, snapshot) { 54 | print(snapshot.connectionState); 55 | if (snapshot.hasError) print(snapshot.error); 56 | if (snapshot.connectionState == ConnectionState.done) { 57 | return AspectRatio( 58 | // aspectRatio: 16 / 9, 59 | aspectRatio: _controller.value.aspectRatio, 60 | child: VideoPlayer(_controller), 61 | ); 62 | } else { 63 | return Center( 64 | child: CircularProgressIndicator(), 65 | ); 66 | } 67 | }, 68 | ), 69 | SizedBox(height: 30), 70 | RaisedButton( 71 | child: Icon( 72 | _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, 73 | ), 74 | onPressed: () { 75 | setState(() { 76 | if (_controller.value.isPlaying) { 77 | _controller.pause(); 78 | } else { 79 | // If the video is paused, play it. 80 | _controller.play(); 81 | } 82 | }); 83 | }, 84 | ) 85 | ], 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.6-container和Text Wdget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(MyApp()); 5 | } 6 | 7 | class MyApp extends StatelessWidget { 8 | @override 9 | Widget build(BuildContext context) { 10 | return MaterialApp( 11 | home: Scaffold( 12 | appBar: AppBar( 13 | title: Text('Container Widget'), 14 | backgroundColor: Colors.pink, 15 | ), 16 | body: HomeContent(), 17 | ), 18 | ); 19 | } 20 | } 21 | 22 | class HomeContent extends StatelessWidget { 23 | @override 24 | Widget build(BuildContext context) { 25 | return Center( 26 | child: Container( 27 | child: Text( 28 | '超长文本截断字体等超长文本截断字体等超长文本截断字体等超长文本截断字体等超长文本截断字体等超长文本截断字体等超长文本截断字体等', 29 | textAlign: TextAlign.left, 30 | maxLines: 2, 31 | overflow: TextOverflow.ellipsis, 32 | style: TextStyle( 33 | fontSize: 16, 34 | color: Colors.white, 35 | letterSpacing: 2, 36 | fontStyle: FontStyle.italic, 37 | decoration: TextDecoration.underline, 38 | decorationColor: Colors.yellow, 39 | decorationStyle: TextDecorationStyle.dotted), 40 | ), 41 | height: 300.0, 42 | width: 300, 43 | // padding: EdgeInsets.all(20), 44 | padding: EdgeInsets.fromLTRB(20, 10, 40, 20), 45 | margin: EdgeInsets.only(top: 100), 46 | transform: Matrix4.translationValues(10, 0, 0), 47 | // transform: Matrix4.rotationX(5), 48 | alignment: Alignment.bottomLeft, 49 | decoration: BoxDecoration( 50 | boxShadow: [ 51 | // 阴影 52 | BoxShadow( 53 | color: Colors.grey[500], 54 | offset: Offset(10.0, 12.0), 55 | blurRadius: 4.0, 56 | ), 57 | ], 58 | color: Colors.pink, 59 | border: Border.all( 60 | color: Colors.black, 61 | style: BorderStyle.solid, 62 | width: 2, 63 | ), 64 | borderRadius: BorderRadius.all( 65 | Radius.circular(12), 66 | ), 67 | ), 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.8-ListView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'https://cdn.pixabay.com/photo/2019/05/20/13/22/portugal-4216645_1280.jpg'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('ListView Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Center( 31 | child: ListViewDemo(), 32 | ); 33 | } 34 | } 35 | 36 | class ListViewDemo extends StatelessWidget { 37 | @override 38 | Widget build(BuildContext context) { 39 | return ListView( 40 | children: [ 41 | ListItemImage(), 42 | ListItemImage(), 43 | ListItemImage2(), 44 | ListItemImage2(), 45 | ListItemIcon(), 46 | ListItemIcon(), 47 | ListItemOnlyImage(), 48 | ListItemOnlyImage(), 49 | ], 50 | padding: EdgeInsets.all(12), 51 | ); 52 | } 53 | } 54 | 55 | class ListItemIcon extends StatelessWidget { 56 | @override 57 | Widget build(BuildContext context) { 58 | return ListTile( 59 | leading: Icon(Icons.settings, color: Colors.pink, size: 50), 60 | trailing: Icon(Icons.chevron_right, color: Colors.pink), 61 | title: Text(TITLE), 62 | subtitle: Text( 63 | SUB_TITLE, 64 | maxLines: 1, 65 | overflow: TextOverflow.ellipsis, 66 | ), 67 | ); 68 | } 69 | } 70 | 71 | class ListItemImage extends StatelessWidget { 72 | @override 73 | Widget build(BuildContext context) { 74 | return ListTile( 75 | leading: Container( 76 | child: Image.network( 77 | IMAGE_SRC, 78 | fit: BoxFit.cover, 79 | ), 80 | color: Colors.grey, 81 | width: 60, 82 | height: 60), 83 | trailing: Icon(Icons.chevron_right, color: Colors.pink), 84 | title: Text(TITLE), 85 | subtitle: Text( 86 | SUB_TITLE, 87 | maxLines: 1, 88 | overflow: TextOverflow.ellipsis, 89 | ), 90 | ); 91 | } 92 | } 93 | 94 | class ListItemImage2 extends StatelessWidget { 95 | @override 96 | Widget build(BuildContext context) { 97 | return ListTile( 98 | trailing: Container( 99 | child: Image.network( 100 | IMAGE_SRC, 101 | fit: BoxFit.cover, 102 | ), 103 | color: Colors.grey, 104 | width: 60, 105 | height: 60), 106 | title: Text(TITLE), 107 | subtitle: Text( 108 | SUB_TITLE, 109 | maxLines: 1, 110 | overflow: TextOverflow.ellipsis, 111 | ), 112 | ); 113 | } 114 | } 115 | 116 | class ListItemOnlyImage extends StatelessWidget { 117 | @override 118 | Widget build(BuildContext context) { 119 | return Container( 120 | child: Image.network(IMAGE_SRC, fit: BoxFit.cover), 121 | color: Colors.grey, 122 | width: 600, 123 | height: 400, 124 | margin: EdgeInsets.only(bottom: 10), 125 | ); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.9-横向列表和列表嵌套.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const TITLE = '标题标题标题标题标题标题标题'; 4 | const SUB_TITLE = '二级标题二级标题二级标题二级标题二级标题二级标题二级标题二级标题二'; 5 | const IMAGE_SRC = 6 | 'https://cdn.pixabay.com/photo/2019/05/20/13/22/portugal-4216645_1280.jpg'; 7 | 8 | void main() { 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | @override 14 | Widget build(BuildContext context) { 15 | return MaterialApp( 16 | home: Scaffold( 17 | appBar: AppBar( 18 | title: Text('ListView Widget'), 19 | backgroundColor: Colors.pink, 20 | ), 21 | body: HomeContent(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class HomeContent extends StatelessWidget { 28 | @override 29 | Widget build(BuildContext context) { 30 | return Center( 31 | child: Container( 32 | child: ListViewDemo(), 33 | height: 500, 34 | ), 35 | ); 36 | } 37 | } 38 | 39 | class ListViewDemo extends StatelessWidget { 40 | @override 41 | Widget build(BuildContext context) { 42 | return ListView( 43 | scrollDirection: Axis.horizontal, 44 | children: [ 45 | ListItem(), 46 | ListItem(), 47 | ListViewVertival(), 48 | ListItem(), 49 | ListItem(), 50 | ListItem(), 51 | ListItem(), 52 | ], 53 | padding: EdgeInsets.all(12), 54 | ); 55 | } 56 | } 57 | 58 | class ListItem extends StatelessWidget { 59 | @override 60 | Widget build(BuildContext context) { 61 | return Container( 62 | color: Colors.pink, 63 | margin: EdgeInsets.all(10), 64 | height: 100, 65 | width: 100, 66 | ); 67 | } 68 | } 69 | 70 | class ListViewVertival extends StatelessWidget { 71 | @override 72 | Widget build(BuildContext context) { 73 | return Container( 74 | child: ListView( 75 | children: [ 76 | ListItem(), 77 | ListItem(), 78 | ListItem(), 79 | ListItem(), 80 | ], 81 | ), 82 | width: 100, 83 | height: 500, 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /demo1/lib/bak/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | void main() { 4 | runApp(new Center( 5 | child: new Text( 6 | 'Hello World!', 7 | textDirection: TextDirection.ltr, 8 | ))); 9 | } 10 | -------------------------------------------------------------------------------- /demo1/lib/widegts/EchoWidegt.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class EchoWidegt extends StatelessWidget { 4 | const EchoWidegt({ 5 | @required this.text, 6 | this.backgroundColor, 7 | }); 8 | 9 | final String text; 10 | final Color backgroundColor; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return Center( 15 | child: Container( 16 | color: this.backgroundColor, 17 | child: Text(this.text), 18 | )); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /demo1/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: demo1 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.1.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | date_format: ^1.0.6 27 | cached_network_image: ^0.8.0 28 | transparent_image: ^1.0.0 29 | sentry: ^2.2.0 30 | http: ^0.12.0+2 31 | web_socket_channel: ^1.0.13 32 | shared_preferences: ^0.5.3+1 33 | camera: ^0.5.2+1 34 | video_player: ^0.10.1+3 35 | intl: ^0.15.7 36 | provider: ^2.0.0+1 37 | shrine_images: ^1.0.0 38 | 39 | dev_dependencies: 40 | flutter_test: 41 | sdk: flutter 42 | flutter_localizations: 43 | sdk: flutter 44 | 45 | 46 | # For information on the generic Dart part of this file, see the 47 | # following page: https://dart.dev/tools/pub/pubspec 48 | 49 | # The following section is specific to Flutter. 50 | flutter: 51 | 52 | # The following line ensures that the Material Icons font is 53 | # included with your application, so that you can use the icons in 54 | # the material Icons class. 55 | uses-material-design: true 56 | 57 | # To add assets to your application, add an assets section, like this: 58 | assets: 59 | - images/demo.png 60 | - images/2.0x/demo.png 61 | - images/3.0x/demo.png 62 | - images/loading.gif 63 | 64 | # An image asset can refer to one or more resolution-specific "variants", see 65 | # https://flutter.dev/assets-and-images/#resolution-aware. 66 | 67 | # For details regarding adding assets from package dependencies, see 68 | # https://flutter.dev/assets-and-images/#from-packages 69 | 70 | # To add custom fonts to your application, add a fonts section here, 71 | # in this "flutter" section. Each entry in this list should have a 72 | # "family" key with the font family name, and a "fonts" key with a 73 | # list giving the asset and other descriptors for the font. For 74 | # example: 75 | # fonts: 76 | # - family: Schyler 77 | # fonts: 78 | # - asset: fonts/Schyler-Regular.ttf 79 | # - asset: fonts/Schyler-Italic.ttf 80 | # style: italic 81 | # - family: Trajan Pro 82 | # fonts: 83 | # - asset: fonts/TrajanPro.ttf 84 | # - asset: fonts/TrajanPro_Bold.ttf 85 | # weight: 700 86 | # 87 | # For details regarding fonts from package dependencies, 88 | # see https://flutter.dev/custom-fonts/#from-packages 89 | -------------------------------------------------------------------------------- /demo1/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:demo1/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /demo2/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/ServiceDefinitions.json 65 | **/ios/Runner/GeneratedPluginRegistrant.* 66 | 67 | # Exceptions to above rules. 68 | !**/ios/**/default.mode1v3 69 | !**/ios/**/default.mode2v3 70 | !**/ios/**/default.pbxuser 71 | !**/ios/**/default.perspectivev3 72 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 73 | -------------------------------------------------------------------------------- /demo2/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 91213e2ed6b2aaab14ab40e03b3ba984b9a8bab4 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /demo2/README.md: -------------------------------------------------------------------------------- 1 | # demo2 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /demo2/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.demo2" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 61 | } 62 | -------------------------------------------------------------------------------- /demo2/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo2/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 13 | 20 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /demo2/android/app/src/main/java/com/example/demo2/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.demo2; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /demo2/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /demo2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /demo2/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /demo2/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo2/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.2.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /demo2/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | 3 | -------------------------------------------------------------------------------- /demo2/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /demo2/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /demo2/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /demo2/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /demo2/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /demo2/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo2/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /demo2/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /demo2/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/postbird/FlutterHelloWorld/56674dc34a2b2a32159daab0551594057e3a547e/demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /demo2/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | 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. -------------------------------------------------------------------------------- /demo2/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /demo2/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /demo2/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | demo2 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /demo2/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /demo2/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import './themes/light.dart'; 3 | import './pages/Login.dart'; 4 | import './pages/Products.dart'; 5 | 6 | void main() => runApp(MyApp()); 7 | 8 | class MyApp extends StatelessWidget { 9 | const MyApp({Key key}) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return MaterialApp( 14 | routes: { 15 | '/': (context) => HomeContent(), 16 | '/login': (context) => Login(), 17 | }, 18 | initialRoute: '/login', 19 | theme: lightTheme, 20 | // home: HomeContent(), 21 | ); 22 | } 23 | } 24 | 25 | class HomeContent extends StatelessWidget { 26 | const HomeContent({Key key}) : super(key: key); 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return Scaffold( 31 | appBar: AppBar( 32 | leading: Icon(Icons.menu, semanticLabel: 'menu'), 33 | title: Text('KAOLA'), 34 | actions: [ 35 | IconButton( 36 | icon: Icon(Icons.search), 37 | onPressed: () {}, 38 | ), 39 | IconButton( 40 | icon: Icon(Icons.tune), 41 | onPressed: () {}, 42 | ), 43 | ], 44 | ), 45 | body: ProducsList(), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /demo2/lib/pages/Products.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../mock/products.dart' as goods; 3 | 4 | class ProducsList extends StatelessWidget { 5 | const ProducsList({Key key}) : super(key: key); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return GridView.builder( 10 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( 11 | crossAxisCount: 2, 12 | childAspectRatio: 1.0, 13 | ), 14 | padding: EdgeInsets.all(12), 15 | itemCount: goods.list.length, 16 | itemBuilder: (context, index) { 17 | final Map item = goods.list[index]['goods']; 18 | return Card( 19 | elevation: 0.0, 20 | child: Column( 21 | crossAxisAlignment: CrossAxisAlignment.start, 22 | children: [ 23 | AspectRatio( 24 | aspectRatio: 18.0 / 11.0, 25 | child: Container( 26 | decoration: BoxDecoration( 27 | color: Colors.grey[300], 28 | borderRadius: BorderRadius.vertical( 29 | top: Radius.circular(4.0), 30 | ), 31 | image: DecorationImage( 32 | image: NetworkImage( 33 | item['imageUrlFor220'], 34 | ), 35 | fit: BoxFit.cover, 36 | ), 37 | ), 38 | ), 39 | ), 40 | Expanded( 41 | child: Padding( 42 | padding: EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0), 43 | child: Column( 44 | crossAxisAlignment: CrossAxisAlignment.start, 45 | children: [ 46 | Text( 47 | item['title'], 48 | maxLines: 1, 49 | overflow: TextOverflow.ellipsis, 50 | style: TextStyle(fontSize: 14.0), 51 | ), 52 | SizedBox(height: 5.0), 53 | Row( 54 | children: [ 55 | Expanded( 56 | child: Text( 57 | '¥${item['actualCurrentPriceForApp']}', 58 | style: 59 | TextStyle(fontSize: 14.0, color: Colors.pink), 60 | ), 61 | ), 62 | Expanded( 63 | child: Text( 64 | item['introduce'], 65 | maxLines: 1, 66 | overflow: TextOverflow.ellipsis, 67 | style: TextStyle( 68 | fontSize: 12.0, 69 | color: Colors.grey, 70 | ), 71 | ), 72 | ) 73 | ], 74 | ) 75 | ], 76 | ), 77 | ), 78 | ) 79 | ], 80 | ), 81 | ); 82 | }, 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /demo2/lib/supplemental/asymmetric_view.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018-present the Flutter authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import 'package:flutter/material.dart'; 16 | 17 | import '../model/product.dart'; 18 | import 'product_columns.dart'; 19 | 20 | class AsymmetricView extends StatelessWidget { 21 | final List products; 22 | 23 | AsymmetricView({Key key, this.products}); 24 | 25 | List _buildColumns(BuildContext context) { 26 | if (products == null || products.isEmpty) { 27 | return []; 28 | } 29 | 30 | /// This will return a list of columns. It will oscillate between the two 31 | /// kinds of columns. Even cases of the index (0, 2, 4, etc) will be 32 | /// TwoProductCardColumn and the odd cases will be OneProductCardColumn. 33 | /// 34 | /// Each pair of columns will advance us 3 products forward (2 + 1). That's 35 | /// some kinda awkward math so we use _evenCasesIndex and _oddCasesIndex as 36 | /// helpers for creating the index of the product list that will correspond 37 | /// to the index of the list of columns. 38 | return List.generate(_listItemCount(products.length), (int index) { 39 | double width = .59 * MediaQuery.of(context).size.width; 40 | Widget column; 41 | if (index % 2 == 0) { 42 | /// Even cases 43 | int bottom = _evenCasesIndex(index); 44 | column = TwoProductCardColumn( 45 | bottom: products[bottom], 46 | top: products.length - 1 >= bottom + 1 47 | ? products[bottom + 1] 48 | : null); 49 | width += 32.0; 50 | } else { 51 | /// Odd cases 52 | column = OneProductCardColumn( 53 | product: products[_oddCasesIndex(index)], 54 | ); 55 | } 56 | return Container( 57 | width: width, 58 | child: Padding( 59 | padding: EdgeInsets.symmetric(horizontal: 16.0), 60 | child: column, 61 | ), 62 | ); 63 | }).toList(); 64 | } 65 | 66 | int _evenCasesIndex(int input) { 67 | /// The operator ~/ is a cool one. It's the truncating division operator. It 68 | /// divides the number and if there's a remainder / decimal, it cuts it off. 69 | /// This is like dividing and then casting the result to int. Also, it's 70 | /// functionally equivalent to floor() in this case. 71 | return input ~/ 2 * 3; 72 | } 73 | 74 | int _oddCasesIndex(int input) { 75 | assert(input > 0); 76 | return (input / 2).ceil() * 3 - 1; 77 | } 78 | 79 | int _listItemCount(int totalItems) { 80 | if (totalItems % 3 == 0) { 81 | return totalItems ~/ 3 * 2; 82 | } else { 83 | return (totalItems / 3).ceil() * 2 - 1; 84 | } 85 | } 86 | 87 | @override 88 | Widget build(BuildContext context) { 89 | return ListView( 90 | scrollDirection: Axis.horizontal, 91 | padding: EdgeInsets.fromLTRB(0.0, 34.0, 16.0, 44.0), 92 | children: _buildColumns(context), 93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /demo2/lib/supplemental/product_card.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018-present the Flutter authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import 'package:flutter/material.dart'; 16 | import 'package:intl/intl.dart'; 17 | 18 | import '../model/product.dart'; 19 | 20 | class ProductCard extends StatelessWidget { 21 | ProductCard({this.imageAspectRatio: 33 / 49, this.product}) 22 | : assert(imageAspectRatio == null || imageAspectRatio > 0); 23 | 24 | final double imageAspectRatio; 25 | final Product product; 26 | 27 | static final kTextBoxHeight = 65.0; 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | final NumberFormat formatter = NumberFormat.simpleCurrency( 32 | decimalDigits: 0, locale: Localizations.localeOf(context).toString()); 33 | final ThemeData theme = Theme.of(context); 34 | 35 | final imageWidget = Image.asset( 36 | product.assetName, 37 | package: product.assetPackage, 38 | fit: BoxFit.cover, 39 | ); 40 | 41 | return Column( 42 | mainAxisAlignment: MainAxisAlignment.center, 43 | crossAxisAlignment: CrossAxisAlignment.center, 44 | children: [ 45 | AspectRatio( 46 | aspectRatio: imageAspectRatio, 47 | child: imageWidget, 48 | ), 49 | SizedBox( 50 | height: kTextBoxHeight * MediaQuery.of(context).textScaleFactor, 51 | width: 121.0, 52 | child: Column( 53 | mainAxisAlignment: MainAxisAlignment.end, 54 | crossAxisAlignment: CrossAxisAlignment.center, 55 | children: [ 56 | // TODO(larche): Make headline6 when available 57 | Text( 58 | product == null ? '' : product.name, 59 | style: theme.textTheme.button, 60 | softWrap: false, 61 | overflow: TextOverflow.ellipsis, 62 | maxLines: 1, 63 | ), 64 | SizedBox(height: 4.0), 65 | // TODO(larche): Make subtitle2 when available 66 | Text( 67 | product == null ? '' : formatter.format(product.price), 68 | style: theme.textTheme.caption, 69 | ), 70 | ], 71 | ), 72 | ), 73 | ], 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /demo2/lib/supplemental/product_columns.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2018-present the Flutter authors. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import 'package:flutter/material.dart'; 16 | 17 | import '../model/product.dart'; 18 | import 'product_card.dart'; 19 | 20 | class TwoProductCardColumn extends StatelessWidget { 21 | TwoProductCardColumn({ 22 | this.bottom, 23 | this.top, 24 | }) : assert(bottom != null); 25 | 26 | final Product bottom, top; 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | return LayoutBuilder( 31 | builder: (BuildContext context, BoxConstraints constraints) { 32 | const spacerHeight = 44.0; 33 | 34 | double heightOfCards = (constraints.biggest.height - spacerHeight) / 2.0; 35 | double heightOfImages = heightOfCards - ProductCard.kTextBoxHeight; 36 | // TODO: Change imageAspectRatio calculation (104) 37 | double imageAspectRatio = constraints.biggest.width / heightOfImages; 38 | 39 | // TODO: Replace Column with a ListView (104) 40 | return Column( 41 | mainAxisAlignment: MainAxisAlignment.center, 42 | crossAxisAlignment: CrossAxisAlignment.center, 43 | children: [ 44 | Padding( 45 | padding: EdgeInsetsDirectional.only(start: 28.0), 46 | child: top != null 47 | ? ProductCard( 48 | imageAspectRatio: imageAspectRatio, 49 | product: top, 50 | ) 51 | : SizedBox( 52 | height: heightOfCards, 53 | ), 54 | ), 55 | SizedBox(height: spacerHeight), 56 | Padding( 57 | padding: EdgeInsetsDirectional.only(end: 28.0), 58 | child: ProductCard( 59 | imageAspectRatio: imageAspectRatio, 60 | product: bottom, 61 | ), 62 | ), 63 | ], 64 | ); 65 | }); 66 | } 67 | } 68 | 69 | class OneProductCardColumn extends StatelessWidget { 70 | OneProductCardColumn({this.product}); 71 | 72 | final Product product; 73 | 74 | @override 75 | Widget build(BuildContext context) { 76 | // TODO: Replace Column with a ListView (104) 77 | return Column( 78 | mainAxisAlignment: MainAxisAlignment.end, 79 | children: [ 80 | ProductCard( 81 | product: product, 82 | ), 83 | SizedBox( 84 | height: 40.0, 85 | ), 86 | ], 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /demo2/lib/themes/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const kShrinePink50 = const Color(0xFFFEEAE6); 4 | const kShrinePink100 = const Color(0xFFFEDBD0); 5 | const kShrinePink300 = const Color(0xFFFBB8AC); 6 | const kShrinePink400 = const Color(0xFFEAA4A4); 7 | 8 | const kShrineBrown900 = const Color(0xFF442B2D); 9 | 10 | const kShrineErrorRed = const Color(0xFFC5032B); 11 | 12 | const kShrineSurfaceWhite = const Color(0xFFFFFBFA); 13 | const kShrineBackgroundWhite = Colors.white; 14 | 15 | -------------------------------------------------------------------------------- /demo2/lib/themes/light.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../supplemental/cut_corners_border.dart'; 3 | import 'colors.dart'; 4 | 5 | final ThemeData lightTheme = _buildTheme(); 6 | 7 | ThemeData _buildTheme() { 8 | final ThemeData base = ThemeData.light(); 9 | 10 | return base.copyWith( 11 | accentColor: kShrineBrown900, 12 | primaryColor: kShrinePink100, 13 | buttonColor: kShrinePink100, 14 | scaffoldBackgroundColor: kShrineBackgroundWhite, 15 | cardColor: kShrineBackgroundWhite, 16 | textSelectionColor: kShrinePink100, 17 | errorColor: kShrineErrorRed, 18 | textTheme: _buildTextTheme(base.textTheme), 19 | primaryTextTheme: _buildTextTheme(base.primaryTextTheme), 20 | accentTextTheme: _buildTextTheme(base.accentTextTheme), 21 | primaryIconTheme: base.iconTheme.copyWith( 22 | color: kShrineBrown900, 23 | ), 24 | inputDecorationTheme: InputDecorationTheme(border: CutCornersBorder()), 25 | ); 26 | } 27 | 28 | TextTheme _buildTextTheme(TextTheme base) { 29 | return base 30 | .copyWith( 31 | headline: base.headline.copyWith( 32 | fontWeight: FontWeight.w500, 33 | ), 34 | title: base.title.copyWith(fontSize: 18.0), 35 | caption: base.caption.copyWith( 36 | fontWeight: FontWeight.w400, 37 | fontSize: 14.0, 38 | ), 39 | ) 40 | .apply( 41 | fontFamily: 'Rubik', 42 | displayColor: kShrineBrown900, 43 | bodyColor: kShrineBrown900, 44 | ); 45 | } 46 | -------------------------------------------------------------------------------- /demo2/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: demo2 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.1.0 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | 27 | dev_dependencies: 28 | flutter_test: 29 | sdk: flutter 30 | 31 | 32 | # For information on the generic Dart part of this file, see the 33 | # following page: https://dart.dev/tools/pub/pubspec 34 | 35 | # The following section is specific to Flutter. 36 | flutter: 37 | 38 | # The following line ensures that the Material Icons font is 39 | # included with your application, so that you can use the icons in 40 | # the material Icons class. 41 | uses-material-design: true 42 | 43 | # To add assets to your application, add an assets section, like this: 44 | # assets: 45 | # - images/a_dot_burr.jpeg 46 | # - images/a_dot_ham.jpeg 47 | 48 | # An image asset can refer to one or more resolution-specific "variants", see 49 | # https://flutter.dev/assets-and-images/#resolution-aware. 50 | 51 | # For details regarding adding assets from package dependencies, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /demo2/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:demo2/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | --------------------------------------------------------------------------------