├── README.md
├── flutter_road_test
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ │ ├── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── draftbk
│ │ │ │ │ └── flutter_road_test
│ │ │ │ │ └── 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
│ │ └── xcshareddata
│ │ │ └── WorkspaceSettings.xcsettings
│ └── 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
│ ├── counter.dart
│ └── main.dart
├── pubspec.lock
├── pubspec.yaml
├── test
│ ├── counter_test.dart
│ └── widget_test.dart
└── test_driver
│ ├── app.dart
│ └── app_test.dart
├── flutter_road_widgets
├── .gitignore
├── .metadata
├── README.md
├── android
│ ├── app
│ │ ├── build.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── draftbk
│ │ │ │ └── flutterroadwidgets
│ │ │ │ └── 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
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ └── settings.gradle
├── images
│ └── flutter.png
├── ios
│ ├── Flutter
│ │ ├── AppFrameworkInfo.plist
│ │ ├── Debug.xcconfig
│ │ └── Release.xcconfig
│ ├── Podfile
│ ├── Runner.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── 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
│ ├── days
│ │ ├── Day1.dart
│ │ ├── Day10.dart
│ │ ├── Day11.dart
│ │ ├── Day12.dart
│ │ ├── Day2.dart
│ │ ├── Day3.dart
│ │ ├── Day4.dart
│ │ ├── Day5.dart
│ │ ├── Day6.dart
│ │ ├── Day7.dart
│ │ └── Day8.dart
│ ├── index.dart
│ ├── main.dart
│ ├── subpage
│ │ ├── MySingleChooseDialog.dart
│ │ └── TopBarPage.dart
│ └── utils
│ │ ├── carousel.dart
│ │ ├── carousel_pro.dart
│ │ ├── flutter_icon_icons.dart
│ │ └── throttle_debounce.dart
├── pubspec.yaml
└── test
│ └── widget_test.dart
└── notes
├── Dart_Intro.md
├── Flutter_Async.md
├── Flutter_Button.md
├── Flutter_Dialog.md
├── Flutter_Gridview.md
├── Flutter_Image.md
├── Flutter_Interview_Problem.md
├── Flutter_Listview.md
├── Flutter_NavigationBar.md
├── Flutter_Network.md
├── Flutter_Problem_Need_Solve.md
├── Flutter_Problem_Solved.md
├── Flutter_Tests.md
└── Flutter_Text.md
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter 学习之路
2 |
3 | 一个 Flutter 应用,记录 Flutter 的学习过程。 哈哈哈感觉想往下写挺多的,不知道能不能坚持下去。(ง •̀_•́)ง
4 |
5 | ## 前期准备篇
6 |
7 | - [Dart 入门笔记](https://github.com/draftbk/flutter_road/blob/master/notes/Dart_Intro.md)
8 | - 环境配置(待写)
9 |
10 | ## 控件布局篇
11 |
12 | - [Flutter 学习之路 - Text](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Text.md)
13 | - [Flutter 学习之路 - Button](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Button.md)
14 | - [Flutter 学习之路 - Image](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Image.md)
15 | - [Flutter 学习之路 - ListView](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Listview.md)
16 | - [Flutter 学习之路 - Gridview](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Gridview.md)
17 | - Flutter 学习之路 - Dialog 试验(待)
18 | - [Flutter 学习之路 - 导航栏](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_NavigationBar.md)
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | ## 线程网络篇
28 |
29 | - [Flutter 学习之路 - 异步任务](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Async.md)
30 | - [Flutter 学习之路 - 网络入门](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Network.md)
31 |
32 |
33 |
34 |
35 | ## 其他
36 | - [Flutter 学习之路 - 测试(单元测试,Widget 测试,集成测试)](https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Tests.md)
37 |
38 | ## 微信群
39 |
40 | 欢迎加入一起入坑 Flutter !
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/flutter_road_test/.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 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .packages
26 | .pub-cache/
27 | .pub/
28 | /build/
29 |
30 | # Android related
31 | **/android/**/gradle-wrapper.jar
32 | **/android/.gradle
33 | **/android/captures/
34 | **/android/gradlew
35 | **/android/gradlew.bat
36 | **/android/local.properties
37 | **/android/**/GeneratedPluginRegistrant.java
38 |
39 | # iOS/XCode related
40 | **/ios/**/*.mode1v3
41 | **/ios/**/*.mode2v3
42 | **/ios/**/*.moved-aside
43 | **/ios/**/*.pbxuser
44 | **/ios/**/*.perspectivev3
45 | **/ios/**/*sync/
46 | **/ios/**/.sconsign.dblite
47 | **/ios/**/.tags*
48 | **/ios/**/.vagrant/
49 | **/ios/**/DerivedData/
50 | **/ios/**/Icon?
51 | **/ios/**/Pods/
52 | **/ios/**/.symlinks/
53 | **/ios/**/profile
54 | **/ios/**/xcuserdata
55 | **/ios/.generated/
56 | **/ios/Flutter/App.framework
57 | **/ios/Flutter/Flutter.framework
58 | **/ios/Flutter/Generated.xcconfig
59 | **/ios/Flutter/app.flx
60 | **/ios/Flutter/app.zip
61 | **/ios/Flutter/flutter_assets/
62 | **/ios/ServiceDefinitions.json
63 | **/ios/Runner/GeneratedPluginRegistrant.*
64 |
65 | # Exceptions to above rules.
66 | !**/ios/**/default.mode1v3
67 | !**/ios/**/default.mode2v3
68 | !**/ios/**/default.pbxuser
69 | !**/ios/**/default.perspectivev3
70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
71 |
--------------------------------------------------------------------------------
/flutter_road_test/.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: e5b1ed7a7f7b85c1877e09a9495681f719be5578
8 | channel: beta
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/flutter_road_test/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.draftbk.flutter_road_test"
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 |
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
13 |
20 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/java/com/draftbk/flutter_road_test/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.draftbk.flutter_road_test;
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 |
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/flutter_road_test/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
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 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_test/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/flutter_road_test/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.
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_road_test
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 |
--------------------------------------------------------------------------------
/flutter_road_test/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 |
--------------------------------------------------------------------------------
/flutter_road_test/lib/counter.dart:
--------------------------------------------------------------------------------
1 | class Counter {
2 | int value = 0;
3 |
4 | void increment() => value++;
5 |
6 | void decrement() => value--;
7 | }
--------------------------------------------------------------------------------
/flutter_road_test/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | void main() => runApp(MyApp());
4 |
5 | class MyApp extends StatelessWidget {
6 | @override
7 | Widget build(BuildContext context) {
8 | return MaterialApp(
9 | title: 'Counter App',
10 | home: MyHomePage(title: 'Counter App Home Page'),
11 | );
12 | }
13 | }
14 |
15 | class MyHomePage extends StatefulWidget {
16 | MyHomePage({Key key, this.title}) : super(key: key);
17 |
18 | final String title;
19 |
20 | @override
21 | _MyHomePageState createState() => _MyHomePageState();
22 | }
23 |
24 | class _MyHomePageState extends State {
25 | int _counter = 0;
26 |
27 | void _incrementCounter() {
28 | setState(() {
29 | _counter++;
30 | });
31 | }
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return Scaffold(
36 | appBar: AppBar(
37 | title: Text(widget.title),
38 | ),
39 | body: Center(
40 | child: Column(
41 | mainAxisAlignment: MainAxisAlignment.center,
42 | children: [
43 | Text(
44 | 'You have pushed the button this many times:',
45 | ),
46 | Text(
47 | '$_counter',
48 | // Provide a Key to this specific Text Widget. This allows us
49 | // to identify this specific Widget from inside our test suite and
50 | // read the text.
51 | key: Key('counter'),
52 | style: Theme.of(context).textTheme.display1,
53 | ),
54 | ],
55 | ),
56 | ),
57 | floatingActionButton: FloatingActionButton(
58 | // Provide a Key to this the button. This allows us to find this
59 | // specific button and tap it inside the test suite.
60 | key: Key('increment'),
61 | onPressed: _incrementCounter,
62 | tooltip: 'Increment',
63 | child: Icon(Icons.add),
64 | ),
65 | );
66 | }
67 | }
--------------------------------------------------------------------------------
/flutter_road_test/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_road_test
2 | description: A new Flutter application.
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 | test: any
21 | flutter:
22 | sdk: flutter
23 |
24 | # The following adds the Cupertino Icons font to your application.
25 | # Use with the CupertinoIcons class for iOS style icons.
26 | cupertino_icons: ^0.1.2
27 |
28 | dev_dependencies:
29 | flutter_test:
30 | sdk: flutter
31 | flutter_driver:
32 | sdk: flutter
33 | test: any
34 |
35 |
36 | # For information on the generic Dart part of this file, see the
37 | # following page: https://www.dartlang.org/tools/pub/pubspec
38 |
39 | # The following section is specific to Flutter.
40 | flutter:
41 |
42 | # The following line ensures that the Material Icons font is
43 | # included with your application, so that you can use the icons in
44 | # the material Icons class.
45 | uses-material-design: true
46 |
47 | # To add assets to your application, add an assets section, like this:
48 | # assets:
49 | # - images/a_dot_burr.jpeg
50 | # - images/a_dot_ham.jpeg
51 |
52 | # An image asset can refer to one or more resolution-specific "variants", see
53 | # https://flutter.io/assets-and-images/#resolution-aware.
54 |
55 | # For details regarding adding assets from package dependencies, see
56 | # https://flutter.io/assets-and-images/#from-packages
57 |
58 | # To add custom fonts to your application, add a fonts section here,
59 | # in this "flutter" section. Each entry in this list should have a
60 | # "family" key with the font family name, and a "fonts" key with a
61 | # list giving the asset and other descriptors for the font. For
62 | # example:
63 | # fonts:
64 | # - family: Schyler
65 | # fonts:
66 | # - asset: fonts/Schyler-Regular.ttf
67 | # - asset: fonts/Schyler-Italic.ttf
68 | # style: italic
69 | # - family: Trajan Pro
70 | # fonts:
71 | # - asset: fonts/TrajanPro.ttf
72 | # - asset: fonts/TrajanPro_Bold.ttf
73 | # weight: 700
74 | #
75 | # For details regarding fonts from package dependencies,
76 | # see https://flutter.io/custom-fonts/#from-packages
77 |
--------------------------------------------------------------------------------
/flutter_road_test/test/counter_test.dart:
--------------------------------------------------------------------------------
1 | // Import the test package and Counter class
2 | import 'package:test/test.dart';
3 | import 'package:flutter_road_test/counter.dart';
4 |
5 | void main() {
6 | test('Counter value should be incremented', () {
7 | final counter = Counter();
8 |
9 | counter.increment();
10 |
11 | expect(counter.value, 1);
12 | });
13 | }
--------------------------------------------------------------------------------
/flutter_road_test/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 |
4 | void main() {
5 | // Define a test. The TestWidgets function will also provide a WidgetTester
6 | // for us to work with. The WidgetTester will allow us to build and interact
7 | // with Widgets in the test environment.
8 | testWidgets('MyWidget has a title and message', (WidgetTester tester) async {
9 | // Create the Widget tell the tester to build it
10 | await tester.pumpWidget(MyWidget(title: 'T', message: 'M'));
11 |
12 | // Create our Finders
13 | final titleFinder = find.text('T');
14 | final messageFinder = find.text('M');
15 |
16 | // Use the `findsOneWidget` matcher provided by flutter_test to verify our
17 | // Text Widgets appear exactly once in the Widget tree
18 | expect(titleFinder, findsOneWidget);
19 | expect(messageFinder, findsOneWidget);
20 | });
21 | }
22 |
23 | class MyWidget extends StatelessWidget {
24 | final String title;
25 | final String message;
26 |
27 | const MyWidget({
28 | Key key,
29 | @required this.title,
30 | @required this.message,
31 | }) : super(key: key);
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | return MaterialApp(
36 | title: 'Flutter Demo',
37 | home: Scaffold(
38 | appBar: AppBar(
39 | title: Text(title),
40 | ),
41 | body: Center(
42 | child: Text(message),
43 | ),
44 | ),
45 | );
46 | }
47 | }
--------------------------------------------------------------------------------
/flutter_road_test/test_driver/app.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_driver/driver_extension.dart';
2 | import 'package:flutter_road_test/main.dart' as app;
3 |
4 | void main() {
5 | // This line enables the extension
6 | enableFlutterDriverExtension();
7 |
8 | // Call the `main()` function of your app or call `runApp` with any widget you
9 | // are interested in testing.
10 | app.main();
11 | }
--------------------------------------------------------------------------------
/flutter_road_test/test_driver/app_test.dart:
--------------------------------------------------------------------------------
1 | // Imports the Flutter Driver API
2 | import 'package:flutter_driver/flutter_driver.dart';
3 | import 'package:test/test.dart';
4 |
5 | void main() {
6 | group('Counter App', () {
7 | // 通过 Finders 找到对应的 Widgets
8 | final counterTextFinder = find.byValueKey('counter');
9 | final buttonFinder = find.byValueKey('increment');
10 |
11 | FlutterDriver driver;
12 |
13 | // 连接 Flutter driver
14 | setUpAll(() async {
15 | driver = await FlutterDriver.connect();
16 | });
17 |
18 | // 当测试完成断开连接
19 | tearDownAll(() async {
20 | if (driver != null) {
21 | driver.close();
22 | }
23 | });
24 |
25 | test('starts at 0', () async {
26 | // 用 `driver.getText` 来判断 counter 初始化是 0
27 | expect(await driver.getText(counterTextFinder), "0");
28 | });
29 |
30 | test('increments the counter', () async {
31 | // 首先,点击按钮
32 | await driver.tap(buttonFinder);
33 |
34 | // 然后,判断是否增加了 1
35 | expect(await driver.getText(counterTextFinder), "1");
36 | });
37 | });
38 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.lock
4 | *.log
5 | *.pyc
6 | *.swp
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # Visual Studio Code related
20 | .vscode/
21 |
22 | # Flutter/Dart/Pub related
23 | **/doc/api/
24 | .dart_tool/
25 | .flutter-plugins
26 | .packages
27 | .pub-cache/
28 | .pub/
29 | build/
30 |
31 | # Android related
32 | **/android/**/gradle-wrapper.jar
33 | **/android/.gradle
34 | **/android/captures/
35 | **/android/gradlew
36 | **/android/gradlew.bat
37 | **/android/local.properties
38 | **/android/**/GeneratedPluginRegistrant.java
39 |
40 | # iOS/XCode related
41 | **/ios/**/*.mode1v3
42 | **/ios/**/*.mode2v3
43 | **/ios/**/*.moved-aside
44 | **/ios/**/*.pbxuser
45 | **/ios/**/*.perspectivev3
46 | **/ios/**/*sync/
47 | **/ios/**/.sconsign.dblite
48 | **/ios/**/.tags*
49 | **/ios/**/.vagrant/
50 | **/ios/**/DerivedData/
51 | **/ios/**/Icon?
52 | **/ios/**/Pods/
53 | **/ios/**/.symlinks/
54 | **/ios/**/profile
55 | **/ios/**/xcuserdata
56 | **/ios/.generated/
57 | **/ios/Flutter/App.framework
58 | **/ios/Flutter/Flutter.framework
59 | **/ios/Flutter/Generated.xcconfig
60 | **/ios/Flutter/app.flx
61 | **/ios/Flutter/app.zip
62 | **/ios/Flutter/flutter_assets/
63 | **/ios/ServiceDefinitions.json
64 | **/ios/Runner/GeneratedPluginRegistrant.*
65 |
66 | # Exceptions to above rules.
67 | !**/ios/**/default.mode1v3
68 | !**/ios/**/default.mode2v3
69 | !**/ios/**/default.pbxuser
70 | !**/ios/**/default.perspectivev3
71 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
72 |
--------------------------------------------------------------------------------
/flutter_road_widgets/.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: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
8 | channel: beta
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/flutter_road_widgets/README.md:
--------------------------------------------------------------------------------
1 | ## Flutter Widgets
2 | > 实验一些常用的 Widgets
3 |
4 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 27
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.draftbk.flutterroadwidgets"
37 | minSdkVersion 16
38 | targetSdkVersion 27
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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
15 |
19 |
26 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/java/com/draftbk/flutterroadwidgets/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.draftbk.flutterroadwidgets;
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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_road_widgets/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/images/flutter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/images/flutter.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 packages 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 | post_install do |installer|
64 | installer.pods_project.targets.each do |target|
65 | target.build_configurations.each do |config|
66 | config.build_settings['ENABLE_BITCODE'] = 'NO'
67 | end
68 | end
69 | end
70 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/draftbk/flutter_road/a905158a32eaff5ad021304ecdfbbfc199411f62/flutter_road_widgets/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/flutter_road_widgets/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.
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_road_widgets
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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day1.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 1
3 | * Text
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 |
11 |
12 | class Day1 extends StatefulWidget {
13 | @override
14 | createState() => Day1State();
15 | }
16 |
17 | class Day1State extends State {
18 | var _tapText = '文字点击事件, 点我!';
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 |
23 | Widget textSection = Container(
24 | padding: const EdgeInsets.all(15.0),
25 | color: Colors.white,
26 | child: Column(
27 | children: [
28 | Text('默认的Test'),
29 | //设置字体大小
30 | Padding(
31 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
32 | child: Text(
33 | '设置字体大小',
34 | style: TextStyle(
35 | fontSize: 20,
36 | ),
37 | ),
38 | ),
39 | //设置字体颜色
40 | Padding(
41 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
42 | child: Text(
43 | '设置字体颜色',
44 | style: TextStyle(
45 | color: const Color(0xFFFF856C),
46 | ),
47 | ),
48 | ),
49 | //设置粗体
50 | Padding(
51 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
52 | child: Text(
53 | '设置粗细和斜体',
54 | style: TextStyle(
55 | //字体粗细,粗体和正常
56 | fontWeight: FontWeight.bold,
57 | ),
58 | ),
59 | ),
60 | //设置斜体
61 | Padding(
62 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
63 | child: Text(
64 | '设置粗细和斜体',
65 | style: TextStyle(
66 | //文字样式,斜体和正常
67 | fontStyle: FontStyle.italic,
68 | ),
69 | ),
70 | ),
71 | //自动换行
72 | Padding(
73 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
74 | child: Text(
75 | '超出屏幕后设置自动换行,来,大声喊:啊啊啊啊啊啊啊啊啊啊啊啊啊啊',
76 | softWrap: true,
77 | ),
78 | ),
79 | //文字超出屏幕之后的处理方式 TextOverflow.clip剪裁 TextOverflow.fade 渐隐 TextOverflow.ellipsis省略号
80 | Padding(
81 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
82 | child: Text(
83 | '超出屏幕后设置用省略号,来,大声喊:啊啊啊啊啊啊啊啊啊啊啊啊啊啊',
84 | overflow: TextOverflow.ellipsis,
85 | ),
86 | ),
87 |
88 | //TextAlign.left左对齐,TextAlign.right右对齐,TextAlign.center居中对齐,TextAlign.justfy两端对齐
89 | Padding(
90 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
91 |
92 | child: Text(
93 | '文本居中',
94 | textAlign: TextAlign.center,
95 | ),
96 | ),
97 |
98 | Padding(
99 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
100 | child: Text(
101 | '给文字加下划线',
102 | style: TextStyle(
103 | //none无文字装饰,lineThrough删除线,overline文字上面显示线,underline文字下面显示线
104 | decoration: TextDecoration.underline,
105 | decorationColor: Colors.red,
106 | decorationStyle: TextDecorationStyle.wavy
107 | ),
108 | ),
109 | ),
110 | Padding(
111 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
112 | child: Text(
113 | '文字实现划去效果',
114 | style: TextStyle(
115 | //none无文字装饰,lineThrough删除线,overline文字上面显示线,underline文字下面显示线
116 | decoration: TextDecoration.lineThrough,
117 | decorationColor: Colors.black,
118 | decorationStyle: TextDecorationStyle.solid
119 | ),
120 | ),
121 | ),
122 | //单词间隙设置
123 | Padding(
124 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
125 | child: Text(
126 | '单词间隙设置 hello world',
127 | style: TextStyle(
128 | wordSpacing: 10.0,
129 | ),
130 | ),
131 | ),
132 | //字母间隙设置
133 | Padding(
134 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
135 | child: Text(
136 | '字母间隙设置 hello world',
137 | style: TextStyle(
138 | letterSpacing: 10.0,
139 | ),
140 | ),
141 | ),
142 | // 文本点击
143 | Padding(
144 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
145 | child: GestureDetector(
146 | onTap: () {
147 | setState(() {
148 | if(_tapText=="啊我被点到了"){
149 | _tapText="文字点击事件, 点我!";
150 | }else{
151 | _tapText="啊我被点到了";
152 | }
153 | });
154 | },
155 | child: Text(
156 | _tapText,
157 | style: TextStyle(
158 | fontSize: 16,
159 | fontWeight: FontWeight.bold,
160 | ),
161 | ),
162 | ),
163 | ),
164 |
165 | // 文本拼接
166 | Padding(
167 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
168 | child: Text.rich(
169 | new TextSpan(
170 | text: '文字拼接: ',
171 | style: new TextStyle(
172 | color: Colors.black,
173 | fontSize: 14,
174 | decoration: TextDecoration.none),
175 | children: [
176 | new TextSpan(
177 | text: "文字一",
178 | style: new TextStyle(
179 | color: Colors.blue,
180 | fontSize: 20,
181 | decoration: TextDecoration.none)),
182 | new TextSpan(
183 | text: "文字二",
184 | style: new TextStyle(
185 | color: Colors.green,
186 | fontSize: 14,
187 | decoration: TextDecoration.none)),
188 | new TextSpan(
189 | text: "文字三",
190 | style: new TextStyle(
191 | color: Colors.red,
192 | fontSize: 18,
193 | decoration: TextDecoration.none)),
194 | ]),
195 | ),
196 | )
197 | ],
198 | ),
199 | );
200 |
201 | return Scaffold(
202 | backgroundColor: Colors.grey[200],
203 | appBar: CupertinoNavigationBar(
204 | middle: Text('Text'),
205 | ),
206 | body: textSection,
207 |
208 | );
209 | }
210 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day10.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 10
3 | * Async
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 |
11 |
12 |
13 |
14 |
15 | class Day10 extends StatefulWidget {
16 | @override
17 | createState() => Day10State();
18 | }
19 |
20 |
21 | class Day10State extends State {
22 | String mytext="Console";
23 |
24 | void thenCatch(){
25 | mytext="Started";
26 | setMyTextState(mytext);
27 | // then 用来说明 1 second 后做什么
28 | Future.delayed(Duration(seconds: 1)).then((_){
29 | // 当运行完成
30 | mytext = mytext + "\n" + "Completed Task1";
31 | setMyTextState(mytext);
32 | }).catchError((e){
33 | // 当运行失败
34 | mytext=mytext+"\n"+'failed: ${e.toString()}';
35 | setMyTextState(mytext);
36 | });
37 | }
38 |
39 | void setMyTextState(String newText){
40 | setState(() {
41 | mytext=newText;
42 | });
43 | }
44 |
45 | Future asyncAwait() async{
46 | mytext="Started";
47 | setMyTextState(mytext);
48 | try{
49 | // 这里没有 .then, 要加 await, await 是说在 await 完成前别往下执行
50 | await Future.delayed(Duration(seconds: 1));
51 | mytext=mytext+"\n"+"Completed Task1";
52 | setMyTextState(mytext);
53 | await Future.delayed(Duration(seconds: 1));
54 | mytext=mytext+"\n"+"Completed Task2";
55 | setMyTextState(mytext);
56 | }catch(e){
57 | print('failed: ${e.toString()}');
58 | }
59 | }
60 |
61 | Future asyncNoAwait() async{
62 | mytext="Started";
63 | setMyTextState(mytext);
64 | try{
65 | // 这里没有 .then, 要加 await, await 是说在 await 完成前别往下执行
66 | Future.delayed(Duration(seconds: 2));
67 | mytext=mytext+"\n"+"Completed Task1";
68 | setMyTextState(mytext);
69 | Future.delayed(Duration(seconds: 1));
70 | mytext=mytext+"\n"+"Completed Task2";
71 | setMyTextState(mytext);
72 | }catch(e){
73 | print('failed: ${e.toString()}');
74 | }
75 | }
76 |
77 | Future asyncAwaitWithTask() async{
78 | mytext="Started";
79 | setMyTextState(mytext);
80 | try{
81 | // 这里没有 .then, 要加 await, await 是说在 await 完成前别往下执行
82 | await Future.delayed(Duration(seconds: 1));
83 | mytext=mytext+"\n"+"Completed Task1";
84 | setMyTextState(mytext);
85 | task2();
86 | mytext=mytext+"\n"+"Completed Task3";
87 | setMyTextState(mytext);
88 | mytext=mytext+"\n"+"Completed Task4";
89 | setMyTextState(mytext);
90 | }catch(e){
91 | print('failed: ${e.toString()}');
92 | }
93 | }
94 |
95 | void task2() async{
96 | await Future.delayed(Duration(seconds: 1));
97 | mytext=mytext+"\n"+"Completed Task2";
98 | setMyTextState(mytext);
99 | }
100 |
101 |
102 | @override
103 | Widget build(BuildContext context) {
104 |
105 | Widget asyncSection = Container(
106 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
107 | height: 400.0,
108 | child: new Center(
109 | child: new Column(
110 | mainAxisAlignment: MainAxisAlignment.center,
111 | children: [
112 | new RaisedButton(
113 | onPressed: thenCatch,
114 | child: new Text('Future.Then'),
115 | color: Color(0xFFe16552),
116 | ),
117 | new RaisedButton(
118 | onPressed: asyncNoAwait,
119 | child: new Text('Async no await'),
120 | color: Color(0xFFe16552),
121 | ),
122 | new RaisedButton(
123 | onPressed: asyncAwait,
124 | child: new Text('Async await'),
125 | color: Color(0xFFe16552),
126 | ),
127 | new RaisedButton(
128 | onPressed: asyncAwaitWithTask,
129 | child: new Text('Wait With Other Task'),
130 | color: Color(0xFFe16552),
131 | ),
132 | ],
133 | ),
134 | ),
135 | );
136 | Widget consoleSection = Container(
137 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
138 | height: 300.0,
139 | width: double.infinity,
140 | child: Text(
141 | mytext,
142 | style: TextStyle(
143 | fontSize: 18,
144 | ),
145 | ),
146 |
147 | );
148 |
149 |
150 | return Scaffold(
151 | backgroundColor: Colors.grey[200],
152 | appBar: CupertinoNavigationBar(
153 | middle: Text('Async'),
154 | ),
155 | body: Column(
156 | children:[
157 | asyncSection,
158 | new Container(
159 | color: Color(0xFFe16552),
160 | height: 2,
161 | width: double.infinity,
162 | ),
163 | consoleSection,
164 | ]
165 | )
166 | );
167 | }
168 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day11.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 11
3 | * Network
4 | */
5 |
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter/cupertino.dart';
8 | import 'dart:core';
9 |
10 | // for HttpClient
11 | import 'dart:convert';
12 | import 'dart:io';
13 |
14 | // for http
15 | import 'package:http/http.dart' as http;
16 |
17 | // for dio
18 | import 'package:dio/dio.dart';
19 |
20 | class Day11 extends StatefulWidget {
21 | @override
22 | createState() => Day11State();
23 | }
24 |
25 | class Day11State extends State {
26 | String mytext = "Console";
27 | double buttonWidth = 200;
28 | String getUrl="https://httpbin.org/ip";
29 | String postUrl="http://ip.taobao.com/service/getIpInfo.php";
30 | String searchIp='117.89.35.58';
31 | void setMyTextState(String newText) {
32 | setState(() {
33 | mytext = newText;
34 | });
35 | }
36 |
37 | void HttpClient_Get() async {
38 | mytext = "HttpClient GET Start";
39 | setMyTextState(mytext);
40 | var httpClient = new HttpClient();
41 | String result;
42 | try {
43 | var request = await httpClient.getUrl(Uri.parse(getUrl));
44 | var response = await request.close();
45 | if (response.statusCode == HttpStatus.OK) {
46 | result = await response.transform(utf8.decoder).join();
47 | } else {
48 | result =
49 | 'Error getting IP address:\nHttp status ${response.statusCode}';
50 | }
51 | } catch (exception) {
52 | result = 'Failed getting IP address';
53 | }
54 | mytext = mytext + "\n" + result;
55 | setMyTextState(mytext);
56 | }
57 | // void HttpClient_Post() async {
58 | // mytext = "HttpClient POST Start";
59 | // setMyTextState(mytext);
60 | // var httpClient = new HttpClient();
61 | // String result;
62 | // try {
63 | // Uri uri=new Uri(path:postUrl,queryParameters: {"ip": searchIp} );
64 | // print(uri.toString());
65 | // var request = await httpClient.postUrl(uri);
66 | // var response = await request.close();
67 | // if (response.statusCode == HttpStatus.OK) {
68 | // var my_json = await response.transform(utf8.decoder).join();
69 | // result = my_json.toString();
70 | // } else {
71 | // result =
72 | // 'Error getting IP address:\nHttp status ${response.statusCode}';
73 | // }
74 | // } catch (exception) {
75 | // result = 'Failed getting IP address';
76 | // }
77 | // mytext = mytext + "\n" + result;
78 | // }
79 |
80 |
81 |
82 | void http_Get() async {
83 | mytext = "http GET Start";
84 | setMyTextState(mytext);
85 | String result;
86 | try {
87 | var response = await http.get(getUrl);
88 | if (response.statusCode == HttpStatus.OK) {
89 | result = response.body;
90 | } else {
91 | result =
92 | 'Error getting IP address:\nHttp status ${response.statusCode}';
93 | }
94 | } catch (exception) {
95 | result = 'Failed getting IP address';
96 | }
97 | mytext = mytext + "\n" + result;
98 | setMyTextState(mytext);
99 | }
100 |
101 | void http_Post() async {
102 | mytext = "http POST Start";
103 | setMyTextState(mytext);
104 | String result;
105 | try {
106 |
107 | var client = http.Client();
108 | var response = await client.post(postUrl, body: {"ip": searchIp});
109 |
110 | if (response.statusCode == HttpStatus.OK) {
111 | result = response.body;
112 | } else {
113 | result =
114 | 'Error getting reslut:\nHttp status ${response.statusCode}';
115 | }
116 | } catch (exception) {
117 | result = 'Failed getting reslut';
118 | }
119 | mytext = mytext + "\n" + result;
120 | setMyTextState(mytext);
121 | }
122 |
123 | void dio_Get() async {
124 | mytext = "dio GET Start";
125 | setMyTextState(mytext);
126 | String result;
127 | try {
128 | Dio dio = new Dio();
129 | var response = await dio.get(getUrl);
130 | if (response.statusCode == HttpStatus.OK) {
131 | result = response.data.toString();
132 | } else {
133 | result =
134 | 'Error getting IP address:\nHttp status ${response.statusCode}';
135 | }
136 | } catch (exception) {
137 | result = 'Failed getting IP address';
138 | }
139 | mytext = mytext + "\n" + result;
140 | setMyTextState(mytext);
141 | }
142 |
143 | void dio_Post() async {
144 | mytext = "dio POST Start";
145 | setMyTextState(mytext);
146 | String result="";
147 | try {
148 | var dio = new Dio();
149 | var response = await dio.post(postUrl, queryParameters:{"ip": searchIp});
150 | if (response.statusCode == HttpStatus.OK) {
151 | result = response.data.toString();
152 | } else {
153 | result =
154 | 'Error getting reslut:\nHttp status ${response.statusCode}';
155 | }
156 | } catch (exception) {
157 | result = 'Failed getting reslut';
158 | }
159 | mytext = mytext + "\n" + result;
160 | setMyTextState(mytext);
161 | }
162 |
163 | void Json_Parser()async {
164 | mytext="JSON Parser Start";
165 | setMyTextState(mytext);
166 | var httpClient = new HttpClient();
167 | String result;
168 | try {
169 | var request = await httpClient.getUrl(Uri.parse(getUrl));
170 | var response = await request.close();
171 | if (response.statusCode == HttpStatus.OK) {
172 | result = await response.transform(utf8.decoder).join();
173 | var data = json.decode(result);
174 | result = data['origin'];
175 | } else {
176 | result =
177 | 'Error getting IP address:\nHttp status ${response.statusCode}';
178 | }
179 | } catch (exception) {
180 | result = 'Failed getting IP address';
181 | }
182 | mytext = mytext + "\n" + result;
183 | setMyTextState(mytext);
184 | }
185 |
186 |
187 | @override
188 | Widget build(BuildContext context) {
189 | Widget asyncSection = Container(
190 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
191 | height: 400.0,
192 | child: new Center(
193 | child: new Column(
194 | mainAxisAlignment: MainAxisAlignment.center,
195 | children: [
196 | new ButtonTheme(
197 | minWidth: buttonWidth,
198 | child: RaisedButton(
199 | onPressed: HttpClient_Get,
200 | child: new Text('HttpClient GET'),
201 | color: Color(0xFFe16552),
202 | ),
203 | ),
204 | new ButtonTheme(
205 | minWidth: buttonWidth,
206 | child: RaisedButton(
207 | onPressed: http_Get,
208 | child: new Text('http GET'),
209 | color: Color(0xFFe16552),
210 | ),
211 | ),
212 | new ButtonTheme(
213 | minWidth: buttonWidth,
214 | child: RaisedButton(
215 | onPressed: http_Post,
216 | child: new Text('http POST'),
217 | color: Color(0xFFe16552),
218 | ),
219 | ),
220 | new ButtonTheme(
221 | minWidth: buttonWidth,
222 | child: RaisedButton(
223 | onPressed: dio_Get,
224 | child: new Text('dio GET'),
225 | color: Color(0xFFe16552),
226 | ),
227 | ),
228 | new ButtonTheme(
229 | minWidth: buttonWidth,
230 | child: RaisedButton(
231 | onPressed: dio_Post,
232 | child: new Text('dio POST'),
233 | color: Color(0xFFe16552),
234 | ),
235 | ),
236 | new ButtonTheme(
237 | minWidth: buttonWidth,
238 | child: RaisedButton(
239 | onPressed: Json_Parser,
240 | child: new Text('JSON Parser'),
241 | color: Color(0xFFe16552),
242 | ),
243 | ),
244 | ],
245 | ),
246 | ),
247 | );
248 | Widget consoleSection = Container(
249 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
250 | height: 300.0,
251 | width: double.infinity,
252 | child: Text(
253 | mytext,
254 | style: TextStyle(
255 | fontSize: 18,
256 | ),
257 | ),
258 | );
259 |
260 | return Scaffold(
261 | backgroundColor: Colors.grey[200],
262 | appBar: CupertinoNavigationBar(
263 | middle: Text('Network'),
264 | ),
265 | body: Column(children: [
266 | asyncSection,
267 | new Container(
268 | color: Color(0xFFe16552),
269 | height: 2,
270 | width: double.infinity,
271 | ),
272 | consoleSection,
273 | ]));
274 | }
275 | }
276 |
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day12.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/gestures.dart';
2 | /**
3 | * Day 12
4 | * Test
5 | */
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'package:url_launcher/url_launcher.dart';
10 | import 'dart:core';
11 |
12 |
13 |
14 |
15 | class Day12 extends StatefulWidget {
16 | @override
17 | createState() => Day12State();
18 | }
19 |
20 | class Day12State extends State {
21 |
22 |
23 | void setMyTextState(String newText) {
24 | setState(() {
25 | });
26 | }
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | @override
35 | Widget build(BuildContext context) {
36 | Widget asyncSection = Container(
37 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
38 | height: 400.0,
39 | child: new Center(
40 | child: new RichText(
41 | text: new TextSpan(
42 | children: [
43 | new TextSpan(
44 | text: '测试的项目不适合写在这个项目里,可以查看我写的blog(里面也有代码链接): \n',
45 | style: new TextStyle(color: Colors.black,fontSize: 22),
46 | ),
47 | new TextSpan(
48 | text: 'https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Tests.md\n',
49 | style: new TextStyle(color: Colors.blue,fontSize: 22),
50 | recognizer: new TapGestureRecognizer()
51 | ..onTap = () { launch('https://github.com/draftbk/flutter_road/blob/master/notes/Flutter_Tests.md');
52 | },
53 | ),
54 | new TextSpan(
55 | text: '希望对你有帮助<( ̄︶ ̄)>',
56 | style: new TextStyle(color: Colors.black,fontSize: 22),
57 | ),
58 | ],
59 | ),
60 | ),
61 | ),
62 | );
63 |
64 | return Scaffold(
65 | backgroundColor: Colors.grey[200],
66 | appBar: CupertinoNavigationBar(
67 | middle: Text('Testing'),
68 | ),
69 | body: Column(children: [
70 | asyncSection,
71 | ]));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day2.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 2
3 | * Button
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 |
11 |
12 | class Day2 extends StatefulWidget {
13 | @override
14 | createState() => Day2State();
15 | }
16 |
17 | class Day2State extends State {
18 | var mCurrentValue = 1.0;
19 | var isChecked=false;
20 | int groupValue1,groupValue2;
21 | @override
22 | Widget build(BuildContext context) {
23 |
24 | Widget buttonSection = Container(
25 | padding: const EdgeInsets.all(15.0),
26 | color: Colors.white,
27 | child: Column(
28 | children: [
29 | // RaisedButton
30 | Padding(
31 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
32 | child: new RaisedButton(
33 | onPressed: () {print('button click');},
34 | child: new Text("RaisedButton"),
35 | ),
36 | ),
37 | // FlatButton
38 | Padding(
39 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
40 | child: new FlatButton(
41 | onPressed: () {print('button click');},
42 | child: new Text("FlatButton"),
43 | color: Color(0xFFe16552),
44 | ),
45 | ),
46 |
47 | //FloatingActionButton 多个FloatingActionButton的时候会报错,要加 heroTag: null
48 | Padding(
49 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
50 | child: Row(
51 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
52 | children: [
53 | // FloatingActionButton
54 | new FloatingActionButton(
55 | onPressed: () {print('button click');},
56 | foregroundColor: Colors.white,
57 | backgroundColor: Color(0xFFf19670),
58 | child: new Icon(Icons.add),
59 | heroTag: null,
60 | ),
61 | // FloatingActionButton
62 | new FloatingActionButton(
63 | onPressed: () {print('button click');},
64 | foregroundColor: Colors.white,
65 | backgroundColor: Color(0xFFf19670),
66 | child: new Text("文字"),
67 | heroTag: null,
68 | ),
69 | ],
70 | ),
71 | ),
72 |
73 | // FloatingActionButton.extended
74 | Padding(
75 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
76 | child: new FloatingActionButton.extended(
77 | onPressed: () {
78 | print('button click');
79 | },
80 | foregroundColor: Colors.white,
81 | backgroundColor: Colors.amber,
82 | icon: new Icon(Icons.flag,color: Colors.red,),
83 | label: new Text('FloatingActionButton.extended', maxLines: 1),
84 | )
85 | ),
86 |
87 | // Slider
88 | Padding(
89 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
90 | child: new Slider(
91 | value: mCurrentValue,
92 | min: 1.0,
93 | max: 10.0,
94 | onChanged: (e) {
95 | setState(() {
96 | //四舍五入的双精度值
97 | mCurrentValue = e.roundToDouble();
98 | });
99 | }
100 | )
101 | ),
102 |
103 | // Checkbox
104 | Padding(
105 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
106 | child: new Checkbox(
107 | value: isChecked,
108 | onChanged: (bool){
109 | setState(() {
110 | isChecked=bool;
111 | });
112 | }, activeColor: Colors.blue,
113 | )
114 | ),
115 |
116 | // Radio
117 | Padding(
118 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
119 | child: new ButtonBar(//ButtonBar:水平排列按钮
120 | alignment: MainAxisAlignment.center,
121 | children: [
122 | //value和groupValue值一样的话,则按钮选中
123 | new Radio(value: 1,
124 | groupValue: groupValue1,
125 | onChanged: (int e) => updateGroupValue(e)),
126 | new Radio(value: 2,
127 | groupValue: groupValue1,
128 | onChanged: (int e) => updateGroupValue(e)),
129 | new Radio(value: 3,
130 | groupValue: groupValue1,
131 | onChanged: (int e) => updateGroupValue(e)),
132 | new Radio(value: 4,
133 | groupValue: groupValue1,
134 | onChanged: (int e) => updateGroupValue(e)),
135 | //value 值为 null 则表示按钮不可用
136 | new Radio(value: null, groupValue: null, onChanged: null)
137 | ],
138 | )
139 | ),
140 |
141 | // Radio
142 | Padding(
143 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
144 | child: new Column(//ButtonBar:水平排列按钮
145 | children: [
146 | //value和groupValue值一样的话,则按钮选中
147 | new RadioListTile(
148 | title: const Text('A'),
149 | value: 1,
150 | activeColor: Colors.red,
151 | groupValue: groupValue2,
152 | onChanged: (int e)=>updateGroupValue2(e),
153 | ),
154 | new RadioListTile(
155 | title: const Text('B'),
156 | value: 2,
157 | activeColor: Colors.yellow,
158 | groupValue: groupValue2,
159 | onChanged: (int e)=>updateGroupValue2(e),
160 | ),
161 | new RadioListTile(
162 | title: const Text('C'),
163 | value: 3,
164 | activeColor: Colors.green,
165 | groupValue: groupValue2,
166 | onChanged: (int e)=>updateGroupValue2(e),
167 | ),
168 | ],
169 | )
170 | ),
171 | ],
172 | ),
173 | );
174 |
175 | return Scaffold(
176 | backgroundColor: Colors.grey[200],
177 | appBar: CupertinoNavigationBar(
178 | middle: Text('Button'),
179 | ),
180 | body: buttonSection,
181 |
182 | );
183 | }
184 | ///更新 groupValue1, 当Radio的value==groupValue 时候,则按钮被选中
185 | void updateGroupValue(int e){
186 | setState(() {
187 | groupValue1=e;
188 | });
189 | }
190 | ///更新 groupValue2, 当Radio的value==groupValue 时候,则按钮被选中
191 | void updateGroupValue2(int e){
192 | setState(() {
193 | groupValue2=e;
194 | });
195 | }
196 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day3.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 3
3 | * Image
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'package:cached_network_image/cached_network_image.dart';
10 | import 'package:transparent_image/transparent_image.dart';
11 | import 'dart:core';
12 |
13 |
14 |
15 |
16 | class Day3 extends StatefulWidget {
17 | @override
18 | createState() => Day3State();
19 | }
20 |
21 | class Day3State extends State {
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 |
26 | Widget imageSection = Container(
27 | padding: const EdgeInsets.all(15.0),
28 | width: 1000,
29 | color: Colors.white,
30 | child: Column(
31 | children: [
32 | // Image from internet
33 | Padding(
34 | padding: const EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0),
35 | child: new Image(
36 | image:new AssetImage('images/flutter.png'),
37 | width: 50,
38 | height: 50,
39 | ),
40 | ),
41 | // Image from asserts
42 | Padding(
43 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
44 | child: Image.network(
45 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/picture/day3/flutter.png?raw=true',
46 | scale: 4,
47 | ),
48 | ),
49 | // Gif from internet
50 | Padding(
51 | padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
52 | child:Image.network(
53 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/gif/day3/google.gif?raw=true',
54 | scale: 4,
55 | ),
56 | ),
57 |
58 | // FadeInImage
59 | Padding(
60 | padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
61 | child: FadeInImage.memoryNetwork(
62 | width: 180,
63 | height: 180,
64 | placeholder: kTransparentImage,
65 | image: 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/picture/day3/flutter.png?raw=true',
66 | ),
67 | ),
68 |
69 | // CachedNetworkImage
70 | Padding(
71 | padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
72 | child: CachedNetworkImage(
73 | width: 100,
74 | height: 100,
75 | // placeholder: CircularProgressIndicator(), // 一开始能用,后来可能CachedNetworkImage没有 placeholder了就先注释掉
76 | imageUrl:
77 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/picture/day3/flutter.png?raw=true',
78 | ),
79 | ),
80 |
81 |
82 |
83 | ],
84 | ),
85 | );
86 |
87 | return Scaffold(
88 | backgroundColor: Colors.grey[200],
89 | appBar: CupertinoNavigationBar(
90 | middle: Text('Image'),
91 | ),
92 | body: imageSection,
93 |
94 | );
95 | }
96 |
97 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day4.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 4
3 | * ListView
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 |
11 |
12 |
13 |
14 | class Day4 extends StatefulWidget {
15 | @override
16 | createState() => Day4State();
17 | }
18 |
19 |
20 | class Day4State extends State {
21 | List items=[];
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 |
26 | Widget horizontalListSection = Container(
27 | margin: EdgeInsets.symmetric(vertical: 20.0),
28 | height: 200.0,
29 | child: ListView(
30 | scrollDirection: Axis.horizontal,
31 | children: [
32 | Container(
33 | width: 160.0,
34 | color: Colors.red,
35 | ),
36 | Container(
37 | width: 160.0,
38 | color: Colors.blue,
39 | ),
40 | Container(
41 | width: 160.0,
42 | color: Colors.green,
43 | ),
44 | Container(
45 | width: 160.0,
46 | color: Colors.yellow,
47 | ),
48 | Container(
49 | width: 160.0,
50 | color: Colors.orange,
51 | ),
52 | ],
53 | ),
54 | );
55 |
56 | Widget basicListSection = Builder(
57 | builder: (context) => Container(
58 | margin: EdgeInsets.symmetric(vertical: 5.0),
59 | height: 200.0,
60 | child: ListView(
61 | children: [
62 | ListTile(
63 | leading: Icon(Icons.map),
64 | title: Text('Map'),
65 | onTap: (){
66 | _showToast(context,"Map");
67 | },
68 | ),
69 | ListTile(
70 | leading: Icon(Icons.photo_album),
71 | title: Text('Album'),
72 | onTap: (){
73 | _showToast(context,"Album");
74 | },
75 | ),
76 | ListTile(
77 | leading: Icon(Icons.phone),
78 | title: Text('Phone'),
79 | onTap: (){
80 | _showToast(context,"Phone");
81 | },
82 | ),
83 | ],
84 | )
85 | )
86 | );
87 |
88 | Widget buttonSection = Padding(
89 | padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
90 | child: new RaisedButton(
91 | onPressed: () {_addListDate();},
92 | child: new Text("Add New Item"),
93 | ),
94 | );
95 |
96 | Widget dynamicSection = Container(
97 | margin: EdgeInsets.symmetric(vertical: 5.0),
98 | height: 200.0,
99 | child: ListView.builder(
100 | itemCount: items.length,
101 | itemBuilder: (context,index){
102 | return ListTile(
103 | leading: Icon(Icons.send),
104 | title: new Text("NewItem $index"));
105 | }
106 | )
107 | );
108 |
109 |
110 |
111 | return Scaffold(
112 | backgroundColor: Colors.grey[200],
113 | appBar: CupertinoNavigationBar(
114 | middle: Text('ListView'),
115 | ),
116 | body: Column(
117 | children:[
118 | horizontalListSection,
119 | basicListSection,
120 | buttonSection,
121 | dynamicSection
122 | ]
123 | )
124 | );
125 | }
126 | void _showToast(BuildContext context,String text) {
127 | final scaffold = Scaffold.of(context);
128 | scaffold.showSnackBar(
129 | SnackBar(
130 | content: Text(text),
131 | ),
132 | );
133 | }
134 |
135 |
136 | void _addListDate(){
137 | setState(() {
138 | items.add(1);
139 | });
140 | }
141 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day5.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 5
3 | * GridView
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 |
11 |
12 |
13 |
14 | class Day5 extends StatefulWidget {
15 | @override
16 | createState() => Day5State();
17 | }
18 |
19 |
20 | class Day5State extends State {
21 |
22 | List words=["abandon","abhor","abnormal","abroad","abrupt",
23 | "absent","absorb","abstract","absurd","abundant","abuse","academy"];
24 | List translations=["放弃","厌恶","反常的","海外","突然的",
25 | "缺席的","吸收","抽象(的)","不合理的","丰富的","滥用","研究院"];
26 | Color myColor=Color(0xFFe16552);
27 | int listNumber=6;
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | Widget gridItem (BuildContext context, int _index) {
32 | int index=_index%words.length;
33 | return Container(
34 | alignment: Alignment.center,
35 | child: GestureDetector(
36 | onTap: () {
37 | setState(() {
38 | String temp=words[index];
39 | words[index]=translations[index];
40 | translations[index]=temp;
41 | });
42 | },
43 | child: Text(
44 | words[index],
45 | style: TextStyle(
46 | fontSize: 28,
47 | color: Colors.white,
48 | ),
49 | ),
50 | ),
51 | color:myColor,
52 | );
53 | }
54 |
55 | Widget gridViewSection = Builder(
56 | builder: (context) => Container(
57 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
58 | height: 500.0,
59 | child: GridView.count(
60 | // 每行有几个子控件
61 | crossAxisCount: 2,
62 | // 水平子Widget之间间距
63 | crossAxisSpacing: 10.0,
64 | // 水平子Widget之间间距
65 | mainAxisSpacing: 8.0,
66 | // 子Widget宽高比例
67 | childAspectRatio: 2.0,
68 | children: List.generate(listNumber, (index) {
69 | return gridItem(context, index);
70 | }),
71 | ),
72 | )
73 | );
74 |
75 |
76 | return Scaffold(
77 | backgroundColor: Colors.grey[200],
78 | appBar: CupertinoNavigationBar(
79 | middle: Text('GridView'),
80 | ),
81 | body: Column(
82 | children:[
83 | gridViewSection, // FloatingActionButton.extended
84 | Padding(
85 | padding: const EdgeInsets.fromLTRB(0.0, 55.0, 0.0, 0.0),
86 | child: new FloatingActionButton.extended(
87 | onPressed: () {
88 | setState(() {
89 | listNumber=listNumber+1;
90 | });
91 | },
92 | foregroundColor: Colors.white,
93 | backgroundColor: myColor,
94 | icon: new Icon(Icons.add,color: Colors.white,),
95 | label: new Text('添加新单词 ', maxLines: 1),
96 | )
97 | ),
98 |
99 | ]
100 | )
101 | );
102 | }
103 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day6.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 6
3 | * Dialog
4 | */
5 |
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter/cupertino.dart';
8 | import 'dart:core';
9 |
10 | import 'package:flutter_road_widgets/subpage/MySingleChooseDialog.dart';
11 |
12 | class Day6 extends StatefulWidget {
13 | @override
14 | createState() => Day6State();
15 | }
16 |
17 | class Day6State extends State {
18 | double buttonWidth = 200;
19 | String mytext = "Console";
20 |
21 | void setMyTextState(String newText) {
22 | setState(() {
23 | mytext = newText;
24 | });
25 | }
26 |
27 | Future _showSnackBar(BuildContext context, String text) async {
28 | final scaffold = Scaffold.of(context);
29 | scaffold.showSnackBar(
30 | SnackBar(
31 | content: Text(text),
32 | ),
33 | );
34 | }
35 |
36 | Future _showSimpleAlertDialog(String message) async {
37 | return showDialog(
38 | context: context,
39 | barrierDismissible: false, // user must tap button!
40 | builder: (BuildContext context) {
41 | return AlertDialog(
42 | title: Text('我是一个简单 Dialog'),
43 | content: SingleChildScrollView(
44 | child: ListBody(
45 | children: [
46 | Text(message),
47 | ],
48 | ),
49 | ),
50 | actions: [
51 | FlatButton(
52 | child: Text('是的'),
53 | onPressed: () {
54 | Navigator.of(context).pop();
55 | },
56 | ),
57 | ],
58 | );
59 | },
60 | );
61 | }
62 |
63 | Future _showListAlertDialog() async {
64 | return showDialog(
65 | context: context,
66 | barrierDismissible: false, // user must tap button!
67 | builder: (BuildContext context) {
68 | return AlertDialog(
69 | title: Text('我是一个列表 Dialog'),
70 | content: SingleChildScrollView(
71 | child: ListBody(
72 | children: [
73 | ListTile(
74 | leading: Icon(Icons.map),
75 | title: Text('Map'),
76 | onTap: () {
77 | setMyTextState("你点击了: Map");
78 | Navigator.of(context).pop();
79 | },
80 | ),
81 | ListTile(
82 | leading: Icon(Icons.photo_album),
83 | title: Text('Album'),
84 | onTap: () {
85 | setMyTextState("你点击了: Album");
86 | Navigator.of(context).pop();
87 | },
88 | ),
89 | ListTile(
90 | leading: Icon(Icons.phone),
91 | title: Text('Phone'),
92 | onTap: () {
93 | setMyTextState("你点击了: Phone");
94 | Navigator.of(context).pop();
95 | },
96 | ),
97 | ],
98 | ),
99 | ),
100 | actions: [
101 | FlatButton(
102 | child: Text('返回'),
103 | onPressed: () {
104 | Navigator.of(context).pop();
105 | },
106 | ),
107 | ],
108 | );
109 | },
110 | );
111 | }
112 |
113 | Future _showSingleChooseDialog() async {
114 | return showDialog(
115 | context: context,
116 | barrierDismissible: false, // user must tap button!
117 | builder: (BuildContext context) {
118 | return MySingleChooseDialog();
119 | },
120 | );
121 | }
122 |
123 | @override
124 | Widget build(BuildContext context) {
125 | Widget dialogSection = Builder(
126 | builder: (context) => Container(
127 | margin: EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 5.0),
128 | height: 400.0,
129 | child: new Center(
130 | child: Column(
131 | children: [
132 | new ButtonTheme(
133 | minWidth: buttonWidth,
134 | child: RaisedButton(
135 | onPressed: () =>
136 | _showSnackBar(context, '欢迎来到我的 Flutter 博客!'),
137 | child: new Text('底部提示框'),
138 | color: Color(0xFFe16552),
139 | ),
140 | ),
141 | new ButtonTheme(
142 | minWidth: buttonWidth,
143 | child: RaisedButton(
144 | onPressed: () => _showSimpleAlertDialog('Flutter 是不是很棒!'),
145 | child: new Text('简单 Dialog 提示框'),
146 | color: Color(0xFFe16552),
147 | ),
148 | ),
149 | new ButtonTheme(
150 | minWidth: buttonWidth,
151 | child: RaisedButton(
152 | onPressed: () => _showListAlertDialog(),
153 | child: new Text('列表 Dialog 提示框'),
154 | color: Color(0xFFe16552),
155 | ),
156 | ),
157 | new ButtonTheme(
158 | minWidth: buttonWidth,
159 | child: RaisedButton(
160 | onPressed: () => _showSingleChooseDialog(),
161 | child: new Text('单选 Dialog 提示框'),
162 | color: Color(0xFFe16552),
163 | ),
164 | ),
165 | ],
166 | ))));
167 |
168 | Widget consoleSection = Container(
169 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
170 | height: 300.0,
171 | width: double.infinity,
172 | child: Text(
173 | mytext,
174 | style: TextStyle(
175 | fontSize: 18,
176 | ),
177 | ),
178 | );
179 |
180 | return Scaffold(
181 | backgroundColor: Colors.grey[200],
182 | appBar: CupertinoNavigationBar(
183 | middle: Text('Dialog'),
184 | ),
185 | body: Column(children: [
186 | dialogSection,
187 | new Container(
188 | color: Color(0xFFe16552),
189 | height: 2,
190 | width: double.infinity,
191 | ),
192 | consoleSection,
193 | ]));
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day7.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 6
3 | * Dialog
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 | import 'package:flutter_road_widgets/subpage/TopBarPage.dart';
11 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
12 |
13 |
14 |
15 |
16 | class Day7 extends StatefulWidget {
17 | @override
18 | createState() => Day7State();
19 | }
20 |
21 |
22 |
23 | class Day7State extends State {
24 |
25 |
26 |
27 | PageController pageController;
28 | int page = 1;
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 |
33 | return new Scaffold(
34 |
35 | backgroundColor: Colors.grey[200],
36 |
37 | // 传入
38 | body: new PageView(
39 | children: [
40 | new Scaffold(
41 | backgroundColor: Colors.grey[200],
42 | appBar: CupertinoNavigationBar(middle: Text('PageLeft'),),
43 | body: new Center(child: new Text('PageLeft',style: TextStyle(fontSize: 20,),)),
44 | ),
45 | new TopBarPage(),
46 | new Scaffold(
47 | backgroundColor: Colors.grey[200],
48 | appBar: CupertinoNavigationBar(middle: Text('PageRight'),),
49 | body: new Center(child: new Text('PageRight',style: TextStyle(fontSize: 20,),)),
50 | ),
51 | ],
52 | controller: pageController,
53 | onPageChanged: onPageChanged,
54 | ),
55 |
56 | bottomNavigationBar: new BottomNavigationBar(items: [
57 | new BottomNavigationBarItem(
58 | icon: new Icon(FontAwesomeIcons.font),
59 | title: new Text("Text"),
60 | backgroundColor: Colors.grey
61 | ),
62 | new BottomNavigationBarItem(
63 | icon: new Icon(FontAwesomeIcons.handPointUp),
64 | title: new Text("Top"),
65 | backgroundColor: Colors.grey),
66 | new BottomNavigationBarItem(
67 | icon: new Icon(FontAwesomeIcons.image),
68 | title: new Text("Button"),
69 | backgroundColor: Colors.grey,
70 | ),
71 | ],
72 | onTap: onTap,
73 | currentIndex: page
74 | ),
75 | );
76 | }
77 |
78 | @override
79 | void initState() {
80 | super.initState();
81 | // 设置初始化page
82 | pageController = new PageController(initialPage: this.page);
83 | }
84 |
85 |
86 | void onTap(int index) {
87 | pageController.animateToPage(
88 | index,
89 | // 设置页面转换效果的时间
90 | duration: const Duration(milliseconds: 300),
91 | // 设置转换时的效果
92 | curve: Curves.ease);
93 | }
94 |
95 |
96 | void onPageChanged(int page) {
97 | setState(() {
98 | this.page = page;
99 | });
100 | }
101 |
102 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/days/Day8.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 1
3 | * Text
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 |
11 |
12 | class Day8 extends StatefulWidget {
13 | @override
14 | createState() => Day8State();
15 | }
16 |
17 | class Day8State extends State {
18 | var _tapText = '文字点击事件, 点我!';
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 |
23 | Widget textSection = Container(
24 | padding: const EdgeInsets.all(15.0),
25 | color: Colors.white,
26 | child: Column(
27 | children: [
28 | Text('默认的Test'),
29 | //设置字体大小
30 | Padding(
31 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
32 | child: Text(
33 | '设置字体大小',
34 | style: TextStyle(
35 | fontSize: 20,
36 | ),
37 | ),
38 | ),
39 | //设置字体颜色
40 | Padding(
41 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
42 | child: Text(
43 | '设置字体颜色',
44 | style: TextStyle(
45 | color: const Color(0xFFFF856C),
46 | ),
47 | ),
48 | ),
49 | //设置粗体
50 | Padding(
51 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
52 | child: Text(
53 | '设置粗细和斜体',
54 | style: TextStyle(
55 | //字体粗细,粗体和正常
56 | fontWeight: FontWeight.bold,
57 | ),
58 | ),
59 | ),
60 | //设置斜体
61 | Padding(
62 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
63 | child: Text(
64 | '设置粗细和斜体',
65 | style: TextStyle(
66 | //文字样式,斜体和正常
67 | fontStyle: FontStyle.italic,
68 | ),
69 | ),
70 | ),
71 | //自动换行
72 | Padding(
73 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
74 | child: Text(
75 | '超出屏幕后设置自动换行,来,大声喊:啊啊啊啊啊啊啊啊啊啊啊啊啊啊',
76 | softWrap: true,
77 | ),
78 | ),
79 | //文字超出屏幕之后的处理方式 TextOverflow.clip剪裁 TextOverflow.fade 渐隐 TextOverflow.ellipsis省略号
80 | Padding(
81 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
82 | child: Text(
83 | '超出屏幕后设置用省略号,来,大声喊:啊啊啊啊啊啊啊啊啊啊啊啊啊啊',
84 | overflow: TextOverflow.ellipsis,
85 | ),
86 | ),
87 |
88 | //TextAlign.left左对齐,TextAlign.right右对齐,TextAlign.center居中对齐,TextAlign.justfy两端对齐
89 | Padding(
90 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
91 |
92 | child: Text(
93 | '文本居中',
94 | textAlign: TextAlign.center,
95 | ),
96 | ),
97 |
98 | Padding(
99 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
100 | child: Text(
101 | '给文字加下划线',
102 | style: TextStyle(
103 | //none无文字装饰,lineThrough删除线,overline文字上面显示线,underline文字下面显示线
104 | decoration: TextDecoration.underline,
105 | decorationColor: Colors.red,
106 | decorationStyle: TextDecorationStyle.wavy
107 | ),
108 | ),
109 | ),
110 | Padding(
111 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
112 | child: Text(
113 | '文字实现划去效果',
114 | style: TextStyle(
115 | //none无文字装饰,lineThrough删除线,overline文字上面显示线,underline文字下面显示线
116 | decoration: TextDecoration.lineThrough,
117 | decorationColor: Colors.black,
118 | decorationStyle: TextDecorationStyle.solid
119 | ),
120 | ),
121 | ),
122 | //单词间隙设置
123 | Padding(
124 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
125 | child: Text(
126 | '单词间隙设置 hello world',
127 | style: TextStyle(
128 | wordSpacing: 10.0,
129 | ),
130 | ),
131 | ),
132 | //字母间隙设置
133 | Padding(
134 | padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
135 | child: Text(
136 | '字母间隙设置 hello world',
137 | style: TextStyle(
138 | letterSpacing: 10.0,
139 | ),
140 | ),
141 | ),
142 | // 文本点击
143 | Padding(
144 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
145 | child: GestureDetector(
146 | onTap: () {
147 | setState(() {
148 | if(_tapText=="啊我被点到了"){
149 | _tapText="文字点击事件, 点我!";
150 | }else{
151 | _tapText="啊我被点到了";
152 | }
153 | });
154 | },
155 | child: Text(
156 | _tapText,
157 | style: TextStyle(
158 | fontSize: 16,
159 | fontWeight: FontWeight.bold,
160 | ),
161 | ),
162 | ),
163 | ),
164 |
165 | // 文本拼接
166 | Padding(
167 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
168 | child: Text.rich(
169 | new TextSpan(
170 | text: '文字拼接: ',
171 | style: new TextStyle(
172 | color: Colors.black,
173 | fontSize: 14,
174 | decoration: TextDecoration.none),
175 | children: [
176 | new TextSpan(
177 | text: "文字一",
178 | style: new TextStyle(
179 | color: Colors.blue,
180 | fontSize: 20,
181 | decoration: TextDecoration.none)),
182 | new TextSpan(
183 | text: "文字二",
184 | style: new TextStyle(
185 | color: Colors.green,
186 | fontSize: 14,
187 | decoration: TextDecoration.none)),
188 | new TextSpan(
189 | text: "文字三",
190 | style: new TextStyle(
191 | color: Colors.red,
192 | fontSize: 18,
193 | decoration: TextDecoration.none)),
194 | ]),
195 | ),
196 | )
197 | ],
198 | ),
199 | );
200 |
201 | return Scaffold(
202 | backgroundColor: Colors.grey[200],
203 | appBar: CupertinoNavigationBar(
204 | middle: Text('Text'),
205 | ),
206 | body: textSection,
207 |
208 | );
209 | }
210 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/index.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/cupertino.dart';
3 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
4 | import 'package:flutter_road_widgets/days/Day1.dart';
5 | import 'package:flutter_road_widgets/days/Day2.dart';
6 | import 'package:flutter_road_widgets/days/Day3.dart';
7 | import 'package:flutter_road_widgets/days/Day4.dart';
8 | import 'package:flutter_road_widgets/days/Day5.dart';
9 | import 'package:flutter_road_widgets/days/Day6.dart';
10 | import 'package:flutter_road_widgets/days/Day7.dart';
11 | import 'package:flutter_road_widgets/days/Day8.dart';
12 |
13 | import 'package:flutter_road_widgets/days/Day10.dart';
14 | import 'package:flutter_road_widgets/days/Day11.dart';
15 | import 'package:flutter_road_widgets/days/Day12.dart';
16 |
17 | void main() => runApp(new IndexPage());
18 |
19 | class IndexPage extends StatelessWidget {
20 | Widget menuIcons (BuildContext context, Icon icon,String title, Widget nextPage) {
21 | return Container(
22 | decoration: BoxDecoration(
23 | border: BorderDirectional(
24 | bottom: const BorderSide(color: const Color(0xFFCCCCCC)),
25 | end: const BorderSide(color: const Color(0xFFCCCCCC)),
26 | )
27 | ),
28 | child: InkWell(
29 | onTap: (){
30 | Navigator.of(context).push(CupertinoPageRoute(
31 | builder: (BuildContext context) => nextPage,
32 | ),);
33 | },
34 | child: Center(
35 | child: new Column(
36 | mainAxisAlignment: MainAxisAlignment.center,
37 | children: [
38 | icon,
39 | Container(
40 | margin: EdgeInsets.only(top: 10.0),
41 | child: Text(
42 | title,style: TextStyle(fontSize: 16)
43 | )
44 | )
45 | ],
46 | )
47 | )
48 | )
49 | );
50 | }
51 |
52 |
53 | @override
54 | Widget build(BuildContext context) {
55 | return Scaffold(
56 | appBar: CupertinoNavigationBar(
57 | middle: const Text('Flutter Learning Road'),
58 | ),
59 | body: GridView.count(
60 | primary: false,
61 | crossAxisCount: 3,
62 | children: [
63 | menuIcons(context, Icon(FontAwesomeIcons.font, size: 50.0, color: Color(0xFFc94a53)), 'Text' ,Day1()),
64 | menuIcons(context, Icon(FontAwesomeIcons.toggleOff, size: 50.0, color: Color(0xFFe16552)), 'Button' ,Day2()),
65 | menuIcons(context, Icon(FontAwesomeIcons.image, size: 50.0, color: Color(0xFFf19670)), 'Image' ,Day3()),
66 | menuIcons(context, Icon(FontAwesomeIcons.thList, size: 50.0, color: Color(0xFFe2975d)), 'ListView' ,Day4()),
67 | menuIcons(context, Icon(FontAwesomeIcons.thLarge, size: 50.0, color: Color(0xFFe9d78e)), 'GridView' ,Day5()),
68 | menuIcons(context, Icon(FontAwesomeIcons.clone, size: 50.0, color: Color(0xFFe4bf80)), 'Dialog' ,Day6()),
69 | menuIcons(context, Icon(FontAwesomeIcons.columns, size: 50.0, color: Color(0xFFe2975d)), 'NavigationBar' ,Day7()),
70 | menuIcons(context, Icon(FontAwesomeIcons.spinner, size: 50.0, color: Color(0xFFe2975d)), 'pending' ,Day8()),
71 | menuIcons(context, Icon(FontAwesomeIcons.spinner, size: 50.0, color: Color(0xFFe2975d)), 'pending' ,Day1()),
72 | menuIcons(context, Icon(FontAwesomeIcons.exchangeAlt, size: 50.0, color: Color(0xFFe2975d)), 'Async' ,Day10()),
73 | menuIcons(context, Icon(FontAwesomeIcons.networkWired, size: 50.0, color: Color(0xFFe2975d)), 'Network' ,Day11()),
74 | menuIcons(context, Icon(FontAwesomeIcons.asterisk, size: 50.0, color: Color(0xFFe2975d)), 'Test' ,Day12()),
75 | ],
76 | ),
77 | backgroundColor: Colors.white,
78 | );
79 | }
80 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_road_widgets/index.dart';
3 |
4 | void main() => runApp(new MyApp());
5 |
6 | class MyApp extends StatelessWidget {
7 | // This widget is the root of your application.
8 |
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return new MaterialApp(
13 | // 去 dubug 水印
14 | debugShowCheckedModeBanner: false,
15 | theme: new ThemeData(
16 | primarySwatch: Colors.blue,
17 | ),
18 | home: new IndexPage()
19 | );
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/subpage/MySingleChooseDialog.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 6
3 | * TopBarPage
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 |
11 |
12 |
13 |
14 | class MySingleChooseDialog extends StatefulWidget {
15 | @override
16 | createState() => MySingleChooseDialogState();
17 | }
18 |
19 |
20 | class MySingleChooseDialogState extends State{
21 |
22 | int groupValue1;
23 |
24 | ///更新 groupValue1, RadioListTile==groupValue 时候,则按钮被选中
25 | void updateGroupValue(int e) {
26 | setState(() {
27 | groupValue1 = e;
28 | });
29 | }
30 |
31 | @override
32 | Widget build(BuildContext context) {
33 |
34 | return AlertDialog(
35 | title: Text('我是一个单选 Dialog'),
36 | content: SingleChildScrollView(
37 | child: ListBody(
38 | children: [
39 | //value和groupValue值一样的话,则按钮选中
40 | new RadioListTile(
41 | title: const Text('A'),
42 | value: 1,
43 | activeColor: Colors.red,
44 | groupValue: groupValue1,
45 | onChanged: (int e) => updateGroupValue( e),
46 | ),
47 | new RadioListTile(
48 | title: const Text('B'),
49 | value: 2,
50 | activeColor: Colors.yellow,
51 | groupValue: groupValue1,
52 | onChanged: (int e) => updateGroupValue( e),
53 | ),
54 | new RadioListTile(
55 | title: const Text('C'),
56 | value: 3,
57 | activeColor: Colors.green,
58 | groupValue: groupValue1,
59 | onChanged: (int e) => updateGroupValue(e),
60 | ),
61 | ],
62 | ),
63 | ),
64 | actions: [
65 | FlatButton(
66 | child: Text('确定'),
67 | onPressed: () {
68 | Navigator.of(context).pop();
69 | },
70 | ),
71 | ],
72 | );
73 | }
74 |
75 |
76 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/subpage/TopBarPage.dart:
--------------------------------------------------------------------------------
1 | /**
2 | * Day 6
3 | * TopBarPage
4 | */
5 |
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'dart:core';
10 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
11 |
12 |
13 |
14 |
15 | class TopBarPage extends StatefulWidget {
16 | @override
17 | createState() => TopBarPageState();
18 | }
19 |
20 |
21 | class TopBarPageState extends State with SingleTickerProviderStateMixin{
22 |
23 | TabController _tabController;
24 |
25 | @override
26 | void dispose() {
27 | _tabController.dispose();
28 | super.dispose();
29 | }
30 |
31 | void initState() {
32 | super.initState();
33 | _tabController = new TabController(vsync: this, length: 2);
34 | }
35 |
36 | @override
37 | Widget build(BuildContext context) {
38 | return new Scaffold(
39 | appBar: new AppBar(
40 | title: Text('TopBarPage'),
41 | bottom: new TabBar(
42 | tabs: [
43 | new Tab(
44 | icon: new Icon(FontAwesomeIcons.google),
45 | ),
46 | new Tab(
47 | icon: new Icon(FontAwesomeIcons.facebook),
48 | ),
49 | ],
50 | controller: _tabController,
51 | ),
52 | ),
53 | body: new TabBarView(
54 | controller: _tabController,
55 | children: [
56 | new Center(child: new Text('Google',style: TextStyle(fontSize: 20,),)),
57 | new Center(child: new Text('Facebook',style: TextStyle(fontSize: 20,),)),
58 | ],
59 | ),
60 | );
61 | }
62 |
63 |
64 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/utils/carousel.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Carousel extends StatefulWidget {
4 |
5 | ///All the [Widget] on this Carousel.
6 | final List children;
7 |
8 | ///Returns [children]`s [lenght].
9 | int get childrenCount => children.length;
10 |
11 | ///The transition animation timing curve. Default is [Curves.ease]
12 | final Curve animationCurve;
13 |
14 | ///The transition animation duration. Default is 250ms.
15 | final Duration animationDuration;
16 |
17 | // Enable or Disable the indicator (dots). Default is true
18 | final bool showIndicator;
19 |
20 | //Enable/Disable radius Border for the images. Default is false
21 | final bool borderRadius;
22 |
23 | //Border Radius of the images. Default is [Radius.circular(8.0)]
24 | final Radius radius;
25 |
26 | //Move the Indicator From the Bottom
27 | final double moveIndicatorFromBottom;
28 |
29 | //Remove the radius bottom from the indicator background. Default false
30 | final bool noRadiusForIndicator;
31 |
32 | //Padding Size of the background Indicator. Default is 20.0
33 | final double indicatorBgPadding;
34 |
35 | // The base size of the dots. Default is 8.0
36 | final double dotSize;
37 |
38 | // The distance between the center of each dot. Default is 25.0
39 | final double dotSpacing;
40 |
41 | // The Color of each dot. Default is Colors.grey[300]
42 | final Color dotColor;
43 |
44 | // The Color of selected dot. Default is Colors.grey
45 | final Color dotSelectedColor;
46 |
47 | // The background Color of the dots. Default is [Colors.transparent]
48 | final Color dotBgColor;
49 |
50 | Carousel({
51 | this.children,
52 | this.animationCurve = Curves.ease,
53 | this.animationDuration = const Duration(milliseconds: 250),
54 | this.showIndicator = true,
55 | this.borderRadius = false,
56 | this.radius,
57 | this.indicatorBgPadding = 20.0,
58 | this.moveIndicatorFromBottom = 0.0,
59 | this.noRadiusForIndicator = false,
60 | this.dotSize = 8.0,
61 | this.dotSpacing = 25.0,
62 | this.dotColor = const Color(0xFFCCCCCC),
63 | this.dotSelectedColor = Colors.grey,
64 | this.dotBgColor,
65 | }) :
66 | assert(children != null),
67 | assert(children.length > 1),
68 | assert(animationCurve != null),
69 | assert(animationDuration != null);
70 |
71 |
72 | @override
73 | State createState() => new _CarouselState();
74 | }
75 |
76 | class _CarouselState extends State with SingleTickerProviderStateMixin {
77 | TabController _controller;
78 | ///Actual index of the displaying Widget
79 | int get actualIndex => _controller.index;
80 |
81 | int selectedIndex = 0;
82 |
83 | ///Returns the calculated value of the next index.
84 | int get nextIndex {
85 | var nextIndexValue = actualIndex;
86 |
87 | if(nextIndexValue < _controller.length - 1)
88 | nextIndexValue++;
89 | else
90 | nextIndexValue = 0;
91 |
92 | return nextIndexValue;
93 | }
94 |
95 | @override
96 | void initState() {
97 | super.initState();
98 |
99 | _controller = new TabController(length: widget.childrenCount, vsync: this);
100 | _controller.addListener(_handleTabSelection);
101 | }
102 |
103 | @override
104 | void dispose() {
105 | _controller.dispose();
106 | super.dispose();
107 | }
108 |
109 | void _handleTabSelection() {
110 | setState(() {
111 | selectedIndex = _controller.index;
112 | });
113 | }
114 |
115 | @override
116 | Widget build(BuildContext context) {
117 | return new Scaffold(
118 | body: new Stack(
119 | children: [
120 | new TabBarView(
121 | children: widget.children.map((widget) => new Center(child: widget,)).toList(),
122 | controller: this._controller,
123 | ),
124 | widget.showIndicator ? new Positioned(
125 | bottom: widget.moveIndicatorFromBottom,
126 | left: 0.0,
127 | right: 0.0,
128 | child: new Container(
129 | decoration: new BoxDecoration(
130 | color: widget.dotBgColor == null ? Colors.transparent : widget.dotBgColor,
131 | borderRadius: widget.borderRadius ? (widget.noRadiusForIndicator ? null : new BorderRadius.only(
132 | bottomLeft: widget.radius != null ? widget.radius : new Radius.circular(8.0),
133 | bottomRight: widget.radius != null ? widget.radius : new Radius.circular(8.0)
134 | )) : null,
135 | ),
136 | padding: new EdgeInsets.all(widget.indicatorBgPadding),
137 | child: new Center(
138 | child: new DotsIndicator(
139 | controller: _controller,
140 | itemCount: widget.children.length,
141 | color: widget.dotColor,
142 | selectedIndex: selectedIndex,
143 | selectedColor: widget.dotSelectedColor,
144 | dotSize: widget.dotSize,
145 | dotSpacing: widget.dotSpacing,
146 | ),
147 | ),
148 | ),
149 | ) : new Container(),
150 | ],
151 | )
152 | );
153 | }
154 | }
155 |
156 | /// An indicator showing the currently selected page of a PageController
157 | class DotsIndicator extends StatelessWidget {
158 | DotsIndicator({
159 | this.controller,
160 | this.itemCount,
161 | this.color,
162 | this.dotSize,
163 | this.selectedIndex,
164 | this.selectedColor,
165 | this.dotSpacing
166 | });
167 |
168 | // The PageController that this DotsIndicator is representing.
169 | final TabController controller;
170 |
171 | // The number of items managed by the PageController
172 | final int itemCount;
173 |
174 | // Selected index
175 | final int selectedIndex;
176 |
177 | // The color of the dots.
178 | final Color color;
179 |
180 | // The color of the dots.
181 | final Color selectedColor;
182 |
183 | // The base size of the dots
184 | final double dotSize;
185 |
186 | // The distance between the center of each dot
187 | final double dotSpacing;
188 |
189 | Widget _buildDot(int index) {
190 | return new Container(
191 | width: dotSpacing,
192 | child: new Center(
193 | child: new Material(
194 | color: index == selectedIndex ? selectedColor : color,
195 | type: MaterialType.circle,
196 | child: new Container(
197 | width: dotSize,
198 | height: dotSize,
199 | ),
200 | ),
201 | ),
202 | );
203 | }
204 |
205 | Widget build(BuildContext context) {
206 | return new Row(
207 | mainAxisAlignment: MainAxisAlignment.center,
208 | children: new List.generate(itemCount, _buildDot),
209 | );
210 | }
211 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/utils/carousel_pro.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 | import 'package:flutter/material.dart';
3 | import 'dart:async';
4 |
5 | class Carousel extends StatefulWidget {
6 | //All the images on this Carousel.
7 | final List images;
8 |
9 | //The transition animation timing curve. Default is [Curves.ease]
10 | final Curve animationCurve;
11 |
12 | //The transition animation duration. Default is 300ms.
13 | final Duration animationDuration;
14 |
15 | // The base size of the dots. Default is 8.0
16 | final double dotSize;
17 |
18 | // The increase in the size of the selected dot. Default is 2.0
19 | final double dotIncreaseSize;
20 |
21 | // The distance between the center of each dot. Default is 25.0
22 | final double dotSpacing;
23 |
24 | // The Color of each dot. Default is Colors.white
25 | final Color dotColor;
26 |
27 | // The background Color of the dots. Default is [Colors.grey[800].withOpacity(0.5)]
28 | final Color dotBgColor;
29 |
30 | // Enable or Disable the indicator (dots). Default is true
31 | final bool showIndicator;
32 |
33 | //Padding Size of the background Indicator. Default is 20.0
34 | final double indicatorBgPadding;
35 |
36 | //How to show the images in the box. Default is cover
37 | final BoxFit boxFit;
38 |
39 | //Enable/Disable radius Border for the images. Default is false
40 | final bool borderRadius;
41 |
42 | //Border Radius of the images. Default is [Radius.circular(8.0)]
43 | final Radius radius;
44 |
45 | //Move the Indicator From the Bottom
46 | final double moveIndicatorFromBottom;
47 |
48 | //Remove the radius bottom from the indicator background. Default false
49 | final bool noRadiusForIndicator;
50 |
51 | //Enable/Disable Image Overlay Shadow. Default false
52 | final bool overlayShadow;
53 |
54 | //Choose the color of the overlay Shadow color. Default Colors.grey[800]
55 | final Color overlayShadowColors;
56 |
57 | //Choose the size of the Overlay Shadow, from 0.0 to 1.0. Default 0.5
58 | final double overlayShadowSize;
59 |
60 | //Enable/Disable the auto play of the slider. Default true
61 | final bool autoplay;
62 |
63 | //Duration of the Auto play slider by seconds. Default 3 seconds
64 | final Duration autoplayDuration;
65 |
66 | final Color selectedColor;
67 |
68 | Carousel({
69 | this.images,
70 | this.animationCurve = Curves.ease,
71 | this.animationDuration = const Duration(milliseconds: 300),
72 | this.dotSize = 8.0,
73 | this.dotSpacing = 25.0,
74 | this.dotIncreaseSize = 2.0,
75 | this.dotColor = Colors.white,
76 | this.dotBgColor,
77 | this.selectedColor,
78 | this.showIndicator = true,
79 | this.indicatorBgPadding = 20.0,
80 | this.boxFit = BoxFit.cover,
81 | this.borderRadius = false,
82 | this.radius,
83 | this.moveIndicatorFromBottom = 0.0,
84 | this.noRadiusForIndicator = false,
85 | this.overlayShadow = false,
86 | this.overlayShadowColors,
87 | this.overlayShadowSize = 0.5,
88 | this.autoplay = true,
89 | this.autoplayDuration = const Duration(seconds: 3)
90 | }) :
91 | assert(images != null),
92 | assert(animationCurve != null),
93 | assert(animationDuration != null),
94 | assert(dotSize != null),
95 | assert(dotSpacing != null),
96 | assert(dotIncreaseSize != null),
97 | assert(dotColor != null);
98 |
99 | @override
100 | State createState() => new CarouselState();
101 | }
102 |
103 | class CarouselState extends State {
104 | int _selected = 0;
105 | final _controller = new PageController();
106 |
107 | @override
108 | void initState() {
109 | super.initState();
110 |
111 | if(widget.autoplay) {
112 | new Timer.periodic(widget.autoplayDuration, (_) {
113 | if(_controller.page == widget.images.length-1) {
114 | _controller.animateToPage(
115 | 0,
116 | duration: widget.animationDuration,
117 | curve: widget.animationCurve,
118 | );
119 | } else {
120 | _controller.nextPage(duration: widget.animationDuration, curve: widget.animationCurve);
121 | }
122 | });
123 | }
124 | }
125 |
126 | @override
127 | void dispose() {
128 | super.dispose();
129 | }
130 |
131 | @override
132 | Widget build(BuildContext context) {
133 | final List listImages = widget.images;
134 |
135 | return new Scaffold(
136 | body: new Stack(
137 | children: [
138 |
139 | new Container(
140 | child: new PageView(
141 | physics: new AlwaysScrollableScrollPhysics(),
142 | controller: _controller,
143 | children: listImages,
144 | ),
145 | ),
146 |
147 | widget.showIndicator ? new Positioned(
148 | bottom: widget.moveIndicatorFromBottom,
149 | left: 0.0,
150 | right: 0.0,
151 | child: new Container(
152 | decoration: new BoxDecoration(
153 | color: widget.dotBgColor == null ? Colors.grey[800].withOpacity(0.5) : widget.dotBgColor,
154 | borderRadius: widget.borderRadius ? (widget.noRadiusForIndicator ? null : new BorderRadius.only(
155 | bottomLeft: widget.radius != null ? widget.radius : new Radius.circular(8.0),
156 | bottomRight: widget.radius != null ? widget.radius : new Radius.circular(8.0)
157 | )) : null,
158 | ),
159 | padding: new EdgeInsets.all(widget.indicatorBgPadding),
160 | child: new Center(
161 | child: new DotsIndicator(
162 | controller: _controller,
163 | itemCount: listImages.length,
164 | color: widget.dotColor,
165 | dotSize: widget.dotSize,
166 | selectedIndex: _selected,
167 | selectedColor: widget.selectedColor,
168 | dotSpacing: widget.dotSpacing,
169 | dotIncreaseSize: widget.dotIncreaseSize,
170 | onPageSelected: (int page) {
171 | _controller.animateToPage(
172 | page,
173 | duration: widget.animationDuration,
174 | curve: widget.animationCurve,
175 | );
176 |
177 | setState(() {
178 | _selected = page;
179 | });
180 | },
181 | ),
182 | ),
183 | ),
184 | ) : new Container(),
185 |
186 | ],
187 | ),
188 | );
189 | }
190 | }
191 |
192 | /// An indicator showing the currently selected page of a PageController
193 | class DotsIndicator extends StatelessWidget {
194 | DotsIndicator({
195 | this.controller,
196 | this.itemCount,
197 | this.onPageSelected,
198 | this.color,
199 | this.selectedIndex,
200 | this.selectedColor,
201 | this.dotSize,
202 | this.dotIncreaseSize,
203 | this.dotSpacing
204 | });
205 |
206 | // The PageController that this DotsIndicator is representing.
207 | final PageController controller;
208 |
209 | // The number of items managed by the PageController
210 | final int itemCount;
211 |
212 | // Called when a dot is tapped
213 | final ValueChanged onPageSelected;
214 |
215 | // The color of the dots.
216 | final Color color;
217 |
218 | final int selectedIndex;
219 |
220 | final Color selectedColor;
221 |
222 | // The base size of the dots
223 | final double dotSize;
224 |
225 | // The increase in the size of the selected dot
226 | final double dotIncreaseSize;
227 |
228 | // The distance between the center of each dot
229 | final double dotSpacing;
230 |
231 | Widget _buildDot(int index) {
232 | double selectedness = Curves.easeOut.transform(
233 | max(
234 | 0.0,
235 | 1.0 - ((controller.page ?? controller.initialPage) - index).abs(),
236 | ),
237 | );
238 |
239 | print('selectednessd ${selectedness.round()} $index');
240 |
241 | double zoom = 1.0 + (dotIncreaseSize - 1.0) * selectedness;
242 | return new Container(
243 | width: dotSpacing,
244 | child: new Center(
245 | child: new Material(
246 | color: color,
247 | type: MaterialType.circle,
248 | child: new Container(
249 | width: dotSize * zoom,
250 | height: dotSize * zoom,
251 | child: new InkWell(
252 | onTap: () => onPageSelected(index),
253 | ),
254 | ),
255 | ),
256 | ),
257 | );
258 | }
259 |
260 | Widget build(BuildContext context) {
261 | return new Row(
262 | mainAxisAlignment: MainAxisAlignment.center,
263 | children: new List.generate(itemCount, _buildDot),
264 | );
265 | }
266 | }
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/utils/flutter_icon_icons.dart:
--------------------------------------------------------------------------------
1 | /// Flutter icons FlutterIcon
2 | /// Copyright (C) 2018 by original authors @ fluttericon.com, fontello.com
3 | /// This font was generated by FlutterIcon.com, which is derived from Fontello.
4 | ///
5 | /// To use this font, place it in your fonts/ directory and include the
6 | /// following in your pubspec.yaml
7 | ///
8 | /// flutter:
9 | /// fonts:
10 | /// - family: FlutterIcon
11 | /// fonts:
12 | /// - asset: fonts/FlutterIcon.ttf
13 | ///
14 | ///
15 | /// * Meteocons, Copyright (C) 2012 by Alessio Atzeni
16 | /// Author: Alessio Atzeni
17 | /// License: SIL (http://scripts.sil.org/OFL)
18 | /// Homepage: http://www.alessioatzeni.com
19 | ///
20 | import 'package:flutter/widgets.dart';
21 |
22 | class FlutterIcon {
23 | FlutterIcon._();
24 |
25 | static const _kFontFam = 'FlutterIcon';
26 |
27 | static const IconData cloud_moon = const IconData(0xe800, fontFamily: _kFontFam);
28 | static const IconData fahrenheit = const IconData(0xe801, fontFamily: _kFontFam);
29 | static const IconData clouds_flash_alt = const IconData(0xe802, fontFamily: _kFontFam);
30 | static const IconData sun_inv = const IconData(0xe803, fontFamily: _kFontFam);
31 | static const IconData moon_inv = const IconData(0xe804, fontFamily: _kFontFam);
32 | static const IconData clouds_inv = const IconData(0xe805, fontFamily: _kFontFam);
33 | static const IconData clouds_flash_inv = const IconData(0xe806, fontFamily: _kFontFam);
34 | static const IconData temperature = const IconData(0xe807, fontFamily: _kFontFam);
35 | static const IconData compass = const IconData(0xe808, fontFamily: _kFontFam);
36 | static const IconData na = const IconData(0xe809, fontFamily: _kFontFam);
37 | static const IconData celcius = const IconData(0xe80a, fontFamily: _kFontFam);
38 | static const IconData cloud_sun_inv = const IconData(0xe80b, fontFamily: _kFontFam);
39 | static const IconData cloud_moon_inv = const IconData(0xe80c, fontFamily: _kFontFam);
40 | static const IconData moon = const IconData(0xe80d, fontFamily: _kFontFam);
41 | static const IconData eclipse = const IconData(0xe80e, fontFamily: _kFontFam);
42 | static const IconData mist = const IconData(0xe80f, fontFamily: _kFontFam);
43 | static const IconData wind = const IconData(0xe810, fontFamily: _kFontFam);
44 | static const IconData snowflake = const IconData(0xe811, fontFamily: _kFontFam);
45 | static const IconData snow = const IconData(0xe812, fontFamily: _kFontFam);
46 | static const IconData snow_alt = const IconData(0xe813, fontFamily: _kFontFam);
47 | static const IconData cloud_inv = const IconData(0xe814, fontFamily: _kFontFam);
48 | static const IconData hail = const IconData(0xe815, fontFamily: _kFontFam);
49 | static const IconData clouds = const IconData(0xe816, fontFamily: _kFontFam);
50 | static const IconData clouds_flash = const IconData(0xe817, fontFamily: _kFontFam);
51 | static const IconData cloud_flash_inv = const IconData(0xe818, fontFamily: _kFontFam);
52 | static const IconData drizzle_inv = const IconData(0xe819, fontFamily: _kFontFam);
53 | static const IconData rain_inv = const IconData(0xe81a, fontFamily: _kFontFam);
54 | static const IconData fog_sun = const IconData(0xe81b, fontFamily: _kFontFam);
55 | static const IconData fog_moon = const IconData(0xe81c, fontFamily: _kFontFam);
56 | static const IconData fog_cloud = const IconData(0xe81d, fontFamily: _kFontFam);
57 | static const IconData fog = const IconData(0xe81e, fontFamily: _kFontFam);
58 | static const IconData cloud = const IconData(0xe81f, fontFamily: _kFontFam);
59 | static const IconData cloud_flash = const IconData(0xe820, fontFamily: _kFontFam);
60 | static const IconData cloud_flash_alt = const IconData(0xe821, fontFamily: _kFontFam);
61 | static const IconData drizzle = const IconData(0xe822, fontFamily: _kFontFam);
62 | static const IconData rain = const IconData(0xe823, fontFamily: _kFontFam);
63 | static const IconData windy = const IconData(0xe824, fontFamily: _kFontFam);
64 | static const IconData windy_rain_inv = const IconData(0xe825, fontFamily: _kFontFam);
65 | static const IconData snow_inv = const IconData(0xe826, fontFamily: _kFontFam);
66 | static const IconData snow_heavy_inv = const IconData(0xe827, fontFamily: _kFontFam);
67 | static const IconData windy_inv = const IconData(0xe828, fontFamily: _kFontFam);
68 | static const IconData sunrise = const IconData(0xe829, fontFamily: _kFontFam);
69 | static const IconData sun = const IconData(0xe82a, fontFamily: _kFontFam);
70 | static const IconData hail_inv = const IconData(0xe82b, fontFamily: _kFontFam);
71 | static const IconData windy_rain = const IconData(0xe82c, fontFamily: _kFontFam);
72 | static const IconData snow_heavy = const IconData(0xe82d, fontFamily: _kFontFam);
73 | static const IconData cloud_sun = const IconData(0xe82e, fontFamily: _kFontFam);
74 | }
75 |
--------------------------------------------------------------------------------
/flutter_road_widgets/lib/utils/throttle_debounce.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | class Throttler{
4 |
5 | Duration delay;
6 | var callback;
7 | List args;
8 | bool noTrailing;
9 |
10 | Throttler(this.delay, this.callback, this.args, [this.noTrailing=false]);
11 |
12 | var timeoutId;
13 |
14 | DateTime lastExec = new DateTime.now();
15 |
16 | void throttle() {
17 |
18 | Duration elapsed = new DateTime.now().difference(lastExec);
19 |
20 | void exec() {
21 | lastExec = new DateTime.now();
22 | callback(args);
23 | }
24 |
25 | if(elapsed.compareTo(delay) >= 0) {
26 | exec();
27 | }
28 | //cancel the timeout scheduled for trailing callback
29 | if(timeoutId != null)
30 | timeoutId.cancel();
31 |
32 | if( noTrailing == false) {
33 | //there should be a trailing callback, so schedule one
34 | //buggy here, should be 'delay - elasped' but dart async only supports const Duration for delay
35 | timeoutId = new Timer(delay, exec);
36 | }
37 | }
38 | }
39 |
40 | class Debouncer {
41 |
42 | Duration delay;
43 | var callback;
44 | List args;
45 | bool atBegin;
46 |
47 | Debouncer(this.delay, this.callback, this.args, [this.atBegin=false]);
48 |
49 | var timeoutId;
50 |
51 | void debounce() {
52 |
53 | void exec() {
54 | callback(args);
55 | }
56 |
57 | void clear() {
58 | timeoutId = null;
59 | }
60 | //cancel the previous timer if debounce is still being called before the delay period is over
61 | if(timeoutId != null) {
62 | timeoutId.cancel();
63 | }
64 | //if atBegin is true, 'exec' has to executed the first time debounce gets called
65 | if(atBegin && timeoutId == null) {
66 | exec();
67 | }
68 | //schedule a new call after delay time
69 | timeoutId = new Timer(delay, atBegin ? clear : exec);
70 | }
71 |
72 | }
73 |
74 |
--------------------------------------------------------------------------------
/flutter_road_widgets/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_road_widgets
2 | description: A new Flutter application.
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 | # Read more about versioning at semver.org.
10 | version: 1.0.0+1
11 |
12 | environment:
13 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
14 |
15 | dependencies:
16 | flutter:
17 | sdk: flutter
18 |
19 | # The following adds the Cupertino Icons font to your application.
20 | # Use with the CupertinoIcons class for iOS style icons.
21 | cupertino_icons: ^0.1.2
22 | font_awesome_flutter: any
23 | transparent_image: any
24 | cached_network_image: any
25 | dio: any
26 | url_launcher: any
27 |
28 | dev_dependencies:
29 | test: any
30 | flutter_test:
31 | sdk: flutter
32 |
33 |
34 | # For information on the generic Dart part of this file, see the
35 | # following page: https://www.dartlang.org/tools/pub/pubspec
36 |
37 | # The following section is specific to Flutter.
38 | flutter:
39 |
40 | # The following line ensures that the Material Icons font is
41 | # included with your application, so that you can use the icons in
42 | # the material Icons class.
43 | uses-material-design: true
44 |
45 | # To add assets to your application, add an assets section, like this:
46 | # assets:
47 | # - images/a_dot_burr.jpeg
48 | # - images/a_dot_ham.jpeg
49 | assets:
50 | - images/flutter.png
51 | # An image asset can refer to one or more resolution-specific "variants", see
52 | # https://flutter.io/assets-and-images/#resolution-aware.
53 |
54 | # For details regarding adding assets from package dependencies, see
55 | # https://flutter.io/assets-and-images/#from-packages
56 |
57 | # To add custom fonts to your application, add a fonts section here,
58 | # in this "flutter" section. Each entry in this list should have a
59 | # "family" key with the font family name, and a "fonts" key with a
60 | # list giving the asset and other descriptors for the font. For
61 | # example:
62 | # fonts:
63 | # - family: Schyler
64 | # fonts:
65 | # - asset: fonts/Schyler-Regular.ttf
66 | # - asset: fonts/Schyler-Italic.ttf
67 | # style: italic
68 | # - family: Trajan Pro
69 | # fonts:
70 | # - asset: fonts/TrajanPro.ttf
71 | # - asset: fonts/TrajanPro_Bold.ttf
72 | # weight: 700
73 | #
74 | # For details regarding fonts from package dependencies,
75 | # see https://flutter.io/custom-fonts/#from-packages
76 |
--------------------------------------------------------------------------------
/flutter_road_widgets/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:flutter_road_widgets/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 |
--------------------------------------------------------------------------------
/notes/Dart_Intro.md:
--------------------------------------------------------------------------------
1 | ## Dart入门笔记
2 | > 参考文献: https://www.dartlang.org/samples
3 |
4 | 感觉最近要入坑 **Flutter** 了, 于是决定先了解一下它用的语言: **Dart** 的使用方法,然后写一篇笔记总结一下常用方法。
5 |
6 | #### 运行代码的环境
7 |
8 | 大多数代码都可以在这个 DartPad 上运行:
9 | [https://dartpad.dartlang.org/](https://dartpad.dartlang.org/)
10 | #### 首先就是一个 Hello Word
11 |
12 | ```
13 | void main() {
14 | print('Hello, World!');
15 | }
16 | ```
17 | #### Dart 变量类型
18 |
19 | Dart 可以像 JS 一样用 var 来申明不指定它类型的变量,也可以申明特定类型的变量。
20 |
21 | 用 var 来申明变量:
22 |
23 | ```
24 | // 字符串
25 | var name = 'Voyager I';
26 | // 整型
27 | var year = 1977;
28 | // 浮点型
29 | var antennaDiameter = 3.7;
30 | // 列表 List
31 | var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
32 | // Map 类型
33 | var image = {
34 | 'tags': ['saturn'],
35 | 'url': '//path/to/saturn.jpg'
36 | };
37 | ```
38 |
39 | 申明特定类型的变量:
40 |
41 | ```
42 | // 字符串
43 | String name = 'Voyager I';
44 | // 整型
45 | int year = 1977;
46 | // 浮点型
47 | double antennaDiameter = 3.7;
48 | // 列表 List
49 | List flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
50 | // Map 类型
51 | Map image = {
52 | 'tags': ['saturn'],
53 | 'url': '//path/to/saturn.jpg'
54 | };
55 | ```
56 | 然后,赋值变量的时候要记得考虑关键字:[关键字表](http://wiki.jikexueyuan.com/project/dart-language-tour/keywords.html)
57 |
58 |
59 | #### 条件语句
60 |
61 | ```
62 | //if 语句
63 | if (判断条件) {
64 | 执行语句;
65 | } else if (判断条件) {
66 | 执行语句;
67 | } else{
68 | 执行语句;
69 | }
70 | ```
71 |
72 | ```
73 | // switch case
74 | var number = '1';
75 | switch (number) {
76 | case '1':
77 | print('The number is 1');
78 | break;
79 | case '2':
80 | print('The number is 2');
81 | break;
82 | case '3':
83 | print('The number is 3');
84 | break;
85 | default:
86 | print('The number is Unknown');
87 | }
88 | ```
89 |
90 | #### 循环语句
91 | 两种 For 循环
92 |
93 | ```
94 | // 第一种,就像 java 的 for 循环
95 | for (var i = 0; i < 2; i++) {
96 | print(i);
97 | }
98 | // 第二种,遍历 List 和 Set, 和 Python 用法很像
99 | var myList = [0, 1, 2];
100 | for (var x in myList) {
101 | print(x); // 0 1 2
102 | }
103 | ```
104 | While 循环
105 |
106 | ```
107 | var i=1;
108 | while (i < 200) {
109 | print(i);
110 | i += 1;
111 | }
112 | ```
113 | 和其他语言一样,dart 也可以使用 break 和 continue
114 |
115 | #### Dart 函数
116 | ```
117 | //计算一个斐波那契数列
118 | int fibonacci(int n) {
119 | if (n == 0 || n == 1) return n;
120 | return fibonacci(n - 1) + fibonacci(n - 2);
121 | }
122 |
123 | var result = fibonacci(20);
124 | ```
125 | 上面这个函数看着和一般的语言没差别,但是在 Dart 中和还有一个神奇的写法:
126 |
127 | ```
128 | void main() => RunWhile(20);
129 |
130 | RunWhile(n) {
131 | var i=1;
132 | while (i < n) {
133 | print(i);
134 | i += 1;
135 | }
136 | }
137 | ```
138 | 这么 main() 函数后面直接跟了一个 => 来调用 RunWhile 方法,这是Dart中单行函数或方法的简写。
139 |
140 | #### 引用库
141 |
142 |
143 | ```
144 | // 导入内置库
145 | import 'dart:math';
146 |
147 | // 导入外部库
148 | import 'package:test/test.dart';
149 |
150 | // 通过文件系统路径导入库
151 | import 'path/to/my_other_file.dart';
152 | ```
153 |
154 | #### 创建类
155 |
156 | ```
157 | // 创建一个猫的类
158 | class Cat {
159 | String name;
160 | num age;
161 | Cat(name, age) {
162 | //初始化
163 | this.name=name;
164 | this.age=age;
165 | }
166 | void talk() {
167 | print('My name is $name, I am ${age} years old now.');
168 | }
169 | }
170 |
171 | void main(){
172 | // 实例化并调用方法
173 | var myCat=new Cat("小爪", 1); // 没错,我的🐱叫小爪!!
174 | myCat.talk();
175 | }
176 | ```
177 |
178 | 结尾了结尾了!umm, 推荐一个网站,我是看这个网站总结的:
179 | [https://www.dartlang.org/guides/language](https://www.dartlang.org/guides/language)
180 |
181 | 最后!希望 Dart 和 Flutter 能发展的好起来!
182 |
183 | umm, 就这样,拜拜👋
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/notes/Flutter_Async.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - 异步任务
2 | > 实验 Flutter 的异步任务 --- [代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day10.dart)
3 |
4 | ### Fultter 异步任务试验
5 |
6 | Flutter 在很多地方需要用到异步的任务,例如,加载网络数据,任务延迟执行等,所以异步任务是不可避免的问题。本次试验主要试验了下面几种情况:
7 |
8 | - 用 Future, then 实现任务延迟执行
9 | - 用 async 和 await 实现任务延迟执行
10 | - 测试调用 async 方法时,代码的执行顺序问题
11 |
12 | [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day10.dart)
13 |
14 | 
15 |
16 |
17 | #### 用 Future, then 实现任务延迟执行
18 |
19 | Future 可以用来执行未来要执行的方法,例如下面代码,先输出 ”Started“, 调用 Future 以后过了一秒钟,再输出 ”Completed Task1“。
20 |
21 | ```
22 | void thenCatch(){
23 | mytext="Started";
24 | setMyTextState(mytext);
25 | // then 用来说明 1 second 后做什么
26 | Future.delayed(Duration(seconds: 1)).then((_){
27 | // 当运行完成
28 | mytext = mytext + "\n" + "Completed Task1";
29 | setMyTextState(mytext);
30 | }).catchError((e){
31 | // 当运行失败
32 | mytext=mytext+"\n"+'failed: ${e.toString()}';
33 | setMyTextState(mytext);
34 | });
35 | }
36 | ```
37 |
38 | #### 用 async 和 await 实现任务延迟执行
39 |
40 | await 也是 Flutter 中很好的一种执行异步任务的方法。
41 |
42 | 但是要使用await,必须在有async标记的函数中运行,否则这个await会报错。
43 |
44 | 下面是一个加了 await 的方法,它的输出是怎么样呢?
45 |
46 | ```
47 | Future asyncAwait() async{
48 | mytext="Started";
49 | setMyTextState(mytext);
50 | try{
51 | // 这里没有 .then, 要加 await, await 是说在 await 完成前别往下执行
52 | await Future.delayed(Duration(seconds: 1));
53 | mytext=mytext+"\n"+"Completed Task1";
54 | setMyTextState(mytext);
55 | await Future.delayed(Duration(seconds: 1));
56 | mytext=mytext+"\n"+"Completed Task2";
57 | setMyTextState(mytext);
58 | }catch(e){
59 | print('failed: ${e.toString()}');
60 | }
61 | }
62 | ```
63 |
64 | 答案是:
65 |
66 | ```
67 | Started
68 | --- 1 second ---
69 | Completed Task1
70 | --- 2 second ---
71 | Completed Task2
72 | ```
73 | 先输出 ”Start“, 然后过一秒,输出 ”Completed Task1“ 再过一秒输出 ”Completed Task2“ 。
74 |
75 | 如果把方法里的 await 去掉,看看会发生什么呢,结果是,Task1 和 Task2不会等待Future.delayed 完成,会直接执行。
76 |
77 | ```
78 | Started
79 | Completed Task1
80 | Completed Task2
81 | --- 1 second ---
82 | ```
83 |
84 | #### 测试调用 async 方法时,代码的执行顺序问题
85 |
86 | 那如果说,代码依次是 Task1, Task2, Task3, Task4, Task2 是一个异步的方法,Task3 , Task4 需要等待 Task2 完成吗?
87 |
88 | 代码如下:
89 |
90 | ```
91 | Future asyncAwaitWithTask() async{
92 | mytext="Started";
93 | setMyTextState(mytext);
94 | try{
95 | // 这里没有 .then, 要加 await, await 是说在 await 完成前别往下执行
96 | await Future.delayed(Duration(seconds: 1));
97 | mytext=mytext+"\n"+"Completed Task1";
98 | setMyTextState(mytext);
99 | task2();
100 | mytext=mytext+"\n"+"Completed Task3";
101 | setMyTextState(mytext);
102 | mytext=mytext+"\n"+"Completed Task4";
103 | setMyTextState(mytext);
104 | }catch(e){
105 | print('failed: ${e.toString()}');
106 | }
107 | }
108 |
109 | void task2() async{
110 | await Future.delayed(Duration(seconds: 1));
111 | mytext=mytext+"\n"+"Completed Task2";
112 | setMyTextState(mytext);
113 | }
114 | ```
115 | 答案是, Task3, Task4 会先于 Task2 执行,最前面的 GIF 图就是在运行的这个场景。
116 |
117 | ```
118 | Started
119 | --- 1 second ---
120 | Completed Task1
121 | Completed Task3
122 | Completed Task4
123 | --- 2 second ---
124 | Completed Task2
125 | ```
126 |
127 |
128 | ### Flutter 学习之路 Github 地址
129 |
130 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/notes/Flutter_Button.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - Button 控件
2 | > 实验一些常用的 Button 功能 ([代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day2.dart))
3 |
4 | ### Button 实验
5 |
6 | 实验了 Button 常用的一些功能
7 |
8 | - RaisedButton
9 | - FlatButton
10 | - 悬浮按钮 (FloatingActionButton)
11 | - 宽的悬浮按钮 (FloatingActionButton.extended)
12 | - 滚动条(Slider)
13 | - 复选框(Checkbox)
14 | - 选项按钮 (Radio Buttons)
15 |
16 | [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day2.dart)
17 |
18 | 
19 |
20 |
21 |
22 | #### RaisedButton
23 |
24 | 用 child 的方式添加文字,用 onPressed 方法监听按钮行为。
25 |
26 | ```
27 | // RaisedButton
28 | Padding(
29 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
30 | child: new RaisedButton(
31 | onPressed: () {print('button click');},
32 | child: new Text("RaisedButton"),
33 | ),
34 | ),
35 | ```
36 |
37 | #### FlatButton
38 |
39 | 和 RaisedButton 一样用 child 的方式添加文字,用 onPressed 方法监听按钮行为。
40 | FlatButton 本身是透明且没有突出的,所以设置了 color 使它更明显
41 |
42 |
43 | ```
44 | // FlatButton
45 | Padding(
46 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
47 | child: new FlatButton(
48 | onPressed: () {print('button click');},
49 | child: new Text("FlatButton"),
50 | color: Color(0xFFe16552),
51 | ),
52 | ),
53 | ```
54 |
55 | #### 悬浮按钮 (FloatingActionButton)
56 |
57 | 悬浮按钮,可以通过改变 child 来设置 button 上显示文字或者 icon。
58 |
59 | 同时这里有个要注意的点,就是 **material design** 建议每个屏幕只有一个 FloatingActionButton,所以如果一定要两个(比如像我这样写demo),就要把这个 heroTag 设置为 null。
60 |
61 | ```
62 | //FloatingActionButton 多个FloatingActionButton的时候会报错,要加 heroTag: null
63 | Padding(
64 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
65 | child: Row(
66 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
67 | children: [
68 | // FloatingActionButton
69 | new FloatingActionButton(
70 | onPressed: () {print('button click');},
71 | foregroundColor: Colors.white,
72 | backgroundColor: Color(0xFFf19670),
73 | child: new Icon(Icons.add),
74 | heroTag: null,
75 | ),
76 | // FloatingActionButton
77 | new FloatingActionButton(
78 | onPressed: () {print('button click');},
79 | foregroundColor: Colors.white,
80 | backgroundColor: Color(0xFFf19670),
81 | child: new Text("文字"),
82 | heroTag: null,
83 | ),
84 | ],
85 | ),
86 | ),
87 | ```
88 | #### 宽的悬浮按钮 (FloatingActionButton.extended)
89 |
90 | 可以看我上面的动图,有这个按钮的效果,感觉还挺棒的哈哈。
91 |
92 | ```
93 | // FloatingActionButton.extended
94 | Padding(
95 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
96 | child: new FloatingActionButton.extended(
97 | onPressed: () {
98 | print('button click');
99 | },
100 | foregroundColor: Colors.white,
101 | backgroundColor: Colors.amber,
102 | icon: new Icon(Icons.flag,color: Colors.red,),
103 | label: new Text('FloatingActionButton.extended', maxLines: 1),
104 | )
105 | ),
106 | ```
107 |
108 | #### 滚动条(Slider)
109 |
110 | ```
111 | Padding(
112 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
113 | child: new Slider(
114 | value: mCurrentValue,
115 | min: 1.0,
116 | max: 10.0,
117 | onChanged: (e) {
118 | setState(() {
119 | //四舍五入的双精度值
120 | mCurrentValue = e.roundToDouble();
121 | });
122 | }
123 | )
124 | ),
125 | ```
126 |
127 | #### 复选框(Checkbox)
128 |
129 | ```
130 | Padding(
131 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
132 | child: new Checkbox(
133 | value: isChecked,
134 | onChanged: (bool){
135 | setState(() {
136 | isChecked=bool;
137 | });
138 | }, activeColor: Colors.blue,
139 | )
140 | ),
141 | ```
142 |
143 | #### 选项按钮 (Radio Buttons)
144 |
145 | 这里如果把新建的 Radio 的值设置为 null, 这个 Radio 就是不可选的,会显示一个灰色的状态。
146 |
147 | ```
148 | // Radio
149 | Padding(
150 | padding: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
151 | child: new ButtonBar(//ButtonBar:水平排列按钮
152 | alignment: MainAxisAlignment.center,
153 | children: [
154 | //value和groupValue值一样的话,则按钮选中
155 | new Radio(value: 1,
156 | groupValue: groupValue1,
157 | onChanged: (int e) => updateGroupValue(e)),
158 | new Radio(value: 2,
159 | groupValue: groupValue1,
160 | onChanged: (int e) => updateGroupValue(e)),
161 | new Radio(value: 3,
162 | groupValue: groupValue1,
163 | onChanged: (int e) => updateGroupValue(e)),
164 | new Radio(value: 4,
165 | groupValue: groupValue1,
166 | onChanged: (int e) => updateGroupValue(e)),
167 | //value 值为 null 则表示按钮不可用
168 | new Radio(value: null, groupValue: null, onChanged: null)
169 | ],
170 | )
171 | ),
172 | ```
173 |
174 | #### 遇到的问题
175 |
176 | 感觉对于控件,各个参数主要是看官网文档,然后自己改改, 所以还是记录一下遇到的问题。
177 |
178 | ##### 问题一: 当多个 FloatingActionButton 的时候程序运行会黑屏
179 |
180 | 解决方案:把 **heroTag** 设置为 **null**
181 |
182 | ```
183 | new FloatingActionButton(
184 | onPressed: () {print('button click');},
185 | foregroundColor: Colors.white,
186 | backgroundColor: Color(0xFFf19670),
187 | child: new Icon(Icons.add),
188 | heroTag: null,
189 | ),
190 | ```
191 | 看了官网的说明,大意是 **material design** 建议每个屏幕只有一个 FloatingActionButton,所以如果一定要两个(比如像我这样写demo),就把这个 heroTag 设置为 null。
192 |
193 | 官网对于 heroTag 的说明: [link](https://docs.flutter.io/flutter/material/FloatingActionButton/heroTag.html)
194 |
195 | #### Flutter 学习之路 Github 地址
196 |
197 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
--------------------------------------------------------------------------------
/notes/Flutter_Dialog.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - 对话框(Dialog)
2 | > 实验一些常用的对话框实现方式--- [代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day6.dart)
3 |
4 | ### Dialog 实验
5 |
6 | 补上这个应该在第六篇博客就想写的坑,试验在 Flutter 中对 dialog 的各种使用方式。
7 |
8 | Flutter 官方建议使用 SimpleDialog 和 AlertDialog 两种方式来实现 Dialog, 然后这篇文章受下面这篇安卓的博客的启发,尝试实现一些不同功能的 Dialog:
9 |
10 | [https://www.cnblogs.com/gzdaijie/p/5222191.html](https://www.cnblogs.com/gzdaijie/p/5222191.html)
11 |
12 |
13 | 
14 |
15 |
16 | #### 底部提示栏
17 |
18 | 最简单的提示方式,从底部弹出提示。
19 |
20 | ```Dart
21 | Future _showSnackBar(BuildContext context, String text) async {
22 | final scaffold = Scaffold.of(context);
23 | scaffold.showSnackBar(
24 | SnackBar(
25 | content: Text(text),
26 | ),
27 | );
28 | }
29 | ```
30 |
31 |
32 | #### 简单的 Dialog
33 |
34 | 见到提示对话框,只是提示功能,不需要交互。当看到显示之后,就只需要点击 “是的”,表示知道就行了。
35 |
36 | ```Dart
37 | Future _showSnackBar(BuildContext context, String text) async {
38 | final scaffold = Scaffold.of(context);
39 | scaffold.showSnackBar(
40 | SnackBar(
41 | content: Text(text),
42 | ),
43 | );
44 | }
45 | ```
46 |
47 | #### 一个列表的 Dialog
48 |
49 | 列表的 Dialog 可以选择点击不同的 item 进行不同的操作。
50 |
51 | 在实现的时候遇到了一个坑,就是,在SingleChildScrollView里不能用 ListView,是直接在 ListBody 里面加入 ListTile 就好了。
52 |
53 | ```Dart
54 | Future _showListAlertDialog() async {
55 | return showDialog(
56 | context: context,
57 | barrierDismissible: false, // user must tap button!
58 | builder: (BuildContext context) {
59 | return AlertDialog(
60 | title: Text('我是一个列表 Dialog'),
61 | content: SingleChildScrollView(
62 | child: ListBody(
63 | children: [
64 | ListTile(
65 | leading: Icon(Icons.map),
66 | title: Text('Map'),
67 | onTap: () {
68 | setMyTextState("你选择了: Map");
69 | Navigator.of(context).pop();
70 | },
71 | ),
72 | ListTile(
73 | leading: Icon(Icons.photo_album),
74 | title: Text('Album'),
75 | onTap: () {
76 | setMyTextState("你选择了: Album");
77 | Navigator.of(context).pop();
78 | },
79 | ),
80 | ListTile(
81 | leading: Icon(Icons.phone),
82 | title: Text('Phone'),
83 | onTap: () {
84 | setMyTextState("你选择了: Phone");
85 | Navigator.of(context).pop();
86 | },
87 | ),
88 | ],
89 | ),
90 | ),
91 | actions: [
92 | FlatButton(
93 | child: Text('返回'),
94 | onPressed: () {
95 | Navigator.of(context).pop();
96 | },
97 | ),
98 | ],
99 | );
100 | },
101 | );
102 | }
103 | ```
104 |
105 |
106 |
107 | #### 单选框 Dialog (啊啊啊我还是先写一篇 setState, stateful widget 之类的文章再写这个好了!现在写就是在乱试,乱写!)
108 |
109 | 一开始以为会和上面那个 Dialog 差不多实现,实际上还是遇到了问题,发现在按下按钮不会产生选中效果,因为这个
110 |
111 | ### Flutter 学习之路 Github 地址
112 |
113 | 这是项目的 GitHub 地址,正在持续更新,欢迎 Star 呀!╮( ̄▽ ̄)╭
114 |
115 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/notes/Flutter_Gridview.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - Gridview
2 | > 实验一些常用的 Gridview 功能 --- [代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day5.dart)
3 |
4 | ### Gridview 实验
5 |
6 | Flutter 学习之路第五次实验,实验了 Gridview 常用的一些功能,用 Gridview 实现单词软件的一个基础功能。
7 |
8 | - 设置 gridview 各个属性设置(间距,每行个数,长宽比)
9 | - 自定义 item, 以及 gridview item 点击事件
10 | - 动态添加 gridview 的 item
11 |
12 | [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day5.dart)
13 |
14 | 
15 |
16 |
17 | #### 设置 gridview 各个属性设置(间距,每行个数,长宽比)
18 |
19 | - 用 crossAxisCount 来设置每行个数
20 | - 用 crossAxisSpacing 设置水平间隙
21 | - 用 mainAxisSpacing 设置上下间隙
22 | - 用 childAspectRatio 来设置宽高比例
23 |
24 | ```
25 | child: GridView.count(
26 | // 每行有几个子控件
27 | crossAxisCount: 2,
28 | // 水平子Widget之间间距
29 | crossAxisSpacing: 10.0,
30 | // 设置上下间隙
31 | mainAxisSpacing: 8.0,
32 | // 子Widget宽高比例
33 | childAspectRatio: 2.0,
34 | children: List.generate(listNumber, (index) {
35 | return gridItem(context, index);
36 | }),
37 | ),
38 | ```
39 |
40 | #### 自定义 item, 以及 gridview item 点击事件
41 |
42 | 这两个一起写是因为,实际上,item 点击是建立在自定义 item 上的,能自定义 item 了就能点击了。
43 |
44 | 自定义一个 gridItem 的 Widget
45 |
46 | ```
47 | Widget gridItem (BuildContext context, int _index) {
48 | int index=_index%words.length;
49 | return Container(
50 | alignment: Alignment.center,
51 | child: GestureDetector(
52 | onTap: () {
53 | setState(() {
54 | String temp=words[index];
55 | words[index]=translations[index];
56 | translations[index]=temp;
57 | });
58 | },
59 | child: Text(
60 | words[index],
61 | style: TextStyle(
62 | fontSize: 28,
63 | color: Colors.white,
64 | ),
65 | ),
66 | ),
67 | color:myColor,
68 | );
69 | }
70 | ```
71 |
72 | 用 List.generate 加载自定义的 gridItem
73 |
74 | ```
75 | Widget gridViewSection = Builder(
76 | builder: (context) => Container(
77 | margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 5.0),
78 | height: 600.0,
79 | child: GridView.count(
80 | // 每行有几个子控件
81 | crossAxisCount: 2,
82 | // 水平子Widget之间间距
83 | crossAxisSpacing: 10.0,
84 | // 水平子Widget之间间距
85 | mainAxisSpacing: 8.0,
86 | // 子Widget宽高比例
87 | childAspectRatio: 2.0,
88 | children: List.generate(listNumber, (index) {
89 | return gridItem(context, index);
90 | }),
91 | ),
92 | )
93 | );
94 | ```
95 |
96 | #### 动态添加 gridview 的 item
97 |
98 | 这个和之前写 listview 的动态添加套路差不多,就是改变下面这个 listNumber 的值,就可以完成动态添加.
99 |
100 | ```
101 | children: List.generate(listNumber, (index) {
102 | return gridItem(context, index);
103 | }),
104 | ```
105 | 同样,别忘了用 setState
106 |
107 | ```
108 | onTap: () {
109 | setState(() {
110 | String temp=words[index];
111 | words[index]=translations[index];
112 | translations[index]=temp;
113 | });
114 | },
115 | ```
116 |
117 | ### Flutter 学习之路 Github 地址
118 |
119 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/notes/Flutter_Image.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - Image 控件
2 | > 实验一些常用的 Image 功能 ([代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day3.dart))
3 |
4 | ### Image 试验
5 |
6 | Flutter 学习之路第三次试验,试验了有关于 Image 常用的一些功能,包括图片本地加载,图片和 GIF 的网络加载,图片渐现呈现,从网络加载图片并缓存在内存中。
7 |
8 | [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day3.dart)
9 |
10 | 
11 |
12 | ##### 加载本地图片
13 |
14 | 在 lib 同级目录下创建文件夹 images, 并且在 pubspec.yaml 文件中添加如下几行。
15 |
16 | ```
17 | flutter:
18 | assets:
19 | - images/flutter.png
20 | ```
21 |
22 | 用 AssetImage 获取图片
23 |
24 | ```
25 | // Image from asserts
26 | Padding(
27 | padding: const EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0),
28 | child: new Image(
29 | image:new AssetImage('images/flutter.png'),
30 | width: 50,
31 | height: 50,
32 | ),
33 | ),
34 | ```
35 |
36 | ##### 根据网络链接加载图片
37 |
38 | ```
39 | // Image from internet
40 | Padding(
41 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
42 | child: Image.network(
43 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/picture/day3/flutter.png?raw=true',
44 | scale: 4,
45 | ),
46 | ),
47 | ```
48 |
49 | ##### 从网络链接加载 **GIF**
50 |
51 | 可以很方便地加载 GIF 是个很棒的功能了,找了个 Google 动图哈哈
52 |
53 | ```
54 | // Gif from internet
55 | Padding(
56 | padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
57 | child:Image.network(
58 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/gif/day3/google.gif?raw=true',
59 | scale: 4,
60 | ),
61 | ),
62 | ```
63 |
64 | ##### FadeInImage(图片渐现呈现)
65 |
66 | 在 pubspec.yaml 加入 cached\_network\_image
67 |
68 | ```
69 | // FadeInImage
70 | Padding(
71 | padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
72 | child: FadeInImage.memoryNetwork(
73 | width: 180,
74 | height: 180,
75 | placeholder: kTransparentImage,
76 | image: 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/picture/day3/flutter.png?raw=true',
77 | ),
78 | ),
79 | ```
80 |
81 | ##### CachedNetworkImage (从网络加载图片并缓存在内存中)
82 |
83 | 在 pubspec.yaml 加入 cached\_network\_image
84 |
85 | ```
86 | // CachedNetworkImage
87 | Padding(
88 | padding: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
89 | child: CachedNetworkImage(
90 | width: 100,
91 | height: 100,
92 | placeholder: CircularProgressIndicator(),
93 | imageUrl:
94 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/picture/day3/flutter.png?raw=true',
95 | ),
96 | ),
97 | ```
98 |
99 |
100 | #### 遇到的问题
101 |
102 | 所以还是记录一些自己遇到的问题。
103 |
104 | ##### 问题一: 当我使用如下代码加载 Gif 以及 png 时,不能显示
105 |
106 |
107 | ```
108 | // Gif from internet
109 | adding(
110 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
111 | child:Image.network(
112 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/gif/day3/google.gif?raw=true',
113 | scale: 2,
114 | ),
115 | )
116 | ```
117 |
118 | 解决方法:在链接后面加上 **?raw=true** 就可以显示了
119 |
120 | ```
121 | 'https://github.com/draftbk/Blog_Resource/blob/master/Flutter/gif/day3/google.gif?raw=true',
122 | ```
123 | ##### 问题二: 不知道 assets 文件夹在哪创建,图片放哪可以被用到
124 |
125 |
126 | 查了一下发现,其实不用非要 assets 文件夹,Flutter 使用 pubspec.yaml 文件(位于项目根目录),来识别应用程序所需的asset。 可以创建一个其他名字的文件夹来标识 assets 路径。
127 |
128 | ```
129 | flutter:
130 | assets:
131 | - images/flutter.png
132 | ```
133 |
134 | ##### 问题三:在导入 package 的时候有时候不知道导入什么版本
135 |
136 | 懒人方法:any
137 |
138 | ```
139 | dependencies:
140 | flutter:
141 | sdk: flutter
142 | transparent_image: any
143 | cached_network_image: any
144 | ```
145 |
146 | ##### 问题四:最开始没有给 Container 设置宽度,在加载图片时动画布局变化很糟(果然还是新手233)
147 |
148 | 解决:给 Container 设置 width
149 |
150 | ```
151 | Widget buttonSection = Container(
152 | padding: const EdgeInsets.all(15.0),
153 | width: 1000,
154 | ```
155 |
156 | #### Flutter 学习之路 Github 地址
157 |
158 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/notes/Flutter_Interview_Problem.md:
--------------------------------------------------------------------------------
1 | ## Flutter 面试可能遇到的问题
2 | > 整理一些面试问题,也好明白以后学习的方向
3 |
4 |
5 |
6 |
7 | ### Dart 语言
8 |
9 | #### 1. dart是值传递还是引用传递
10 |
11 | 值传递(Java 也是)
12 |
13 |
14 |
15 | ### Android 端
16 |
17 |
18 |
19 | ### 来源
20 |
21 | 感谢网上分享面经的前辈们,给我们提供要提高的方向。
22 |
23 | - [可以算是Flutter面试凉凉经吧](https://juejin.im/post/5c67d621518825620a7f133e)
--------------------------------------------------------------------------------
/notes/Flutter_Listview.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - Listview 入门
2 | > 实验一些常用的 List 功能 --- [代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day4.dart)
3 |
4 | ### Listview 实验
5 |
6 | 实验了 Listview 常用的一些功能
7 |
8 | - 实现水平的 Listview
9 | - 给Listview item 加上点击事件
10 | - Listview 动态更新
11 |
12 | [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day4.dart)
13 |
14 | 
15 |
16 | #### 实现水平的 Listview
17 |
18 | 把属性 scrollDirection 设置为 Axis.horizontal 就能水平了,真的好方便。下面的代码为了避免太长我就选了一部分,实际上children还要多才有效果,可以看我 github 上的源码,或者自己加几个就好了。
19 |
20 |
21 | ```
22 | child: ListView(
23 | scrollDirection: Axis.horizontal,
24 | children: [
25 | Container(
26 | width: 160.0,
27 | color: Colors.red,
28 | ),
29 | Container(
30 | width: 160.0,
31 | color: Colors.blue,
32 | ),
33 | // Add more childre
34 | ],
35 | ),
36 | ```
37 |
38 | #### 给 Listview item 加上点击事件
39 |
40 | 点击事件感觉和处在 listview 里的 children 有关,children 是怎么设置点击事件,就按它的设置就好。
41 |
42 | ```
43 | child: ListView(
44 | children: [
45 | ListTile(
46 | leading: Icon(Icons.map),
47 | title: Text('Map'),
48 | onTap: (){
49 | _showToast(context,"Map");
50 | },
51 | ),
52 | ],
53 | )
54 | ```
55 |
56 | ##### Listview 动态更新
57 | 用 ListView.builder 以及 一个外部的 List, 然后写一个方法更新 List 的值
58 |
59 | ```
60 | List items=[];
61 | // show listview by item
62 | Widget dynamicSection = Container(
63 | margin: EdgeInsets.symmetric(vertical: 5.0),
64 | height: 200.0,
65 | child: ListView.builder(
66 | itemCount: items.length,
67 | itemBuilder: (context,index){
68 | return ListTile(
69 | leading: Icon(Icons.send),
70 | title: new Text("NewItem $index"));
71 | }
72 | )
73 | );
74 | // modify items
75 | void _addListDate(){
76 | setState(() {
77 | items.add(1);
78 | });
79 | }
80 | ```
81 |
82 |
83 | #### 遇到的问题
84 |
85 | 记录一下遇到的问题。
86 |
87 | ##### 问题一: Snackbar 报错不显示
88 |
89 | 原本代码:
90 |
91 | ```
92 | Widget basicListSection = Container(
93 | margin: EdgeInsets.symmetric(vertical: 20.0),
94 | height: 200.0,
95 | child: ListView(
96 | children: [
97 | ListTile(
98 | leading: Icon(Icons.map),
99 | title: Text('Map'),
100 | onTap: (){
101 | _showToast(context,"Map");
102 | },
103 | ),
104 | ],
105 | )
106 | );
107 | ```
108 |
109 | 原因:原本用的 context 是 Scaffold 的实例化的 widget 的 context, 不是 Scaffold 的。
110 |
111 | 参考:[link](https://stackoverflow.com/questions/51304568/scaffold-of-called-with-a-context-that-does-not-contain-a-scaffold/51304732)
112 |
113 | 所以要改成下面这样:(用 Builder(
114 | builder: (context) => ) 包起来
115 |
116 | ```
117 | Widget basicListSection = Builder(
118 | builder: (context) => Container(
119 | margin: EdgeInsets.symmetric(vertical: 20.0),
120 | height: 200.0,
121 | child: ListView(
122 | children: [
123 | ListTile(
124 | leading: Icon(Icons.map),
125 | title: Text('Map'),
126 | onTap: (){
127 | _showToast(context,"Map");
128 | },
129 | ),
130 | ],
131 | )
132 | )
133 | );
134 | ```
135 |
136 |
137 | #### Flutter 学习之路 Github 地址
138 |
139 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/notes/Flutter_NavigationBar.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - 导航栏(NavigationBar)
2 | > 实验一些常用的 NavigationBar 功能 --- [代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day7.dart)
3 |
4 | ### NavigationBar 实验
5 |
6 |
7 | - 底部导航栏 [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day7.dart)
8 | - 顶部导航栏 [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/subpage/TopBarPage.dart)
9 |
10 |
11 |
12 |
13 | 
14 |
15 |
16 | #### 底部导航栏(Part1)
17 |
18 | 底部导航用 PageView 和 BottomNavigationBar 完成。大段的代码就不贴了,在 [Github 代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day7.dart) 就能找到。
19 |
20 | ##### BottomNavigationBar
21 |
22 | BottomNavigationBar 在 items 里面添加想要的 BottomNavigationBarItem,然后 currentIndex 代表当前 item, page 在 PageView 的 onPageChanged()更改。
23 |
24 | ```
25 | bottomNavigationBar: new BottomNavigationBar(items: [
26 | new BottomNavigationBarItem(
27 | icon: new Icon(FontAwesomeIcons.font),
28 | title: new Text("Text"),
29 | backgroundColor: Colors.grey
30 | ),
31 | //更多 BottomNavigationBarItem
32 | ],
33 | onTap: onTap,
34 | currentIndex: page
35 | ),
36 | ```
37 |
38 | ##### 改变页面切换时候的动画效果
39 | 看 onTap 方法,其中改变 curve 可以改变页面切换时候的动画效果,可以点进 curves,dart 里面看看,有挺多种方法,尝试了一下,还是 Curves.ease 是一种最让人舒服的动画。 然后 duration 可以设置动画时间,可以尝试设置成 1000,你会发现切换页面,嗯,很慢。
40 |
41 | ```
42 | void onTap(int index) {
43 | pageController.animateToPage(
44 | index,
45 | // 设置页面转换效果的时间
46 | duration: const Duration(milliseconds: 300),
47 | // 设置转换时的效果
48 | curve: Curves.ease);
49 | }
50 | ```
51 |
52 | ##### PageView
53 |
54 | 然后是 PageView:用把子页面放到 children 里面(这里Page1() 什么的是为了简化篇幅,实际上没这个 class),然后用一个 pageController 来监听页面切换,可以上面的代码里就有 pageController 来控制页面和转换效果。用 onPageChanged 监听页面切换,执行页面切换以后的要执行的操作。
55 |
56 | ```
57 | body: new PageView(
58 | children: [
59 | new Page1(),
60 | new Page2(),
61 | new Page3(),
62 | ],
63 | controller: pageController,
64 | onPageChanged: onPageChanged,
65 | ),
66 | ```
67 | 用 onPageChanged 监听页面切换,切换后设置当前 page 值。
68 |
69 | ```
70 | void onPageChanged(int page) {
71 | setState(() {
72 | this.page = page;
73 | });
74 | }
75 | ```
76 | ##### 设置起始子页面:
77 |
78 | ```
79 | @override
80 | void initState() {
81 | super.initState();
82 | // 设置初始化page
83 | pageController = new PageController(initialPage: this.page);
84 | }
85 | ```
86 |
87 | #### 顶部导航栏(Part2)
88 |
89 | 用 AppBar 实现,用 title 设置顶部 bar 的文字,bottom用 TabBar 设置导航栏的图标,然后界面上在 TabBarView 里面完成不同的 subpage。
90 |
91 | ```
92 | new AppBar(
93 | title: Text('TopBarPage'),
94 | bottom: new TabBar(
95 | tabs: [
96 | new Tab(
97 | icon: new Icon(FontAwesomeIcons.google),
98 | ),
99 | new Tab(
100 | icon: new Icon(FontAwesomeIcons.facebook),
101 | ),
102 | ],
103 | controller: _tabController,
104 | ),
105 | ),
106 | body: new TabBarView(
107 | controller: _tabController,
108 | children: [
109 | new Center(child: new Text('Google',style: TextStyle(fontSize: 20,),)),
110 | new Center(child: new Text('Facebook',style: TextStyle(fontSize: 20,),)),
111 | ],
112 | ),
113 | ```
114 |
115 | #### 其他
116 |
117 | 刚刚在油管上浏览,看到 Flutter 又出新视频,上面有用 Cupertino Package 实现 iOS 风格的导航栏,有兴趣也可以看一下。
118 |
119 | [https://www.youtube.com/watch?v=3PdUaidHc-E](https://www.youtube.com/watch?v=3PdUaidHc-E)
120 |
121 | ### Flutter 学习之路 Github 地址
122 |
123 | 这是项目的 GitHub 地址,正在持续更新,欢迎 Star 呀!╮( ̄▽ ̄)╭
124 |
125 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/notes/Flutter_Network.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - 网络入门
2 | > 实验一些 Flutter 的网络方面的功能 ([代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day11.dart))
3 |
4 | ### 概述
5 |
6 | 一开始在想标题要叫什么呢,想想网络是个很复杂的东西,这里就实验了最基本的,开发过程中最常用的 Get Post, 就叫网络入门吧哈哈。
7 |
8 | Flutter 现在常用的网络方式有如下三种:
9 |
10 | - HttpClient
11 | - http
12 | - dio
13 |
14 | 这里试验了三种方法的 GET,POST 方法,以及 JSON 的解析。
15 |
16 | 实现通过 ip 获取 ip 所在地信息等方法。
17 |
18 |
19 | [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day11.dart)
20 |
21 | 
22 |
23 | 本次试验 url:
24 |
25 | ```Dart
26 | String getUrl="https://httpbin.org/ip";
27 | String postUrl="http://ip.taobao.com/service/getIpInfo.php";
28 | String searchIp='117.89.35.58';
29 | ```
30 | 分别是获取 ip(虽然我觉得它获取的ip 很奇怪),以及通过 ip 获取 ip 的所在地以及其他信息。
31 |
32 | 为了方便,第二个url 要用的 ip 设定为一个固定值。
33 |
34 | ### 用 HttpClient 实现
35 | HttpClient 是 Dart 原生的网络请求,flutter 中文网上的 cookbook 是用这个来实现的
36 |
37 | 不需要在 pubspec.yaml 添加依赖
38 |
39 | 引入:
40 |
41 | ```Dart
42 | import 'dart:convert';
43 | import 'dart:io';
44 | ```
45 |
46 | #### GET 请求
47 |
48 | ```Dart
49 | void HttpClient_Get() async {
50 | var httpClient = new HttpClient();
51 | String result;
52 | try {
53 | var request = await httpClient.getUrl(Uri.parse(getUrl));
54 | var response = await request.close();
55 | if (response.statusCode == HttpStatus.OK) {
56 | result = await response.transform(utf8.decoder).join();
57 | } else {
58 | result =
59 | 'Error getting IP address:\nHttp status ${response.statusCode}';
60 | }
61 | } catch (exception) {
62 | result = 'Failed getting IP address';
63 | }
64 | }
65 | ```
66 |
67 | #### POST 请求
68 |
69 | 网上找没有,然后对应着官网 API 尝试用了下面这个方法还是失败, 不清楚为什么,如果有同学找到方法解决求告知一下!
70 |
71 | ```Dart
72 | Uri uri=new Uri(path:postUrl,queryParameters: {"ip": searchIp} );
73 | var request = await httpClient.postUrl(uri);
74 | var response = await request.close();
75 | ```
76 | 其他两个方法 POST 都可以,umm, 而且功能还更全,所以还是用另外两种方法吧!
77 |
78 | ### 用 http 实现
79 | flutter 官网上的 cookbook 是用这个来实现的
80 |
81 | 不需要在 pubspec.yaml 添加依赖
82 |
83 | 引入:
84 |
85 | ```Dart
86 | import 'package:http/http.dart' as http;
87 | ```
88 |
89 | #### GET 请求
90 |
91 | ```Dart
92 | void http_Get() async {
93 | String result;
94 | try {
95 | var response = await http.get(getUrl);
96 | if (response.statusCode == HttpStatus.OK) {
97 | result = response.body;
98 | } else {
99 | result =
100 | 'Error getting IP address:\nHttp status ${response.statusCode}';
101 | }
102 | } catch (exception) {
103 | result = 'Failed getting IP address';
104 | }
105 | }
106 | ```
107 |
108 | #### POST 请求
109 |
110 | ```Dart
111 | void http_Post() async {
112 | String result;
113 | try {
114 |
115 | var client = http.Client();
116 | var response = await client.post(postUrl, body: {"ip": searchIp});
117 |
118 | if (response.statusCode == HttpStatus.OK) {
119 | result = response.body;
120 | } else {
121 | result =
122 | 'Error getting IP address:\nHttp status ${response.statusCode}';
123 | }
124 | } catch (exception) {
125 | result = 'Failed getting IP address';
126 | }
127 | }
128 | ```
129 |
130 | ### 用 dio 实现
131 |
132 | dio是Flutter中文网开源的一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等
133 |
134 | 需要在 pubspec.yaml 添加依赖 **dio: any**
135 |
136 | ```Dart
137 | dependencies:
138 | flutter:
139 | sdk: flutter
140 | dio: any
141 | ```
142 |
143 | 引入:
144 |
145 | ```Dart
146 | import 'package:dio/dio.dart';
147 | ```
148 |
149 |
150 | #### GET 请求
151 |
152 | ```Dart
153 | void dio_Get() async {
154 | String result;
155 | try {
156 | Dio dio = new Dio();
157 | var response = await dio.get(getUrl);
158 | if (response.statusCode == HttpStatus.OK) {
159 | result = response.data.toString();
160 | } else {
161 | result =
162 | 'Error getting IP address:\nHttp status ${response.statusCode}';
163 | }
164 | } catch (exception) {
165 | result = 'Failed getting IP address';
166 | }
167 | }
168 | ```
169 |
170 | #### POST 请求
171 |
172 | ```Dart
173 | void dio_Post() async {
174 | String result="";
175 | try {
176 | var dio = new Dio();
177 | var response = await dio.post(postUrl, queryParameters:{"ip": searchIp});
178 | if (response.statusCode == HttpStatus.OK) {
179 | result = response.data.toString();
180 | } else {
181 | result =
182 | 'Error getting IP address:\nHttp status ${response.statusCode}';
183 | }
184 | } catch (exception) {
185 | result = 'Failed getting IP address';
186 | }
187 | }
188 | ```
189 |
190 | #### 其他
191 |
192 | dio 还有好多方法,可以看看这个链接:
193 | [https://pub.dartlang.org/packages/dio](https://pub.dartlang.org/packages/dio)
194 |
195 | ### JSON 解析
196 |
197 | 就直接用下面的方法就可以解析了,真的很方便
198 |
199 | ```Dart
200 | var data = json.decode(result);
201 | result = data['origin'];
202 | ```
203 |
204 |
205 | ### Flutter 学习之路 Github 地址
206 |
207 | 这是项目的 GitHub 地址,正在持续更新,欢迎 Star 呀!╮( ̄▽ ̄)╭
208 |
209 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
--------------------------------------------------------------------------------
/notes/Flutter_Problem_Need_Solve.md:
--------------------------------------------------------------------------------
1 | ## Flutter 想要学习的问题
2 | > 整理一些想要学习或者了解的 Flutter 的东西
3 |
4 | - 在原生 Android 项目里添加 Flutter 代码
5 | - 热更新
6 | - 第三方登录
7 | - 储存
8 | - Flutter 机器学习
9 | - 拍照,视频
10 | - 二维码扫描
11 | - 不同的布局(例如两个控件叠加,一个半透明作为背景,这种要怎么实现)
12 | - 如何看代码结构 -- 例如用 Open DevTools
13 | - Flutter 动画
--------------------------------------------------------------------------------
/notes/Flutter_Problem_Solved.md:
--------------------------------------------------------------------------------
1 | ## Flutter 遇到并解决的问题
2 | > Flutter 遇到并解决的问题
3 |
4 |
5 | #### Dart 代码排版问题
6 |
7 | 1. 在编译器的设置里面可以设置 dart 代码的格式
8 | 2. 在代码界面右键然后选择 **Reformat Code with dartfmt**,排版就 ok了!
9 |
--------------------------------------------------------------------------------
/notes/Flutter_Text.md:
--------------------------------------------------------------------------------
1 | ## Flutter 学习之路 - Text 控件
2 | > 实验一些常用的 Text 功能 ([代码Github地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day1.dart))
3 |
4 | ### Text 实验
5 |
6 | Text 实验了 Text 常用的一些功能
7 |
8 | - 文字大小调整
9 | - 文字颜色设置
10 | - 文字粗体,斜体
11 | - Text 显示的 maxLines 以及 是否换行
12 | - 文字居中
13 | - 文字的装饰(下划线,划去)
14 | - 单词间隙,字母间隙的设置
15 | - 文字点击事件
16 | - 文字拼接
17 |
18 | [代码地址](https://github.com/draftbk/flutter_road/blob/master/flutter_road_widgets/lib/days/Day1.dart)
19 |
20 | 
21 |
22 |
23 | #### Text Style 属性
24 |
25 | 感觉Text的前面的一些地方都是通过改 Text 的属性,可以直接进入我的代码地址看代码看懂的,这边就放一个属性表。
26 |
27 | | 属性 | 意义 |
28 | | ---------- | ----------- |
29 | | fontSize | 文字大小 |
30 | | fontWeight | 文字粗细 |
31 | | color | 文字颜色 |
32 | | fontFamily | 字体 |
33 | | fontStyle | 文字风格(可以设置斜体) |
34 | | wordSpacing | 单词之间的间隙 |
35 | | letterSpacing |字母之间的间隙 |
36 | | locale |区域设置 |
37 | | decoration | 文字装饰(例如下划线,上划线,划去的效果) |
38 | | decorationStyle |文字装饰的风格(例如我上面代码实现的波浪线) |
39 | | decorationColor |文字装饰的颜色 |
40 |
41 | #### 文本点击
42 | 点击事件改变自己参数的时候要用 setState, 不然直接改 _tapText 界面并不会有反应。
43 |
44 | ```
45 | Padding(
46 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
47 | child: GestureDetector(
48 | onTap: () {
49 | setState(() {
50 | if(_tapText=="啊我被点到了"){
51 | _tapText="文字点击事件, 点我!";
52 | }else{
53 | _tapText="啊我被点到了";
54 | }
55 | });
56 | },
57 | child: Text(
58 | _tapText,
59 | style: TextStyle(
60 | fontSize: 16,
61 | fontWeight: FontWeight.bold,
62 | ),
63 | ),
64 | ),
65 | ),
66 | ```
67 |
68 | #### 文本拼接
69 |
70 | 拼接效果可以看上面的动图,感觉拼接是一个很有趣的功能,可以在一段文字里实现不同的功能,或者不同的点击,感觉例如一个英文文档,可以点击不同的文字获取不同的中文翻译这样的功能可以这样实现。
71 |
72 | ```
73 | // 文本拼接
74 | Padding(
75 | padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 0.0),
76 | child: Text.rich(
77 | new TextSpan(
78 | text: '文字拼接: ',
79 | style: new TextStyle(
80 | color: Colors.black,
81 | fontSize: 14,
82 | decoration: TextDecoration.none),
83 | children: [
84 | new TextSpan(
85 | text: "文字一",
86 | style: new TextStyle(
87 | color: Colors.blue,
88 | fontSize: 20,
89 | decoration: TextDecoration.none)),
90 | new TextSpan(
91 | text: "文字二",
92 | style: new TextStyle(
93 | color: Colors.green,
94 | fontSize: 14,
95 | decoration: TextDecoration.none)),
96 | new TextSpan(
97 | text: "文字三",
98 | style: new TextStyle(
99 | color: Colors.red,
100 | fontSize: 18,
101 | decoration: TextDecoration.none)),
102 | ]),
103 | ),
104 | )
105 | ```
106 |
107 | #### Flutter 学习之路 Github 地址
108 |
109 | [https://github.com/draftbk/flutter_road](https://github.com/draftbk/flutter_road)
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------