├── .gitignore
├── .idea
├── codeStyles
│ └── Project.xml
├── libraries
│ ├── Dart_Packages.xml
│ ├── Dart_SDK.xml
│ ├── Flutter_Plugins.xml
│ └── Flutter_for_Android.xml
├── misc.xml
├── modules.xml
├── runConfigurations
│ └── main_dart.xml
├── vcs.xml
└── workspace.xml
├── .metadata
├── .vscode
└── launch.json
├── README.md
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── ninghaoflutter
│ │ │ └── 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.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── flutter_export_environment.sh
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── 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
├── demo
│ ├── alert_dialog_demo.dart
│ ├── animation
│ │ └── animation_demo.dart
│ ├── basic_demo.dart
│ ├── bloc
│ │ ├── bloc_demo.dart
│ │ └── counter_bloc_demo.dart
│ ├── bottom_navigation_bar_demo.dart
│ ├── bottom_sheet_demo.dart
│ ├── button_demo.dart
│ ├── card_demo.dart
│ ├── checkbox_demo.dart
│ ├── chip_demo.dart
│ ├── data_table_demo.dart
│ ├── datetime_demo.dart
│ ├── drawer_demo.dart
│ ├── expansion_panel_demo.dart
│ ├── floating_action_button_demo.dart
│ ├── form_demo.dart
│ ├── hello_demo.dart
│ ├── http
│ │ └── http_demo.dart
│ ├── i18n
│ │ ├── i18n_demo.dart
│ │ ├── intl
│ │ │ ├── intl_en.arb
│ │ │ ├── intl_messages.arb
│ │ │ ├── intl_zh.arb
│ │ │ ├── ninghao_demo_localizations.dart
│ │ │ ├── ninghao_demo_messages_all.dart
│ │ │ ├── ninghao_demo_messages_en.dart
│ │ │ ├── ninghao_demo_messages_messages.dart
│ │ │ └── ninghao_demo_messages_zh.dart
│ │ └── map
│ │ │ └── ninghao_demo_localizations.dart
│ ├── layout_demo.dart
│ ├── listview_demo.dart
│ ├── material_components.dart
│ ├── navigator_demo.dart
│ ├── paginated_data_table_demo.dart
│ ├── popup_menu_button_demo.dart
│ ├── post_show.dart
│ ├── radio_demo.dart
│ ├── rxdart
│ │ └── rxdart_demo.dart
│ ├── simple_dialog_demo.dart
│ ├── slider_demo.dart
│ ├── sliver_demo.dart
│ ├── snack_bar_demo.dart
│ ├── state
│ │ └── state_management_demo.dart
│ ├── stepper_demo.dart
│ ├── stream
│ │ └── stream_demo.dart
│ ├── switch_demo.dart
│ ├── test
│ │ └── test_demo.dart
│ └── view_demo.dart
├── main.dart
└── model
│ └── post.dart
├── ninghao_flutter.iml
├── ninghao_flutter_android.iml
├── pubspec.lock
├── pubspec.yaml
├── test
└── ninghao_demo_test.dart
└── test_driver
├── app.dart
└── app_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 |
9 | .flutter-plugins
10 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_Plugins.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/libraries/Flutter_for_Android.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations/main_dart.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
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 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 | 1533729618709
185 |
186 |
187 | 1533729618709
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
--------------------------------------------------------------------------------
/.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: 66091f969653fd3535b265ddcd87436901858a1d
8 | channel: dev
9 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Flutter",
9 | "request": "launch",
10 | "type": "dart"
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ninghao_flutter
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | For help getting started with Flutter, view our online
8 | [documentation](https://flutter.io/).
9 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | *.class
3 | .gradle
4 | /local.properties
5 | /.idea/workspace.xml
6 | /.idea/libraries
7 | .DS_Store
8 | /build
9 | /captures
10 | GeneratedPluginRegistrant.java
11 |
--------------------------------------------------------------------------------
/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 | throw new GradleException("versionCode not found. Define flutter.versionCode in the local.properties file.")
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | throw new GradleException("versionName not found. Define flutter.versionName in the local.properties file.")
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.example.ninghaoflutter"
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 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
15 |
19 |
26 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/ninghaoflutter/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.ninghaoflutter;
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 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.1.2'
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 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/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.4-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vagrant/
3 | .sconsign.dblite
4 | .svn/
5 |
6 | .DS_Store
7 | *.swp
8 | profile
9 |
10 | DerivedData/
11 | build/
12 | GeneratedPluginRegistrant.h
13 | GeneratedPluginRegistrant.m
14 |
15 | .generated/
16 |
17 | *.pbxuser
18 | *.mode1v3
19 | *.mode2v3
20 | *.perspectivev3
21 |
22 | !default.pbxuser
23 | !default.mode1v3
24 | !default.mode2v3
25 | !default.perspectivev3
26 |
27 | xcuserdata
28 |
29 | *.moved-aside
30 |
31 | *.pyc
32 | *sync/
33 | Icon?
34 | .tags*
35 |
36 | /Flutter/app.flx
37 | /Flutter/app.zip
38 | /Flutter/flutter_assets/
39 | /Flutter/App.framework
40 | /Flutter/Flutter.framework
41 | /Flutter/Generated.xcconfig
42 | /ServiceDefinitions.json
43 |
44 | Pods/
45 | .symlinks/
46 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/flutter_export_environment.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # This is a generated file; do not edit or check into version control.
3 | export "FLUTTER_ROOT=/Applications/flutter"
4 | export "FLUTTER_APPLICATION_PATH=/Users/wanghao/Desktop/ninghao_flutter"
5 | export "FLUTTER_TARGET=/Users/wanghao/Desktop/ninghao_flutter/lib/main.dart"
6 | export "FLUTTER_BUILD_DIR=build"
7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios"
8 | export "FLUTTER_FRAMEWORK_DIR=/Applications/flutter/bin/cache/artifacts/engine/ios"
9 | export "FLUTTER_BUILD_NAME=1.0.0"
10 | export "FLUTTER_BUILD_NUMBER=1"
11 | export "TRACK_WIDGET_CREATION=true"
12 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ninghao/ninghao_flutter/2bb8ee8d96fb33d90d2cc8538d79df3a9b070ff2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/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.
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | ninghao_flutter
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 | CFBundleLocalizations
45 |
46 | en
47 | zh_CN
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/demo/alert_dialog_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'dart:async';
3 |
4 | enum Action {
5 | Ok,
6 | Cancel
7 | }
8 |
9 | class AlertDialogDemo extends StatefulWidget {
10 | @override
11 | _AlertDialogDemoState createState() => _AlertDialogDemoState();
12 | }
13 |
14 | class _AlertDialogDemoState extends State {
15 | String _choice = 'Nothing';
16 |
17 | Future _openAlertDialog() async {
18 | final action = await showDialog(
19 | context: context,
20 | barrierDismissible: false,
21 | builder: (BuildContext context) {
22 | return AlertDialog(
23 | title: Text('AlertDialog'),
24 | content: Text('Are you sure about this?'),
25 | actions: [
26 | FlatButton(
27 | child: Text('Cancel'),
28 | onPressed: () {
29 | Navigator.pop(context, Action.Cancel);
30 | },
31 | ),
32 | FlatButton(
33 | child: Text('Ok'),
34 | onPressed: () {
35 | Navigator.pop(context, Action.Ok);
36 | },
37 | ),
38 | ],
39 | );
40 | },
41 | );
42 |
43 | switch (action) {
44 | case Action.Ok:
45 | setState(() {
46 | _choice = 'Ok';
47 | });
48 | break;
49 | case Action.Cancel:
50 | setState(() {
51 | _choice = 'Cancel';
52 | });
53 | break;
54 | default:
55 | }
56 | }
57 |
58 | @override
59 | Widget build(BuildContext context) {
60 | return Scaffold(
61 | appBar: AppBar(
62 | title: Text('AlertDialogDemo'),
63 | elevation: 0.0,
64 | ),
65 | body: Container(
66 | padding: EdgeInsets.all(16.0),
67 | child: Column(
68 | mainAxisAlignment: MainAxisAlignment.center,
69 | children: [
70 | Text('Your choice is: $_choice'),
71 | SizedBox(height: 16.0,),
72 | Row(
73 | mainAxisAlignment: MainAxisAlignment.center,
74 | children: [
75 | RaisedButton(
76 | child: Text('Open AlertDialog'),
77 | onPressed: _openAlertDialog,
78 | ),
79 | ],
80 | ),
81 | ],
82 | ),
83 | ),
84 | );
85 | }
86 | }
--------------------------------------------------------------------------------
/lib/demo/animation/animation_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class AnimationDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Scaffold(
7 | appBar: AppBar(
8 | title: Text('AnimationDemo'),
9 | elevation: 0.0,
10 | ),
11 | body: AnimationDemoHome());
12 | }
13 | }
14 |
15 | class AnimationDemoHome extends StatefulWidget {
16 | @override
17 | _AnimationDemoHomeState createState() => _AnimationDemoHomeState();
18 | }
19 |
20 | class _AnimationDemoHomeState extends State
21 | with TickerProviderStateMixin {
22 | AnimationController animationDemoController;
23 | Animation animation;
24 | Animation animationColor;
25 | CurvedAnimation curve;
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 |
31 | animationDemoController = AnimationController(
32 | // value: 32.0,
33 | // lowerBound: 32.0,
34 | // upperBound: 100.0,
35 | duration: Duration(milliseconds: 1000),
36 | vsync: this,
37 | );
38 |
39 | curve = CurvedAnimation(
40 | parent: animationDemoController, curve: Curves.bounceOut);
41 |
42 | animation = Tween(begin: 32.0, end: 100.0).animate(curve);
43 | animationColor =
44 | ColorTween(begin: Colors.red, end: Colors.red[900]).animate(curve);
45 |
46 | // animationDemoController.addListener(() {
47 | // // print('${animationDemoController.value}');
48 | // setState(() {});
49 | // });
50 |
51 | animationDemoController.addStatusListener((AnimationStatus status) {
52 | print(status);
53 | });
54 |
55 | // animationDemoController.forward();
56 | }
57 |
58 | @override
59 | void dispose() {
60 | super.dispose();
61 |
62 | animationDemoController.dispose();
63 | }
64 |
65 | @override
66 | Widget build(BuildContext context) {
67 | return Center(
68 | child: AnimatedHeart(
69 | animations: [
70 | animation,
71 | animationColor,
72 | ],
73 | controller: animationDemoController,
74 | ),
75 | );
76 | }
77 | }
78 |
79 | class AnimatedHeart extends AnimatedWidget {
80 | final List animations;
81 | final AnimationController controller;
82 |
83 | AnimatedHeart({
84 | this.animations,
85 | this.controller,
86 | }) : super(listenable: controller);
87 |
88 | @override
89 | Widget build(BuildContext context) {
90 | return IconButton(
91 | icon: Icon(Icons.favorite),
92 | iconSize: animations[0].value,
93 | color: animations[1].value,
94 | onPressed: () {
95 | switch (controller.status) {
96 | case AnimationStatus.completed:
97 | controller.reverse();
98 | break;
99 | default:
100 | controller.forward();
101 | }
102 | },
103 | );
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/lib/demo/basic_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class BasicDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return ContainerBoxDecorationDemo();
7 | }
8 | }
9 |
10 | class ContainerBoxDecorationDemo extends StatelessWidget {
11 | @override
12 | Widget build(BuildContext context) {
13 | return Container(
14 | // color: Colors.grey[100],
15 | decoration: BoxDecoration(
16 | image: DecorationImage(
17 | image: NetworkImage('https://resources.ninghao.org/images/say-hello-to-barry.jpg'),
18 | alignment: Alignment.topCenter,
19 | // repeat: ImageRepeat.repeatY,
20 | fit: BoxFit.cover,
21 | colorFilter: ColorFilter.mode(
22 | Colors.indigoAccent[400].withOpacity(0.5),
23 | BlendMode.hardLight,
24 | ),
25 | ),
26 | ),
27 | child: Row(
28 | mainAxisAlignment: MainAxisAlignment.center,
29 | children: [
30 | Container(
31 | child: Icon(Icons.pool, size: 32.0, color: Colors.white),
32 | // color: Color.fromRGBO(3, 54, 255, 1.0),
33 | padding: EdgeInsets.all(16.0),
34 | margin: EdgeInsets.all(8.0),
35 | width: 90.0,
36 | height: 90.0,
37 | decoration: BoxDecoration(
38 | color: Color.fromRGBO(3, 54, 255, 1.0),
39 | border: Border.all(
40 | color: Colors.indigoAccent[100],
41 | width: 3.0,
42 | style: BorderStyle.solid,
43 | ),
44 | // borderRadius: BorderRadius.circular(16.0),
45 | boxShadow: [
46 | BoxShadow(
47 | offset: Offset(0.0, 16.0),
48 | color: Color.fromRGBO(16, 20, 188, 1.0),
49 | blurRadius: 25.0,
50 | spreadRadius: -9.0,
51 | ),
52 | ],
53 | shape: BoxShape.circle,
54 | // gradient: RadialGradient(
55 | // colors: [
56 | // Color.fromRGBO(7, 102, 255, 1.0),
57 | // Color.fromRGBO(3, 28, 128, 1.0),
58 | // ],
59 | // ),
60 | gradient: LinearGradient(
61 | colors: [
62 | Color.fromRGBO(7, 102, 255, 1.0),
63 | Color.fromRGBO(3, 28, 128, 1.0),
64 | ],
65 | begin: Alignment.topCenter,
66 | end: Alignment.bottomCenter,
67 | ),
68 | ),
69 | ),
70 | ],
71 | ),
72 | );
73 | }
74 | }
75 |
76 | class RichTextDemo extends StatelessWidget {
77 | @override
78 | Widget build(BuildContext context) {
79 | return RichText(
80 | text: TextSpan(
81 | text: 'ninghao',
82 | style: TextStyle(
83 | color: Colors.deepPurpleAccent,
84 | fontSize: 34.0,
85 | fontStyle: FontStyle.italic,
86 | fontWeight: FontWeight.w100,
87 | ),
88 | children: [
89 | TextSpan(
90 | text: '.net',
91 | style: TextStyle(
92 | fontSize: 17.0,
93 | color: Colors.grey,
94 | ),
95 | )
96 | ],
97 | ),
98 | );
99 | }
100 | }
101 |
102 | class TextDemo extends StatelessWidget {
103 | final TextStyle _textStyle = TextStyle(
104 | fontSize: 16.0,
105 | );
106 |
107 | final String _author = '李白';
108 | final String _title = '将进酒';
109 |
110 | @override
111 | Widget build(BuildContext context) {
112 | // TODO: implement build
113 | return Text(
114 | '《 $_title 》—— $_author。君不见黄河之水天上来,奔流到海不复回。君不见高堂明镜悲白发,朝如青丝暮成雪。人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。',
115 | textAlign: TextAlign.left,
116 | style: _textStyle,
117 | maxLines: 3,
118 | overflow: TextOverflow.ellipsis,
119 | );
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/lib/demo/bloc/bloc_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:ninghao_flutter/demo/bloc/counter_bloc_demo.dart';
3 |
4 | class BlocDemo extends StatelessWidget {
5 | @override
6 | Widget build(BuildContext context) {
7 | return CounterProvider(
8 | bloc: CounterBloc(),
9 | child: Scaffold(
10 | appBar: AppBar(
11 | title: Text('BlocDemo'),
12 | elevation: 0.0,
13 | ),
14 | body: CounterHome(),
15 | floatingActionButton: CounterActionButton(),
16 | ),
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/lib/demo/bloc/counter_bloc_demo.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class CounterHome extends StatelessWidget {
6 | @override
7 | Widget build(BuildContext context) {
8 | CounterBloc _counterBloc = CounterProvider.of(context).bloc;
9 |
10 | return Center(
11 | child: StreamBuilder(
12 | initialData: 0,
13 | stream: _counterBloc.count,
14 | builder: (context, snapshot) {
15 | return ActionChip(
16 | label: Text('${snapshot.data}'),
17 | onPressed: () {
18 | // _counterBloc.log();
19 | _counterBloc.counter.add(1);
20 | },
21 | );
22 | },
23 | ),
24 | );
25 | }
26 | }
27 |
28 | class CounterActionButton extends StatelessWidget {
29 | @override
30 | Widget build(BuildContext context) {
31 | CounterBloc _counterBloc = CounterProvider.of(context).bloc;
32 |
33 | return FloatingActionButton(
34 | child: Icon(Icons.add),
35 | onPressed: () {
36 | // _counterBloc.log();
37 | _counterBloc.counter.add(1);
38 | },
39 | );
40 | }
41 | }
42 |
43 | class CounterProvider extends InheritedWidget {
44 | final Widget child;
45 | final CounterBloc bloc;
46 |
47 | CounterProvider({
48 | this.child,
49 | this.bloc,
50 | }) : super(child: child);
51 |
52 | static CounterProvider of(BuildContext context) =>
53 | context.inheritFromWidgetOfExactType(CounterProvider);
54 |
55 | @override
56 | bool updateShouldNotify(CounterProvider oldWidget) {
57 | return true;
58 | }
59 | }
60 |
61 | class CounterBloc {
62 | int _count = 0;
63 |
64 | final _counterActionController = StreamController();
65 | StreamSink get counter => _counterActionController.sink;
66 |
67 | final _counterController = StreamController();
68 | Stream get count => _counterController.stream;
69 |
70 | CounterBloc() {
71 | _counterActionController.stream.listen(onData);
72 | }
73 |
74 | void onData(int data) {
75 | print('$data');
76 | _count = data + _count;
77 | _counterController.add(_count);
78 | }
79 |
80 | void disponse() {
81 | _counterActionController.close();
82 | _counterController.close();
83 | }
84 |
85 | void log() {
86 | print('BLoC');
87 | }
88 | }
--------------------------------------------------------------------------------
/lib/demo/bottom_navigation_bar_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class BottomNavigationBarDemo extends StatefulWidget {
4 | @override
5 | State createState() {
6 | // TODO: implement createState
7 | return _BottomNavigationBarDemoState();
8 | }
9 | }
10 |
11 | class _BottomNavigationBarDemoState extends State {
12 | int _currentIndex = 0;
13 |
14 | void _onTapHandler (int index) {
15 | setState(() {
16 | _currentIndex = index;
17 | });
18 | }
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | // TODO: implement build
23 | return BottomNavigationBar(
24 | currentIndex: _currentIndex,
25 | onTap: _onTapHandler,
26 | type: BottomNavigationBarType.fixed,
27 | fixedColor: Colors.black,
28 | items: [
29 | BottomNavigationBarItem(
30 | icon: Icon(Icons.explore),
31 | title: Text('Explore'),
32 | ),
33 | BottomNavigationBarItem(
34 | icon: Icon(Icons.history),
35 | title: Text('History'),
36 | ),
37 | BottomNavigationBarItem(
38 | icon: Icon(Icons.list),
39 | title: Text('List'),
40 | ),
41 | BottomNavigationBarItem(
42 | icon: Icon(Icons.person),
43 | title: Text('My'),
44 | ),
45 | ],
46 | );
47 | }
48 | }
--------------------------------------------------------------------------------
/lib/demo/bottom_sheet_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'dart:async';
3 |
4 | class BottomSheetDemo extends StatefulWidget {
5 | @override
6 | _BottomSheetDemoState createState() => _BottomSheetDemoState();
7 | }
8 |
9 | class _BottomSheetDemoState extends State {
10 | final _bottomSheetScaffoldKey = GlobalKey();
11 |
12 | _openBottomSheet() {
13 | _bottomSheetScaffoldKey
14 | .currentState
15 | .showBottomSheet((BuildContext context) {
16 | return BottomAppBar(
17 | child: Container(
18 | height: 90.0,
19 | width: double.infinity,
20 | padding: EdgeInsets.all(16.0),
21 | child: Row(
22 | children: [
23 | Icon(Icons.pause_circle_outline),
24 | SizedBox(width: 16.0,),
25 | Text('01:30 / 03:30'),
26 | Expanded(
27 | child: Text('Fix you - Coldplay', textAlign: TextAlign.right,),
28 | ),
29 | ],
30 | ),
31 | ),
32 | );
33 | });
34 | }
35 |
36 | Future _openModalBottomSheet() async {
37 | final option = await showModalBottomSheet(
38 | context: context,
39 | builder: (BuildContext context) {
40 | return Container(
41 | height: 200.0,
42 | child: Column(
43 | children: [
44 | ListTile(
45 | title: Text('Option A'),
46 | onTap: () {
47 | Navigator.pop(context, 'A');
48 | },
49 | ),
50 | ListTile(
51 | title: Text('Option B'),
52 | onTap: () {
53 | Navigator.pop(context, 'B');
54 | },
55 | ),
56 | ListTile(
57 | title: Text('Option C'),
58 | onTap: () {
59 | Navigator.pop(context, 'C');
60 | },
61 | ),
62 | ],
63 | ),
64 | );
65 | }
66 | );
67 |
68 | print(option);
69 | }
70 |
71 | @override
72 | Widget build(BuildContext context) {
73 | return Scaffold(
74 | key: _bottomSheetScaffoldKey,
75 | appBar: AppBar(
76 | title: Text('BottomSheetDemo'),
77 | elevation: 0.0,
78 | ),
79 | body: Container(
80 | padding: EdgeInsets.all(16.0),
81 | child: Column(
82 | mainAxisAlignment: MainAxisAlignment.center,
83 | children: [
84 | Row(
85 | mainAxisAlignment: MainAxisAlignment.center,
86 | children: [
87 | FlatButton(
88 | child: Text('Open BottomSheet'),
89 | onPressed: _openBottomSheet,
90 | ),
91 | FlatButton(
92 | child: Text('Modal BottomSheet'),
93 | onPressed: _openModalBottomSheet,
94 | ),
95 | ]
96 | ),
97 | ],
98 | ),
99 | ),
100 | );
101 | }
102 | }
--------------------------------------------------------------------------------
/lib/demo/button_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ButtonDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | final Widget flatButtonDemo = Row(
7 | mainAxisAlignment: MainAxisAlignment.center,
8 | children: [
9 | FlatButton(
10 | child: Text('Button'),
11 | onPressed: () {},
12 | splashColor: Colors.grey,
13 | textColor: Theme.of(context).accentColor,
14 | ),
15 | FlatButton.icon(
16 | icon: Icon(Icons.add),
17 | label: Text('Button'),
18 | onPressed: () {},
19 | splashColor: Colors.grey,
20 | textColor: Theme.of(context).accentColor,
21 | ),
22 | ],
23 | );
24 |
25 | final Widget raisedButtonDemo = Row(
26 | mainAxisAlignment: MainAxisAlignment.center,
27 | children: [
28 | Theme(
29 | data: Theme.of(context).copyWith(
30 | buttonColor: Theme.of(context).accentColor,
31 | buttonTheme: ButtonThemeData(
32 | textTheme: ButtonTextTheme.primary,
33 | // shape: BeveledRectangleBorder(
34 | // borderRadius: BorderRadius.circular(5.0),
35 | // ),
36 | shape: StadiumBorder(),
37 | ),
38 | ),
39 | child: RaisedButton(
40 | child: Text('Button'),
41 | onPressed: () {},
42 | splashColor: Colors.grey,
43 | elevation: 0.0,
44 | // color: Theme.of(context).accentColor,
45 | // textColor: Colors.white,
46 | // textTheme: ButtonTextTheme.primary,
47 | ),
48 | ),
49 | SizedBox(width: 16.0,),
50 | RaisedButton.icon(
51 | icon: Icon(Icons.add),
52 | label: Text('Button'),
53 | onPressed: () {},
54 | splashColor: Colors.grey,
55 | elevation: 12.0,
56 | textColor: Theme.of(context).accentColor,
57 | ),
58 | ],
59 | );
60 |
61 | final Widget outlineButtonDemo = Row(
62 | mainAxisAlignment: MainAxisAlignment.center,
63 | children: [
64 | Theme(
65 | data: Theme.of(context).copyWith(
66 | buttonColor: Theme.of(context).accentColor,
67 | buttonTheme: ButtonThemeData(
68 | textTheme: ButtonTextTheme.primary,
69 | // shape: BeveledRectangleBorder(
70 | // borderRadius: BorderRadius.circular(5.0),
71 | // ),
72 | shape: StadiumBorder(),
73 | ),
74 | ),
75 | child: OutlineButton(
76 | child: Text('Button'),
77 | onPressed: () {},
78 | splashColor: Colors.grey[100],
79 | borderSide: BorderSide(
80 | color: Colors.black,
81 | ),
82 | // color: Theme.of(context).accentColor,
83 | textColor: Colors.black,
84 | highlightedBorderColor: Colors.grey,
85 | // textTheme: ButtonTextTheme.primary,
86 | ),
87 | ),
88 | SizedBox(width: 16.0,),
89 | OutlineButton.icon(
90 | icon: Icon(Icons.add),
91 | label: Text('Button'),
92 | onPressed: () {},
93 | splashColor: Colors.grey,
94 | textColor: Theme.of(context).accentColor,
95 | ),
96 | ],
97 | );
98 |
99 | final Widget fixedWidthButton = Row(
100 | mainAxisAlignment: MainAxisAlignment.center,
101 | children: [
102 | Container(
103 | width: 130.0,
104 | child: OutlineButton(
105 | child: Text('Button'),
106 | onPressed: () {},
107 | splashColor: Colors.grey[100],
108 | borderSide: BorderSide(
109 | color: Colors.black,
110 | ),
111 | textColor: Colors.black,
112 | highlightedBorderColor: Colors.grey,
113 | ),
114 | ),
115 | ],
116 | );
117 |
118 | final Widget expandedButton = Row(
119 | mainAxisAlignment: MainAxisAlignment.center,
120 | children: [
121 | Expanded(
122 | child: OutlineButton(
123 | child: Text('Button'),
124 | onPressed: () {},
125 | splashColor: Colors.grey[100],
126 | borderSide: BorderSide(
127 | color: Colors.black,
128 | ),
129 | textColor: Colors.black,
130 | highlightedBorderColor: Colors.grey,
131 | ),
132 | ),
133 | SizedBox(width: 16.0,),
134 | Expanded(
135 | flex: 2,
136 | child: OutlineButton(
137 | child: Text('Button'),
138 | onPressed: () {},
139 | splashColor: Colors.grey[100],
140 | borderSide: BorderSide(
141 | color: Colors.black,
142 | ),
143 | textColor: Colors.black,
144 | highlightedBorderColor: Colors.grey,
145 | ),
146 | ),
147 | ],
148 | );
149 |
150 | final Widget buttonBarDemo = Row(
151 | mainAxisAlignment: MainAxisAlignment.center,
152 | children: [
153 | Theme(
154 | data: Theme.of(context).copyWith(
155 | buttonTheme: ButtonThemeData(
156 | padding: EdgeInsets.symmetric(horizontal: 32.0),
157 | ),
158 | ),
159 | child: ButtonBar(
160 | children: [
161 | OutlineButton(
162 | child: Text('Button'),
163 | onPressed: () {},
164 | splashColor: Colors.grey[100],
165 | borderSide: BorderSide(
166 | color: Colors.black,
167 | ),
168 | textColor: Colors.black,
169 | highlightedBorderColor: Colors.grey,
170 | ),
171 | OutlineButton(
172 | child: Text('Button'),
173 | onPressed: () {},
174 | splashColor: Colors.grey[100],
175 | borderSide: BorderSide(
176 | color: Colors.black,
177 | ),
178 | textColor: Colors.black,
179 | highlightedBorderColor: Colors.grey,
180 | ),
181 | ],
182 | ),
183 | ),
184 | ],
185 | );
186 |
187 | return Scaffold(
188 | appBar: AppBar(
189 | title: Text('ButtonDemo'),
190 | elevation: 0.0,
191 | ),
192 | body: Container(
193 | padding: EdgeInsets.all(16.0),
194 | child: Column(
195 | mainAxisAlignment: MainAxisAlignment.center,
196 | children: [
197 | flatButtonDemo,
198 | raisedButtonDemo,
199 | outlineButtonDemo,
200 | fixedWidthButton,
201 | expandedButton,
202 | buttonBarDemo,
203 | ],
204 | ),
205 | )
206 | );
207 | }
208 | }
--------------------------------------------------------------------------------
/lib/demo/card_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../model/post.dart';
3 |
4 | class CardDemo extends StatefulWidget {
5 | @override
6 | _CardDemoState createState() => _CardDemoState();
7 | }
8 |
9 | class _CardDemoState extends State {
10 | @override
11 | Widget build(BuildContext context) {
12 | return Scaffold(
13 | appBar: AppBar(
14 | title: Text('CardDemo'),
15 | elevation: 0.0,
16 | ),
17 | body: Container(
18 | padding: EdgeInsets.all(16.0),
19 | child: ListView(
20 | children: posts.map((post) {
21 | return Card(
22 | child: Column(
23 | children: [
24 | AspectRatio(
25 | aspectRatio: 16/9,
26 | child: ClipRRect(
27 | borderRadius: BorderRadius.only(
28 | topLeft: Radius.circular(4.0),
29 | topRight: Radius.circular(4.0),
30 | ),
31 | child: Image.network(
32 | post.imageUrl,
33 | fit: BoxFit.cover,
34 | ),
35 | ),
36 | ),
37 | ListTile(
38 | leading: CircleAvatar(
39 | backgroundImage: NetworkImage(post.imageUrl),
40 | ),
41 | title: Text(post.title),
42 | subtitle: Text(post.author),
43 | ),
44 | Container(
45 | padding: EdgeInsets.all(16.0),
46 | child: Text(post.description, maxLines: 2, overflow: TextOverflow.ellipsis,),
47 | ),
48 | ButtonTheme.bar(
49 | child: ButtonBar(
50 | children: [
51 | FlatButton(
52 | child: Text('Like'.toUpperCase()),
53 | onPressed: () {},
54 | ),
55 | FlatButton(
56 | child: Text('Read'.toUpperCase()),
57 | onPressed: () {},
58 | ),
59 | ],
60 | ),
61 | ),
62 | ],
63 | ),
64 | );
65 | }).toList(),
66 | ),
67 | )
68 | );
69 | }
70 | }
--------------------------------------------------------------------------------
/lib/demo/checkbox_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class CheckboxDemo extends StatefulWidget {
4 | @override
5 | _CheckboxDemoState createState() => _CheckboxDemoState();
6 | }
7 |
8 | class _CheckboxDemoState extends State {
9 | bool _checkboxItemA = true;
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('CheckboxDemo'),
16 | elevation: 0.0,
17 | ),
18 | body: Container(
19 | padding: EdgeInsets.all(16.0),
20 | child: Column(
21 | mainAxisAlignment: MainAxisAlignment.center,
22 | children: [
23 | CheckboxListTile(
24 | value: _checkboxItemA,
25 | onChanged: (value) {
26 | setState(() {
27 | _checkboxItemA = value;
28 | });
29 | },
30 | title: Text('Checkbox Item A'),
31 | subtitle: Text('Description'),
32 | secondary: Icon(Icons.bookmark),
33 | selected: _checkboxItemA,
34 | ),
35 | Row(
36 | mainAxisAlignment: MainAxisAlignment.center,
37 | children: [
38 | // Checkbox(
39 | // value: _checkboxItemA,
40 | // onChanged: (value) {
41 | // setState(() {
42 | // _checkboxItemA = value;
43 | // });
44 | // },
45 | // activeColor: Colors.black,
46 | // ),
47 | ],
48 | ),
49 | ],
50 | ),
51 | )
52 | );
53 | }
54 | }
--------------------------------------------------------------------------------
/lib/demo/chip_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ChipDemo extends StatefulWidget {
4 | @override
5 | _ChipDemoState createState() => _ChipDemoState();
6 | }
7 |
8 | class _ChipDemoState extends State {
9 | List _tags = [
10 | 'Apple',
11 | 'Banana',
12 | 'Lemon',
13 | ];
14 |
15 | String _action = 'Nothing';
16 | List _selected = [];
17 | String _choice = 'Lemon';
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return Scaffold(
22 | appBar: AppBar(
23 | title: Text('ChipDemo'),
24 | elevation: 0.0,
25 | ),
26 | body: Container(
27 | padding: EdgeInsets.all(16.0),
28 | child: Column(
29 | mainAxisAlignment: MainAxisAlignment.center,
30 | children: [
31 | Wrap(
32 | spacing: 8.0,
33 | runSpacing: 8.0,
34 | children: [
35 | Chip(
36 | label: Text('Life'),
37 | ),
38 | Chip(
39 | label: Text('Sunset'),
40 | backgroundColor: Colors.orange,
41 | ),
42 | Chip(
43 | label: Text('Wanghao'),
44 | avatar: CircleAvatar(
45 | backgroundColor: Colors.grey,
46 | child: Text('皓'),
47 | ),
48 | ),
49 | Chip(
50 | label: Text('Wanghao'),
51 | avatar: CircleAvatar(
52 | backgroundImage: NetworkImage(
53 | 'https://resources.ninghao.net/images/wanghao.jpg'
54 | ),
55 | ),
56 | ),
57 | Chip(
58 | label: Text('City'),
59 | onDeleted: () {},
60 | deleteIcon: Icon(Icons.delete),
61 | deleteIconColor: Colors.redAccent,
62 | deleteButtonTooltipMessage: 'Remove this tag',
63 | ),
64 | Divider(
65 | color: Colors.grey,
66 | height: 32.0,
67 | // indent: 32.0,
68 | ),
69 | Wrap(
70 | spacing: 8.0,
71 | children: _tags.map((tag) {
72 | return Chip(
73 | label: Text(tag),
74 | onDeleted: () {
75 | setState(() {
76 | _tags.remove(tag);
77 | });
78 | },
79 | );
80 | }).toList(),
81 | ),
82 | Divider(
83 | color: Colors.grey,
84 | height: 32.0,
85 | // indent: 32.0,
86 | ),
87 | Container(
88 | width: double.infinity,
89 | child: Text('ActionChip: $_action'),
90 | ),
91 | Wrap(
92 | spacing: 8.0,
93 | children: _tags.map((tag) {
94 | return ActionChip(
95 | label: Text(tag),
96 | onPressed: () {
97 | setState(() {
98 | _action = tag;
99 | });
100 | },
101 | );
102 | }).toList(),
103 | ),
104 | Divider(
105 | color: Colors.grey,
106 | height: 32.0,
107 | // indent: 32.0,
108 | ),
109 | Container(
110 | width: double.infinity,
111 | child: Text('FilterChip: ${_selected.toString()}'),
112 | ),
113 | Wrap(
114 | spacing: 8.0,
115 | children: _tags.map((tag) {
116 | return FilterChip(
117 | label: Text(tag),
118 | selected: _selected.contains(tag),
119 | onSelected: (value) {
120 | setState(() {
121 | if (_selected.contains(tag)) {
122 | _selected.remove(tag);
123 | } else {
124 | _selected.add(tag);
125 | }
126 | });
127 | },
128 | );
129 | }).toList(),
130 | ),
131 | Divider(
132 | color: Colors.grey,
133 | height: 32.0,
134 | // indent: 32.0,
135 | ),
136 | Container(
137 | width: double.infinity,
138 | child: Text('ChoiceChip: $_choice'),
139 | ),
140 | Wrap(
141 | spacing: 8.0,
142 | children: _tags.map((tag) {
143 | return ChoiceChip(
144 | label: Text(tag),
145 | selectedColor: Colors.black,
146 | selected: _choice == tag,
147 | onSelected: (value) {
148 | setState(() {
149 | _choice = tag;
150 | });
151 | },
152 | );
153 | }).toList(),
154 | ),
155 | ],
156 | ),
157 | ],
158 | ),
159 | ),
160 | floatingActionButton: FloatingActionButton(
161 | child: Icon(Icons.restore),
162 | onPressed: () {
163 | setState(() {
164 | _tags = [
165 | 'Apple',
166 | 'Banana',
167 | 'Lemon',
168 | ];
169 |
170 | _selected = [];
171 |
172 | _choice = 'Lemon';
173 | });
174 | },
175 | ),
176 | );
177 | }
178 | }
--------------------------------------------------------------------------------
/lib/demo/data_table_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../model/post.dart';
3 |
4 | class DataTableDemo extends StatefulWidget {
5 | @override
6 | _DataTableDemoState createState() => _DataTableDemoState();
7 | }
8 |
9 | class _DataTableDemoState extends State {
10 | int _sortColumnIndex;
11 | bool _sortAscending = true;
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Scaffold(
16 | appBar: AppBar(
17 | title: Text('DataTableDemo'),
18 | elevation: 0.0,
19 | ),
20 | body: Container(
21 | padding: EdgeInsets.all(16.0),
22 | child: ListView(
23 | children: [
24 | DataTable(
25 | sortColumnIndex: _sortColumnIndex,
26 | sortAscending: _sortAscending,
27 | // onSelectAll: (bool value) {},
28 | columns: [
29 | DataColumn(
30 | label: Text('Title'),
31 | onSort: (int index, bool ascending) {
32 | setState(() {
33 | _sortColumnIndex = index;
34 | _sortAscending = ascending;
35 |
36 | posts.sort((a, b) {
37 | if (!ascending) {
38 | final c = a;
39 | a = b;
40 | b = c;
41 | }
42 |
43 | return a.title.length.compareTo(b.title.length);
44 | });
45 | });
46 | },
47 | ),
48 | DataColumn(
49 | label: Text('Author'),
50 | ),
51 | DataColumn(
52 | label: Text('Image'),
53 | ),
54 | ],
55 | rows: posts.map((post) {
56 | return DataRow(
57 | selected: post.selected,
58 | onSelectChanged: (bool value) {
59 | setState(() {
60 | if (post.selected != value) {
61 | post.selected = value;
62 | }
63 | });
64 | },
65 | cells: [
66 | DataCell(Text(post.title)),
67 | DataCell(Text(post.author)),
68 | DataCell(Image.network(post.imageUrl)),
69 | ]
70 | );
71 | }).toList(),
72 | ),
73 | ],
74 | ),
75 | )
76 | );
77 | }
78 | }
--------------------------------------------------------------------------------
/lib/demo/datetime_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:intl/intl.dart';
3 | import 'dart:async';
4 |
5 | class DateTimeDemo extends StatefulWidget {
6 | @override
7 | _DateTimeDemoState createState() => _DateTimeDemoState();
8 | }
9 |
10 | class _DateTimeDemoState extends State {
11 | DateTime selectedDate = DateTime.now();
12 | TimeOfDay selectedTime = TimeOfDay(hour: 9, minute: 30);
13 |
14 | Future _selectDate() async {
15 | final DateTime date = await showDatePicker(
16 | context: context,
17 | initialDate: selectedDate,
18 | firstDate: DateTime(1900),
19 | lastDate: DateTime(2100),
20 | );
21 |
22 | if (date == null) return;
23 |
24 | setState(() {
25 | selectedDate = date;
26 | });
27 | }
28 |
29 | Future _selectTime() async {
30 | final TimeOfDay time = await showTimePicker(
31 | context: context,
32 | initialTime: selectedTime,
33 | );
34 |
35 | if (time == null) return;
36 |
37 | setState(() {
38 | selectedTime = time;
39 | });
40 | }
41 |
42 | @override
43 | Widget build(BuildContext context) {
44 | return Scaffold(
45 | appBar: AppBar(
46 | title: Text('DateTimeDemo'),
47 | elevation: 0.0,
48 | ),
49 | body: Container(
50 | padding: EdgeInsets.all(16.0),
51 | child: Column(
52 | mainAxisAlignment: MainAxisAlignment.center,
53 | children: [
54 | Row(
55 | mainAxisAlignment: MainAxisAlignment.center,
56 | children: [
57 | InkWell(
58 | onTap: _selectDate,
59 | child: Row(
60 | children: [
61 | Text(DateFormat.yMMMMd().format(selectedDate)),
62 | Icon(Icons.arrow_drop_down),
63 | ],
64 | ),
65 | ),
66 | InkWell(
67 | onTap: _selectTime,
68 | child: Row(
69 | children: [
70 | Text(selectedTime.format(context)),
71 | Icon(Icons.arrow_drop_down),
72 | ],
73 | ),
74 | ),
75 | ],
76 | ),
77 | ],
78 | ),
79 | )
80 | );
81 | }
82 | }
--------------------------------------------------------------------------------
/lib/demo/drawer_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DrawerDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | // TODO: implement build
7 | return Drawer(
8 | child: ListView(
9 | padding: EdgeInsets.zero,
10 | children: [
11 | UserAccountsDrawerHeader(
12 | accountName:
13 | Text('wanghao', style: TextStyle(fontWeight: FontWeight.bold)),
14 | accountEmail: Text('wanghao@ninghao.net'),
15 | currentAccountPicture: CircleAvatar(
16 | backgroundImage: NetworkImage(
17 | 'https://resources.ninghao.org/images/wanghao.jpg'),
18 | ),
19 | decoration: BoxDecoration(
20 | color: Colors.yellow[400],
21 | image: DecorationImage(
22 | image: NetworkImage(
23 | 'https://resources.ninghao.org/images/childhood-in-a-picture.jpg'),
24 | fit: BoxFit.cover,
25 | colorFilter: ColorFilter.mode(
26 | Colors.yellow[400].withOpacity(0.6), BlendMode.hardLight),
27 | ),
28 | ),
29 | ),
30 | ListTile(
31 | title: Text(
32 | 'Messages',
33 | textAlign: TextAlign.right,
34 | ),
35 | trailing: Icon(Icons.message, color: Colors.black12, size: 22.0),
36 | onTap: () => Navigator.pop(context),
37 | ),
38 | ListTile(
39 | title: Text(
40 | 'Favorite',
41 | textAlign: TextAlign.right,
42 | ),
43 | trailing: Icon(Icons.favorite, color: Colors.black12, size: 22.0),
44 | onTap: () => Navigator.pop(context),
45 | ),
46 | ListTile(
47 | title: Text(
48 | 'Settings',
49 | textAlign: TextAlign.right,
50 | ),
51 | trailing: Icon(Icons.settings, color: Colors.black12, size: 22.0),
52 | onTap: () => Navigator.pop(context),
53 | ),
54 | ],
55 | ),
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/lib/demo/expansion_panel_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ExpansionPanelItem {
4 | final String headerText;
5 | final Widget body;
6 | bool isExpanded;
7 |
8 | ExpansionPanelItem({
9 | this.headerText,
10 | this.body,
11 | this.isExpanded,
12 | });
13 | }
14 |
15 | class ExpansionPanelDemo extends StatefulWidget {
16 | @override
17 | _ExpansionPanelDemoState createState() => _ExpansionPanelDemoState();
18 | }
19 |
20 | class _ExpansionPanelDemoState extends State {
21 | List _expansionPanelItems;
22 |
23 | @override
24 | void initState() {
25 | super.initState();
26 |
27 | _expansionPanelItems = [
28 | ExpansionPanelItem(
29 | headerText: 'Panel A',
30 | body: Container(
31 | padding: EdgeInsets.all(16.0),
32 | width: double.infinity,
33 | child: Text('Content for Panel A.'),
34 | ),
35 | isExpanded: false,
36 | ),
37 | ExpansionPanelItem(
38 | headerText: 'Panel B',
39 | body: Container(
40 | padding: EdgeInsets.all(16.0),
41 | width: double.infinity,
42 | child: Text('Content for Panel B.'),
43 | ),
44 | isExpanded: false,
45 | ),
46 | ExpansionPanelItem(
47 | headerText: 'Panel C',
48 | body: Container(
49 | padding: EdgeInsets.all(16.0),
50 | width: double.infinity,
51 | child: Text('Content for Panel C.'),
52 | ),
53 | isExpanded: false,
54 | ),
55 | ];
56 | }
57 |
58 | @override
59 | Widget build(BuildContext context) {
60 | return Scaffold(
61 | appBar: AppBar(
62 | title: Text('ExpansionPanelDemo'),
63 | elevation: 0.0,
64 | ),
65 | body: Container(
66 | padding: EdgeInsets.all(16.0),
67 | child: Column(
68 | mainAxisAlignment: MainAxisAlignment.center,
69 | children: [
70 | ExpansionPanelList(
71 | expansionCallback: (int panelIndex, bool isExpanded) {
72 | setState(() {
73 | _expansionPanelItems[panelIndex].isExpanded = !isExpanded;
74 | });
75 | },
76 | children: _expansionPanelItems.map(
77 | (ExpansionPanelItem item) {
78 | return ExpansionPanel(
79 | isExpanded: item.isExpanded,
80 | body: item.body,
81 | headerBuilder: (BuildContext context, bool isExpanded) {
82 | return Container(
83 | padding: EdgeInsets.all(16.0),
84 | child: Text(
85 | item.headerText,
86 | style: Theme.of(context).textTheme.title,
87 | ),
88 | );
89 | },
90 | );
91 | }
92 | ).toList(),
93 | ),
94 | ],
95 | ),
96 | ),
97 | );
98 | }
99 | }
--------------------------------------------------------------------------------
/lib/demo/floating_action_button_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class FloatingActionButtonDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | final Widget _floatingActionButton = FloatingActionButton(
7 | onPressed: () {},
8 | child: Icon(Icons.add),
9 | elevation: 0.0,
10 | backgroundColor: Colors.black87,
11 | // shape: BeveledRectangleBorder(
12 | // borderRadius: BorderRadius.circular(30.0)
13 | // ),
14 | );
15 |
16 | final Widget _floatingActionButtonExtended = FloatingActionButton.extended(
17 | onPressed: () {},
18 | icon: Icon(Icons.add),
19 | label: Text('Add'),
20 | );
21 |
22 | return Scaffold(
23 | appBar: AppBar(
24 | title: Text('FloatingActionButtonDemo'),
25 | elevation: 0.0,
26 | ),
27 | floatingActionButton: _floatingActionButton,
28 | floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
29 | bottomNavigationBar: BottomAppBar(
30 | child: Container(
31 | height: 80.0,
32 | ),
33 | shape: CircularNotchedRectangle(),
34 | ),
35 | );
36 | }
37 | }
--------------------------------------------------------------------------------
/lib/demo/form_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class FormDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Scaffold(
7 | appBar: AppBar(
8 | title: Text('FormDemo'),
9 | elevation: 0.0,
10 | ),
11 | body: Theme(
12 | data: Theme.of(context).copyWith(
13 | primaryColor: Colors.black,
14 | ),
15 | child: Container(
16 | padding: EdgeInsets.all(16.0),
17 | child: Column(
18 | mainAxisAlignment: MainAxisAlignment.center,
19 | children: [
20 | RegisterForm(),
21 | ],
22 | ),
23 | ),
24 | ),
25 | );
26 | }
27 | }
28 |
29 | class RegisterForm extends StatefulWidget {
30 | @override
31 | RegisterFormState createState() => RegisterFormState();
32 | }
33 |
34 | class RegisterFormState extends State {
35 | final registerFormKey = GlobalKey();
36 | String username, password;
37 | bool autovalidate = false;
38 |
39 | void submitRegisterForm() {
40 | if (registerFormKey.currentState.validate()) {
41 | registerFormKey.currentState.save();
42 |
43 | debugPrint('username: $username');
44 | debugPrint('password: $password');
45 |
46 | Scaffold.of(context).showSnackBar(
47 | SnackBar(
48 | content: Text('Registering...'),
49 | )
50 | );
51 | } else {
52 | setState(() {
53 | autovalidate = true;
54 | });
55 | }
56 | }
57 |
58 | String validateUsername(value) {
59 | if (value.isEmpty) {
60 | return 'Username is required.';
61 | }
62 |
63 | return null;
64 | }
65 |
66 | String validatePassword(value) {
67 | if (value.isEmpty) {
68 | return 'Password is required.';
69 | }
70 |
71 | return null;
72 | }
73 |
74 | @override
75 | Widget build(BuildContext context) {
76 | return Form(
77 | key: registerFormKey,
78 | child: Column(
79 | children: [
80 | TextFormField(
81 | decoration: InputDecoration(
82 | labelText: 'Username',
83 | helperText: '',
84 | ),
85 | onSaved: (value) {
86 | username = value;
87 | },
88 | validator: validateUsername,
89 | autovalidate: autovalidate,
90 | ),
91 | TextFormField(
92 | obscureText: true,
93 | decoration: InputDecoration(
94 | labelText: 'Password',
95 | helperText: '',
96 | ),
97 | onSaved: (value) {
98 | password = value;
99 | },
100 | validator: validatePassword,
101 | autovalidate: autovalidate,
102 | ),
103 | SizedBox(height: 32.0,),
104 | Container(
105 | width: double.infinity,
106 | child: RaisedButton(
107 | color: Theme.of(context).accentColor,
108 | child: Text('Register', style: TextStyle(color: Colors.white)),
109 | elevation: 0.0,
110 | onPressed: submitRegisterForm,
111 | ),
112 | ),
113 | ],
114 | ),
115 | );
116 | }
117 | }
118 |
119 | class TextFieldDemo extends StatefulWidget {
120 | @override
121 | TextFieldDemoState createState() => TextFieldDemoState();
122 | }
123 |
124 | class TextFieldDemoState extends State {
125 | final textEditingController = TextEditingController();
126 |
127 | @override
128 | void dispose() {
129 | textEditingController.dispose();
130 | super.dispose();
131 | }
132 |
133 | @override
134 | void initState() {
135 | super.initState();
136 | // textEditingController.text = 'hi';
137 | textEditingController.addListener(
138 | () {
139 | debugPrint('input: ${textEditingController.text}');
140 | }
141 | );
142 | }
143 |
144 | @override
145 | Widget build(BuildContext context) {
146 | return TextField(
147 | controller: textEditingController,
148 | // onChanged: (value) {
149 | // debugPrint('input: $value');
150 | // },
151 | onSubmitted: (value) {
152 | debugPrint('submit: $value');
153 | },
154 | decoration: InputDecoration(
155 | icon: Icon(Icons.subject),
156 | labelText: 'Title',
157 | hintText: 'Enter the post title.',
158 | // border: InputBorder.none,
159 | // border: OutlineInputBorder(),
160 | filled: true,
161 | ),
162 | );
163 | }
164 | }
165 |
166 | class ThemeDemo extends StatelessWidget {
167 | @override
168 | Widget build(BuildContext context) {
169 | return Container(
170 | color: Theme.of(context).accentColor,
171 | );
172 | }
173 | }
--------------------------------------------------------------------------------
/lib/demo/hello_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class Hello extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Center(
7 | child: Text(
8 | 'hello',
9 | textDirection: TextDirection.ltr,
10 | style: TextStyle(
11 | fontSize: 40.0,
12 | fontWeight: FontWeight.bold,
13 | color: Colors.black87,
14 | )
15 | ),
16 | );
17 | }
18 | }
--------------------------------------------------------------------------------
/lib/demo/http/http_demo.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:http/http.dart' as http;
5 | import 'dart:async';
6 |
7 | class HttpDemo extends StatelessWidget {
8 | @override
9 | Widget build(BuildContext context) {
10 | return Scaffold(
11 | appBar: AppBar(
12 | title: Text('HttpDemo'),
13 | elevation: 0.0,
14 | ),
15 | body: HttpDemoHome(),
16 | );
17 | }
18 | }
19 |
20 | class HttpDemoHome extends StatefulWidget {
21 | @override
22 | _HttpDemoHomeState createState() => _HttpDemoHomeState();
23 | }
24 |
25 | class _HttpDemoHomeState extends State {
26 | @override
27 | void initState() {
28 | super.initState();
29 | // fetchPosts()
30 | // .then((value) => print(value));
31 |
32 | // final post = {
33 | // 'title': 'hello',
34 | // 'description': 'nice to meet you.',
35 | // };
36 |
37 | // print(post['title']);
38 | // print(post['description']);
39 |
40 | // final postJson = json.encode(post);
41 | // print(postJson);
42 |
43 | // final postJsonConverted = json.decode(postJson);
44 | // print(postJsonConverted['title']);
45 | // print(postJsonConverted['description']);
46 | // print(postJsonConverted is Map);
47 |
48 | // final postModel = Post.fromJson(postJsonConverted);
49 | // print('title: ${postModel.title}, description: ${postModel.description}');
50 |
51 | // print('${json.encode(postModel)}');
52 | }
53 |
54 | Future> fetchPosts() async {
55 | final response =
56 | await http.get('https://resources.ninghao.net/demo/posts.json');
57 |
58 | // print('statusCode: ${response.statusCode}');
59 | // print('body: ${response.body}');
60 |
61 | if (response.statusCode == 200) {
62 | final responseBody = json.decode(response.body);
63 | List posts = responseBody['posts']
64 | .map((item) => Post.fromJson(item))
65 | .toList();
66 |
67 | return posts;
68 | } else {
69 | throw Exception('Failed to fetch posts.');
70 | }
71 | }
72 |
73 | @override
74 | Widget build(BuildContext context) {
75 | return FutureBuilder(
76 | future: fetchPosts(),
77 | builder: (BuildContext context, AsyncSnapshot snapshot) {
78 | print('data: ${snapshot.data}');
79 | print('connectionState: ${snapshot.connectionState}');
80 |
81 | if (snapshot.connectionState == ConnectionState.waiting) {
82 | return Center(
83 | child: Text('loading...'),
84 | );
85 | }
86 |
87 | return ListView(
88 | children: snapshot.data.map((item) {
89 | return ListTile(
90 | title: Text(item.title),
91 | subtitle: Text(item.author),
92 | leading: CircleAvatar(
93 | backgroundImage: NetworkImage(item.imageUrl),
94 | ),
95 | );
96 | }).toList(),
97 | );
98 | },
99 | );
100 | }
101 | }
102 |
103 | class Post {
104 | final int id;
105 | final String title;
106 | final String description;
107 | final String author;
108 | final String imageUrl;
109 |
110 | Post(
111 | this.id,
112 | this.title,
113 | this.description,
114 | this.author,
115 | this.imageUrl,
116 | );
117 |
118 | Post.fromJson(Map json)
119 | : id = json['id'],
120 | title = json['title'],
121 | description = json['description'],
122 | author = json['author'],
123 | imageUrl = json['imageUrl'];
124 |
125 | Map toJson() => {
126 | 'title': title,
127 | 'descritpion': description,
128 | };
129 | }
130 |
--------------------------------------------------------------------------------
/lib/demo/i18n/i18n_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | // import 'package:ninghao_flutter/demo/i18n/map/ninghao_demo_localizations.dart';
3 | import 'package:ninghao_flutter/demo/i18n/intl/ninghao_demo_localizations.dart';
4 |
5 | class I18nDemo extends StatelessWidget {
6 | @override
7 | Widget build(BuildContext context) {
8 | Locale locale = Localizations.localeOf(context);
9 |
10 | return Scaffold(
11 | appBar: AppBar(
12 | title: Text('I18nDemo'),
13 | elevation: 0.0,
14 | ),
15 | body: Center(
16 | child: Column(
17 | mainAxisAlignment: MainAxisAlignment.center,
18 | children: [
19 | Text(locale.toString()),
20 | Text(
21 | // Localizations.of(context, NinghaoDemoLocalizations).title,
22 | // NinghaoDemoLocalizations.of(context).title,
23 | NinghaoDemoLocalizations.of(context).greet('ninghao'),
24 | style: Theme.of(context).textTheme.title,
25 | )
26 | ],
27 | ),
28 | )
29 | );
30 | }
31 | }
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/intl_en.arb:
--------------------------------------------------------------------------------
1 | {
2 | "@@last_modified": "2018-10-19T15:45:15.386436",
3 | "title": "hello",
4 | "@title": {
5 | "description": "demo localizations.",
6 | "type": "text",
7 | "placeholders": {}
8 | },
9 | "greet": "hello {name}",
10 | "@greet": {
11 | "description": "greet someone.",
12 | "type": "text",
13 | "placeholders": {
14 | "name": {}
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/intl_messages.arb:
--------------------------------------------------------------------------------
1 | {
2 | "@@last_modified": "2018-10-19T15:45:15.386436",
3 | "title": "hello",
4 | "@title": {
5 | "description": "demo localizations.",
6 | "type": "text",
7 | "placeholders": {}
8 | },
9 | "greet": "hello {name}",
10 | "@greet": {
11 | "description": "greet someone.",
12 | "type": "text",
13 | "placeholders": {
14 | "name": {}
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/intl_zh.arb:
--------------------------------------------------------------------------------
1 | {
2 | "@@last_modified": "2018-10-19T15:45:15.386436",
3 | "title": "您好",
4 | "@title": {
5 | "description": "演示本地化",
6 | "type": "text",
7 | "placeholders": {}
8 | },
9 | "greet": "您好 {name}",
10 | "@greet": {
11 | "description": "问候某人",
12 | "type": "text",
13 | "placeholders": {
14 | "name": {}
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/ninghao_demo_localizations.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:intl/intl.dart';
3 | import 'ninghao_demo_messages_all.dart';
4 |
5 | class NinghaoDemoLocalizations {
6 | static NinghaoDemoLocalizations of(BuildContext context) {
7 | return Localizations.of(
8 | context,
9 | NinghaoDemoLocalizations
10 | );
11 | }
12 |
13 | static Future load(Locale locale) {
14 | final String name =
15 | locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
16 |
17 | final String localeName = Intl.canonicalizedLocale(name);
18 |
19 | return initializeMessages(localeName).then((bool _) {
20 | Intl.defaultLocale = localeName;
21 | return NinghaoDemoLocalizations();
22 | });
23 | }
24 |
25 | String get title => Intl.message(
26 | 'hello',
27 | name: 'title',
28 | desc: 'demo localizations.',
29 | );
30 |
31 | String greet(String name) => Intl.message(
32 | 'hello $name',
33 | name: 'greet',
34 | desc: 'greet someone.',
35 | args: [name],
36 | );
37 | }
38 |
39 | class NinghaoDemoLocalizationsDelegate
40 | extends LocalizationsDelegate {
41 | NinghaoDemoLocalizationsDelegate();
42 |
43 | @override
44 | Future load(Locale locale) {
45 | return NinghaoDemoLocalizations.load(locale);
46 | }
47 |
48 | @override
49 | bool isSupported(Locale locale) {
50 | return true;
51 | }
52 |
53 | @override
54 | bool shouldReload(LocalizationsDelegate old) {
55 | return false;
56 | }
57 | }
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/ninghao_demo_messages_all.dart:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
2 | // This is a library that looks up messages for specific locales by
3 | // delegating to the appropriate library.
4 |
5 | import 'dart:async';
6 |
7 | import 'package:intl/intl.dart';
8 | import 'package:intl/message_lookup_by_library.dart';
9 | // ignore: implementation_imports
10 | import 'package:intl/src/intl_helpers.dart';
11 |
12 | import 'ninghao_demo_messages_en.dart' as messages_en;
13 | import 'ninghao_demo_messages_messages.dart' as messages_messages;
14 | import 'ninghao_demo_messages_zh.dart' as messages_zh;
15 |
16 | typedef Future LibraryLoader();
17 | Map _deferredLibraries = {
18 | // ignore: unnecessary_new
19 | 'en': () => new Future.value(null),
20 | // ignore: unnecessary_new
21 | 'messages': () => new Future.value(null),
22 | // ignore: unnecessary_new
23 | 'zh': () => new Future.value(null),
24 | };
25 |
26 | MessageLookupByLibrary _findExact(localeName) {
27 | switch (localeName) {
28 | case 'en':
29 | return messages_en.messages;
30 | case 'messages':
31 | return messages_messages.messages;
32 | case 'zh':
33 | return messages_zh.messages;
34 | default:
35 | return null;
36 | }
37 | }
38 |
39 | /// User programs should call this before using [localeName] for messages.
40 | Future initializeMessages(String localeName) async {
41 | var availableLocale = Intl.verifiedLocale(
42 | localeName,
43 | (locale) => _deferredLibraries[locale] != null,
44 | onFailure: (_) => null);
45 | if (availableLocale == null) {
46 | // ignore: unnecessary_new
47 | return new Future.value(false);
48 | }
49 | var lib = _deferredLibraries[availableLocale];
50 | // ignore: unnecessary_new
51 | await (lib == null ? new Future.value(false) : lib());
52 | // ignore: unnecessary_new
53 | initializeInternalMessageLookup(() => new CompositeMessageLookup());
54 | messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor);
55 | // ignore: unnecessary_new
56 | return new Future.value(true);
57 | }
58 |
59 | bool _messagesExistFor(String locale) {
60 | try {
61 | return _findExact(locale) != null;
62 | } catch (e) {
63 | return false;
64 | }
65 | }
66 |
67 | MessageLookupByLibrary _findGeneratedMessagesFor(locale) {
68 | var actualLocale = Intl.verifiedLocale(locale, _messagesExistFor,
69 | onFailure: (_) => null);
70 | if (actualLocale == null) return null;
71 | return _findExact(actualLocale);
72 | }
73 |
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/ninghao_demo_messages_en.dart:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
2 | // This is a library that provides messages for a en locale. All the
3 | // messages from the main program should be duplicated here with the same
4 | // function name.
5 |
6 | import 'package:intl/intl.dart';
7 | import 'package:intl/message_lookup_by_library.dart';
8 |
9 | // ignore: unnecessary_new
10 | final messages = new MessageLookup();
11 |
12 | // ignore: unused_element
13 | final _keepAnalysisHappy = Intl.defaultLocale;
14 |
15 | // ignore: non_constant_identifier_names
16 | typedef MessageIfAbsent(String message_str, List args);
17 |
18 | class MessageLookup extends MessageLookupByLibrary {
19 | get localeName => 'en';
20 |
21 | static m0(name) => "hello ${name}";
22 |
23 | final messages = _notInlinedMessages(_notInlinedMessages);
24 | static _notInlinedMessages(_) => {
25 | "greet" : m0,
26 | "title" : MessageLookupByLibrary.simpleMessage("hello")
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/ninghao_demo_messages_messages.dart:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
2 | // This is a library that provides messages for a messages locale. All the
3 | // messages from the main program should be duplicated here with the same
4 | // function name.
5 |
6 | import 'package:intl/intl.dart';
7 | import 'package:intl/message_lookup_by_library.dart';
8 |
9 | // ignore: unnecessary_new
10 | final messages = new MessageLookup();
11 |
12 | // ignore: unused_element
13 | final _keepAnalysisHappy = Intl.defaultLocale;
14 |
15 | // ignore: non_constant_identifier_names
16 | typedef MessageIfAbsent(String message_str, List args);
17 |
18 | class MessageLookup extends MessageLookupByLibrary {
19 | get localeName => 'messages';
20 |
21 | static m0(name) => "hello ${name}";
22 |
23 | final messages = _notInlinedMessages(_notInlinedMessages);
24 | static _notInlinedMessages(_) => {
25 | "greet" : m0,
26 | "title" : MessageLookupByLibrary.simpleMessage("hello")
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/lib/demo/i18n/intl/ninghao_demo_messages_zh.dart:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
2 | // This is a library that provides messages for a zh locale. All the
3 | // messages from the main program should be duplicated here with the same
4 | // function name.
5 |
6 | import 'package:intl/intl.dart';
7 | import 'package:intl/message_lookup_by_library.dart';
8 |
9 | // ignore: unnecessary_new
10 | final messages = new MessageLookup();
11 |
12 | // ignore: unused_element
13 | final _keepAnalysisHappy = Intl.defaultLocale;
14 |
15 | // ignore: non_constant_identifier_names
16 | typedef MessageIfAbsent(String message_str, List args);
17 |
18 | class MessageLookup extends MessageLookupByLibrary {
19 | get localeName => 'zh';
20 |
21 | static m0(name) => "您好 ${name}";
22 |
23 | final messages = _notInlinedMessages(_notInlinedMessages);
24 | static _notInlinedMessages(_) => {
25 | "greet" : m0,
26 | "title" : MessageLookupByLibrary.simpleMessage("您好")
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/lib/demo/i18n/map/ninghao_demo_localizations.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart' show SynchronousFuture;
2 | import 'package:flutter/material.dart';
3 |
4 | class NinghaoDemoLocalizations {
5 | final Locale locale;
6 |
7 | NinghaoDemoLocalizations(this.locale);
8 |
9 | static NinghaoDemoLocalizations of(BuildContext context) {
10 | return Localizations.of(
11 | context,
12 | NinghaoDemoLocalizations
13 | );
14 | }
15 |
16 | static Map> _localized = {
17 | 'en': {
18 | 'title': 'hello',
19 | },
20 | 'zh': {
21 | 'title': '您好',
22 | }
23 | };
24 |
25 | String get title {
26 | return _localized[locale.languageCode]['title'];
27 | }
28 | }
29 |
30 | class NinghaoDemoLocalizationsDelegate
31 | extends LocalizationsDelegate {
32 | NinghaoDemoLocalizationsDelegate();
33 |
34 | @override
35 | Future load(Locale locale) {
36 | return SynchronousFuture(
37 | NinghaoDemoLocalizations(locale));
38 | }
39 |
40 | @override
41 | bool isSupported(Locale locale) {
42 | return true;
43 | }
44 |
45 | @override
46 | bool shouldReload(LocalizationsDelegate old) {
47 | return false;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/lib/demo/layout_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class LayoutDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Container(
7 | child: Column(
8 | mainAxisAlignment: MainAxisAlignment.center,
9 | children: [
10 | StackDemo(),
11 | ],
12 | ),
13 | );
14 | }
15 | }
16 |
17 | class ConstrainedBoxDemo extends StatelessWidget {
18 | @override
19 | Widget build(BuildContext context) {
20 | return ConstrainedBox(
21 | constraints: BoxConstraints(
22 | minHeight: 200.0,
23 | maxWidth: 200.0,
24 | ),
25 | child: Container(
26 | color: Color.fromRGBO(3, 54, 255, 1.0),
27 | ),
28 | );
29 | }
30 | }
31 |
32 | class AspectRatioDemo extends StatelessWidget {
33 | @override
34 | Widget build(BuildContext context) {
35 | return AspectRatio(
36 | aspectRatio: 16.0 / 9.0,
37 | child: Container(
38 | color: Color.fromRGBO(3, 54, 255, 1.0),
39 | ),
40 | );
41 | }
42 | }
43 |
44 | class StackDemo extends StatelessWidget {
45 | @override
46 | Widget build(BuildContext context) {
47 | return Stack(
48 | alignment: Alignment.topLeft,
49 | children: [
50 | SizedBox(
51 | width: 200.0,
52 | height: 300.0,
53 | child: Container(
54 | alignment: Alignment(0.0, -0.9),
55 | decoration: BoxDecoration(
56 | color: Color.fromRGBO(3, 54, 255, 1.0),
57 | borderRadius: BorderRadius.circular(8.0),
58 | ),
59 | ),
60 | ),
61 | SizedBox(
62 | height: 32.0,
63 | ),
64 | SizedBox(
65 | width: 100.0,
66 | height: 100.0,
67 | child: Container(
68 | decoration: BoxDecoration(
69 | color: Color.fromRGBO(3, 54, 255, 1.0),
70 | shape: BoxShape.circle,
71 | gradient: RadialGradient(colors: [
72 | Color.fromRGBO(7, 102, 255, 1.0),
73 | Color.fromRGBO(3, 54, 255, 1.0),
74 | ]),
75 | ),
76 | child: Icon(Icons.brightness_2, color: Colors.white, size: 32.0),
77 | ),
78 | ),
79 | Positioned(
80 | right: 20.0,
81 | top: 20.0,
82 | child: Icon(Icons.ac_unit, color: Colors.white, size: 16.0),
83 | ),
84 | Positioned(
85 | right: 40.0,
86 | top: 60.0,
87 | child: Icon(Icons.ac_unit, color: Colors.white, size: 18.0),
88 | ),
89 | Positioned(
90 | right: 20.0,
91 | top: 120.0,
92 | child: Icon(Icons.ac_unit, color: Colors.white, size: 20.0),
93 | ),
94 | Positioned(
95 | right: 70.0,
96 | top: 180.0,
97 | child: Icon(Icons.ac_unit, color: Colors.white, size: 16.0),
98 | ),
99 | Positioned(
100 | right: 30.0,
101 | top: 230.0,
102 | child: Icon(Icons.ac_unit, color: Colors.white, size: 18.0),
103 | ),
104 | Positioned(
105 | right: 90.0,
106 | bottom: 20.0,
107 | child: Icon(Icons.ac_unit, color: Colors.white, size: 16.0),
108 | ),
109 | Positioned(
110 | right: 4.0,
111 | bottom: -4.0,
112 | child: Icon(Icons.ac_unit, color: Colors.white, size: 16.0),
113 | ),
114 | ],
115 | );
116 | }
117 | }
118 |
119 | class IconBadge extends StatelessWidget {
120 | final IconData icon;
121 | final double size;
122 |
123 | IconBadge(this.icon, {this.size = 32.0});
124 |
125 | @override
126 | Widget build(BuildContext context) {
127 | return Container(
128 | child: Icon(icon, size: size, color: Colors.white),
129 | width: size + 60,
130 | height: size + 60,
131 | color: Color.fromRGBO(3, 54, 255, 1.0),
132 | );
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/lib/demo/listview_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import './post_show.dart';
3 | import '../model/post.dart';
4 |
5 | class ListViewDemo extends StatelessWidget {
6 | Widget _listItemBuilder(BuildContext context, int index) {
7 | return Container(
8 | color: Colors.white,
9 | margin: EdgeInsets.all(8.0),
10 | child: Stack(
11 | children: [
12 | Column(
13 | children: [
14 | AspectRatio(
15 | aspectRatio: 16/9,
16 | child: Image.network(posts[index].imageUrl, fit: BoxFit.cover),
17 | ),
18 | SizedBox(height: 16.0),
19 | Text(
20 | posts[index].title,
21 | style: Theme.of(context).textTheme.title
22 | ),
23 | Text(
24 | posts[index].author,
25 | style: Theme.of(context).textTheme.subhead
26 | ),
27 | SizedBox(height: 16.0),
28 | ],
29 | ),
30 | Positioned.fill(
31 | child: Material(
32 | color: Colors.transparent,
33 | child: InkWell(
34 | splashColor: Colors.white.withOpacity(0.3),
35 | highlightColor: Colors.white.withOpacity(0.1),
36 | onTap: () {
37 | Navigator.of(context).push(
38 | MaterialPageRoute(builder: (context) => PostShow(post: posts[index]))
39 | );
40 | }
41 | ),
42 | ),
43 | ),
44 | ],
45 | ),
46 | );
47 | }
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | // TODO: implement build
52 | return ListView.builder(
53 | itemCount: posts.length,
54 | itemBuilder: _listItemBuilder,
55 | );
56 | }
57 | }
--------------------------------------------------------------------------------
/lib/demo/material_components.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import './button_demo.dart';
3 | import './floating_action_button_demo.dart';
4 | import './popup_menu_button_demo.dart';
5 | import './form_demo.dart';
6 | import './checkbox_demo.dart';
7 | import './radio_demo.dart';
8 | import './switch_demo.dart';
9 | import './slider_demo.dart';
10 | import './datetime_demo.dart';
11 | import './simple_dialog_demo.dart';
12 | import './alert_dialog_demo.dart';
13 | import './bottom_sheet_demo.dart';
14 | import './snack_bar_demo.dart';
15 | import './expansion_panel_demo.dart';
16 | import './chip_demo.dart';
17 | import './data_table_demo.dart';
18 | import './paginated_data_table_demo.dart';
19 | import './card_demo.dart';
20 | import './stepper_demo.dart';
21 |
22 | class MaterialComponents extends StatelessWidget {
23 | @override
24 | Widget build(BuildContext context) {
25 | return Scaffold(
26 | appBar: AppBar(
27 | title: Text('MaterialComponents'),
28 | elevation: 0.0,
29 | ),
30 | body: ListView(
31 | children: [
32 | ListItem(title: 'Stepper', page: StepperDemo()),
33 | ListItem(title: 'Card', page: CardDemo()),
34 | ListItem(title: 'PaginatedDataTable', page: PaginatedDataTableDemo()),
35 | ListItem(title: 'DataTable', page: DataTableDemo()),
36 | ListItem(title: 'Chip', page: ChipDemo()),
37 | ListItem(title: 'ExpansionPanel', page: ExpansionPanelDemo()),
38 | ListItem(title: 'SnackBar', page: SnackBarDemo()),
39 | ListItem(title: 'BottomSheet', page: BottomSheetDemo()),
40 | ListItem(title: 'AlertDialog', page: AlertDialogDemo()),
41 | ListItem(title: 'SimpleDialog', page: SimpleDialogDemo()),
42 | ListItem(title: 'Date & Time', page: DateTimeDemo()),
43 | ListItem(title: 'Slider', page: SliderDemo()),
44 | ListItem(title: 'Switch', page: SwitchDemo()),
45 | ListItem(title: 'Radio', page: RadioDemo()),
46 | ListItem(title: 'Checkbox', page: CheckboxDemo()),
47 | ListItem(title: 'Form', page: FormDemo()),
48 | ListItem(title: 'PopupMenuButton', page: PopupMenuButtonDemo()),
49 | ListItem(title: 'Button', page: ButtonDemo()),
50 | ListItem(title: 'FloatingActionButton', page: FloatingActionButtonDemo()),
51 | ],
52 | ),
53 | );
54 | }
55 | }
56 |
57 | class _WidgetDemo extends StatelessWidget {
58 | @override
59 | Widget build(BuildContext context) {
60 | return Scaffold(
61 | appBar: AppBar(
62 | title: Text('_WidgetDemo'),
63 | elevation: 0.0,
64 | ),
65 | body: Container(
66 | padding: EdgeInsets.all(16.0),
67 | child: Column(
68 | mainAxisAlignment: MainAxisAlignment.center,
69 | children: [
70 | Row(
71 | mainAxisAlignment: MainAxisAlignment.center,
72 | children: [
73 |
74 | ],
75 | ),
76 | ],
77 | ),
78 | )
79 | );
80 | }
81 | }
82 |
83 | class ListItem extends StatelessWidget {
84 | final String title;
85 | final Widget page;
86 |
87 | ListItem({
88 | this.title,
89 | this.page,
90 | });
91 |
92 | @override
93 | Widget build(BuildContext context) {
94 | return ListTile(
95 | title: Text(title),
96 | onTap: () {
97 | Navigator.of(context).push(
98 | MaterialPageRoute(builder: (context) => page),
99 | );
100 | },
101 | );
102 | }
103 | }
--------------------------------------------------------------------------------
/lib/demo/navigator_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class NavigatorDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Scaffold(
7 | body: Center(
8 | child: Row(
9 | mainAxisAlignment: MainAxisAlignment.center,
10 | children: [
11 | FlatButton(
12 | child: Text('Home'),
13 | onPressed: null,
14 | ),
15 | FlatButton(
16 | child: Text('About'),
17 | onPressed: () {
18 | Navigator.pushNamed(context, '/about');
19 | },
20 | ),
21 | ],
22 | ),
23 | ),
24 | );
25 | }
26 | }
27 |
28 | class Page extends StatelessWidget {
29 | final String title;
30 |
31 | Page({
32 | this.title
33 | });
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return Scaffold(
38 | appBar: AppBar(
39 | title: Text(title),
40 | elevation: 0.0,
41 | ),
42 | floatingActionButton: FloatingActionButton(
43 | child: Icon(Icons.arrow_back),
44 | onPressed: () {
45 | Navigator.pop(context);
46 | },
47 | ),
48 | );
49 | }
50 | }
--------------------------------------------------------------------------------
/lib/demo/paginated_data_table_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../model/post.dart';
3 |
4 | class PostDataSource extends DataTableSource {
5 | final List _posts = posts;
6 | int _selectedCount = 0;
7 |
8 | @override
9 | int get rowCount => _posts.length;
10 |
11 | @override
12 | bool get isRowCountApproximate => false;
13 |
14 | @override
15 | int get selectedRowCount => _selectedCount;
16 |
17 | @override
18 | DataRow getRow(int index) {
19 | final Post post = _posts[index];
20 |
21 | return DataRow.byIndex(
22 | index: index,
23 | cells: [
24 | DataCell(Text(post.title)),
25 | DataCell(Text(post.author)),
26 | DataCell(Image.network(post.imageUrl)),
27 | ],
28 | );
29 | }
30 |
31 | void _sort(getField(post), bool ascending) {
32 | _posts.sort((a, b) {
33 | if (!ascending) {
34 | final c = a;
35 | a = b;
36 | b = c;
37 | }
38 |
39 | final aValue = getField(a);
40 | final bValue = getField(b);
41 |
42 | return Comparable.compare(aValue, bValue);
43 | });
44 |
45 | notifyListeners();
46 | }
47 | }
48 |
49 | class PaginatedDataTableDemo extends StatefulWidget {
50 | @override
51 | _PaginatedDataTableDemoState createState() => _PaginatedDataTableDemoState();
52 | }
53 |
54 | class _PaginatedDataTableDemoState extends State {
55 | int _sortColumnIndex;
56 | bool _sortAscending = true;
57 |
58 | final PostDataSource _postsDataSource = PostDataSource();
59 |
60 | @override
61 | Widget build(BuildContext context) {
62 | return Scaffold(
63 | appBar: AppBar(
64 | title: Text('PaginatedDataTableDemo'),
65 | elevation: 0.0,
66 | ),
67 | body: Container(
68 | padding: EdgeInsets.all(16.0),
69 | child: ListView(
70 | children: [
71 | PaginatedDataTable(
72 | header: Text('Posts'),
73 | rowsPerPage: 5,
74 | source: _postsDataSource,
75 | sortColumnIndex: _sortColumnIndex,
76 | sortAscending: _sortAscending,
77 | // onSelectAll: (bool value) {},
78 | columns: [
79 | DataColumn(
80 | label: Text('Title'),
81 | onSort: (int columnIndex, bool ascending) {
82 | _postsDataSource._sort((post) => post.title.length, ascending);
83 |
84 | setState(() {
85 | _sortColumnIndex = columnIndex;
86 | _sortAscending = ascending;
87 | });
88 | },
89 | ),
90 | DataColumn(
91 | label: Text('Author'),
92 | ),
93 | DataColumn(
94 | label: Text('Image'),
95 | ),
96 | ],
97 | ),
98 | ],
99 | ),
100 | ));
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/lib/demo/popup_menu_button_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class PopupMenuButtonDemo extends StatefulWidget {
4 | @override
5 | _PopupMenuButtonDemoState createState() => _PopupMenuButtonDemoState();
6 | }
7 |
8 | class _PopupMenuButtonDemoState extends State {
9 | String _currentMenuItem = 'Home';
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('PopupMenuButtonDemo'),
16 | elevation: 0.0,
17 | ),
18 | body: Container(
19 | padding: EdgeInsets.all(16.0),
20 | child: Column(
21 | mainAxisAlignment: MainAxisAlignment.center,
22 | children: [
23 | Row(
24 | mainAxisAlignment: MainAxisAlignment.center,
25 | children: [
26 | Text(_currentMenuItem),
27 | PopupMenuButton(
28 | onSelected: (value) {
29 | print(value);
30 | setState(() {
31 | _currentMenuItem = value;
32 | });
33 | },
34 | itemBuilder: (BuildContext context) => [
35 | PopupMenuItem(
36 | value: 'Home',
37 | child: Text('Home'),
38 | ),
39 | PopupMenuItem(
40 | value: 'Discover',
41 | child: Text('Discover'),
42 | ),
43 | PopupMenuItem(
44 | value: 'Community',
45 | child: Text('Community'),
46 | ),
47 | ],
48 | ),
49 | ],
50 | ),
51 | ],
52 | ),
53 | )
54 | );
55 | }
56 | }
--------------------------------------------------------------------------------
/lib/demo/post_show.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../model/post.dart';
3 |
4 | class PostShow extends StatelessWidget {
5 | final Post post;
6 |
7 | PostShow({
8 | @required this.post,
9 | });
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('${post.title}'),
16 | elevation: 0.0,
17 | ),
18 | body: SingleChildScrollView(
19 | child: Column(
20 | children: [
21 | Image.network(post.imageUrl),
22 | Container(
23 | padding: EdgeInsets.all(32.0),
24 | width: double.infinity,
25 | child: Column(
26 | crossAxisAlignment: CrossAxisAlignment.start,
27 | children: [
28 | Text('${post.title}',
29 | style: Theme.of(context).textTheme.title),
30 | Text('${post.author}',
31 | style: Theme.of(context).textTheme.subhead),
32 | SizedBox(height: 32.0),
33 | Text('${post.description}',
34 | style: Theme.of(context).textTheme.body1),
35 | ],
36 | ),
37 | ),
38 | ],
39 | ),
40 | ));
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/demo/radio_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class RadioDemo extends StatefulWidget {
4 | @override
5 | _RadioDemoState createState() => _RadioDemoState();
6 | }
7 |
8 | class _RadioDemoState extends State {
9 | int _radioGroupA = 0;
10 |
11 | void _handleRadioValueChanged(int value) {
12 | setState(() {
13 | _radioGroupA = value;
14 | });
15 | }
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return Scaffold(
20 | appBar: AppBar(
21 | title: Text('RadioDemo'),
22 | elevation: 0.0,
23 | ),
24 | body: Container(
25 | padding: EdgeInsets.all(16.0),
26 | child: Column(
27 | mainAxisAlignment: MainAxisAlignment.center,
28 | children: [
29 | Text('RadioGroupValue: $_radioGroupA'),
30 | SizedBox(height: 32.0),
31 | RadioListTile(
32 | value: 0,
33 | groupValue: _radioGroupA,
34 | onChanged: _handleRadioValueChanged,
35 | title: Text('Options A'),
36 | subtitle: Text('Description'),
37 | secondary: Icon(Icons.filter_1),
38 | selected: _radioGroupA == 0,
39 | ),
40 | RadioListTile(
41 | value: 1,
42 | groupValue: _radioGroupA,
43 | onChanged: _handleRadioValueChanged,
44 | title: Text('Options B'),
45 | subtitle: Text('Description'),
46 | secondary: Icon(Icons.filter_2),
47 | selected: _radioGroupA == 1,
48 | ),
49 | Row(
50 | mainAxisAlignment: MainAxisAlignment.center,
51 | children: [
52 | // Radio(
53 | // value: 0,
54 | // groupValue: _radioGroupA,
55 | // onChanged: _handleRadioValueChanged,
56 | // activeColor: Colors.black,
57 | // ),
58 | // Radio(
59 | // value: 1,
60 | // groupValue: _radioGroupA,
61 | // onChanged: _handleRadioValueChanged,
62 | // activeColor: Colors.black,
63 | // ),
64 | ],
65 | ),
66 | ],
67 | ),
68 | )
69 | );
70 | }
71 | }
--------------------------------------------------------------------------------
/lib/demo/rxdart/rxdart_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:rxdart/rxdart.dart';
3 | import 'dart:async';
4 |
5 | class RxDartDemo extends StatelessWidget {
6 | @override
7 | Widget build(BuildContext context) {
8 | return Scaffold(
9 | appBar: AppBar(
10 | title: Text('RxDartDemo'),
11 | elevation: 0.0,
12 | ),
13 | body: RxDartDemoHome(),
14 | );
15 | }
16 | }
17 |
18 | class RxDartDemoHome extends StatefulWidget {
19 | @override
20 | _RxDartDemoHomeState createState() => _RxDartDemoHomeState();
21 | }
22 |
23 | class _RxDartDemoHomeState extends State {
24 | PublishSubject _textFieldSubject;
25 |
26 | @override
27 | void initState() {
28 | super.initState();
29 |
30 | _textFieldSubject = PublishSubject();
31 |
32 | _textFieldSubject
33 | // .map((item) => 'item: $item')
34 | // .where((item) => item.length > 9)
35 | .debounce(Duration(milliseconds: 500))
36 | .listen((data) => print(data));
37 |
38 | // Observable _observable =
39 | // // Observable(Stream.fromIterable(['hello', '您好']));
40 | // // Observable.fromFuture(Future.value('hello ~'));
41 | // // Observable.fromIterable(['hello', '您好']);
42 | // // Observable.just('hello ~');
43 | // Observable.periodic(Duration(seconds: 3), (x) => x.toString());
44 |
45 | // _observable.listen(print);
46 |
47 | // PublishSubject _subject = PublishSubject();
48 | // BehaviorSubject _subject = BehaviorSubject();
49 | // ReplaySubject _subject = ReplaySubject(maxSize: 2);
50 |
51 | // _subject.add('hello');
52 | // _subject.add('hola');
53 | // _subject.add('hi');
54 | // _subject.listen((data) => print('listen 1: $data'));
55 | // _subject.listen((data) => print('listen 2: ${data.toUpperCase()}'));
56 |
57 | // _subject.close();
58 | }
59 |
60 | @override
61 | void dispose() {
62 | super.dispose();
63 | _textFieldSubject.close();
64 | }
65 |
66 | @override
67 | Widget build(BuildContext context) {
68 | return Theme(
69 | data: Theme.of(context).copyWith(
70 | primaryColor: Colors.black,
71 | ),
72 | child: TextField(
73 | onChanged: (value) {
74 | _textFieldSubject.add('input: $value');
75 | },
76 | onSubmitted: (value) {
77 | _textFieldSubject.add('submit: $value');
78 | },
79 | decoration: InputDecoration(
80 | labelText: 'Title',
81 | filled: true,
82 | ),
83 | ),
84 | );
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/lib/demo/simple_dialog_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'dart:async';
3 |
4 | enum Option {
5 | A, B, C
6 | }
7 |
8 | class SimpleDialogDemo extends StatefulWidget {
9 | @override
10 | _SimpleDialogDemoState createState() => _SimpleDialogDemoState();
11 | }
12 |
13 | class _SimpleDialogDemoState extends State {
14 | String _choice = 'Nothing';
15 |
16 | Future _openSimpleDialog() async {
17 | final option = await showDialog(
18 | context: context,
19 | builder: (BuildContext context) {
20 | return SimpleDialog(
21 | title: Text('SimpleDialog'),
22 | children: [
23 | SimpleDialogOption(
24 | child: Text('Option A'),
25 | onPressed: () {
26 | Navigator.pop(context, Option.A);
27 | },
28 | ),
29 | SimpleDialogOption(
30 | child: Text('Option B'),
31 | onPressed: () {
32 | Navigator.pop(context, Option.B);
33 | },
34 | ),
35 | SimpleDialogOption(
36 | child: Text('Option C'),
37 | onPressed: () {
38 | Navigator.pop(context, Option.C);
39 | },
40 | ),
41 | ],
42 | );
43 | }
44 | );
45 |
46 | switch (option) {
47 | case Option.A:
48 | setState(() {
49 | _choice = 'A';
50 | });
51 | break;
52 | case Option.B:
53 | setState(() {
54 | _choice = 'B';
55 | });
56 | break;
57 | case Option.C:
58 | setState(() {
59 | _choice = 'C';
60 | });
61 | break;
62 | default:
63 | }
64 | }
65 |
66 | @override
67 | Widget build(BuildContext context) {
68 | return Scaffold(
69 | appBar: AppBar(
70 | title: Text('SimpleDialogDemo'),
71 | elevation: 0.0,
72 | ),
73 | body: Container(
74 | padding: EdgeInsets.all(16.0),
75 | child: Column(
76 | mainAxisAlignment: MainAxisAlignment.center,
77 | children: [
78 | Text('Your choice is: $_choice'),
79 | Row(
80 | mainAxisAlignment: MainAxisAlignment.center,
81 | children: [
82 | ],
83 | ),
84 | ],
85 | ),
86 | ),
87 | floatingActionButton: FloatingActionButton(
88 | child: Icon(Icons.format_list_numbered),
89 | onPressed: _openSimpleDialog,
90 | ),
91 | );
92 | }
93 | }
--------------------------------------------------------------------------------
/lib/demo/slider_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SliderDemo extends StatefulWidget {
4 | @override
5 | _SliderDemoState createState() => _SliderDemoState();
6 | }
7 |
8 | class _SliderDemoState extends State {
9 | double _sliderItemA = 0.0;
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('SliderDemo'),
16 | elevation: 0.0,
17 | ),
18 | body: Container(
19 | padding: EdgeInsets.all(16.0),
20 | child: Column(
21 | mainAxisAlignment: MainAxisAlignment.center,
22 | children: [
23 | Row(
24 | mainAxisAlignment: MainAxisAlignment.center,
25 | children: [
26 | Slider(
27 | value: _sliderItemA,
28 | onChanged: (value) {
29 | setState(() {
30 | _sliderItemA = value;
31 | });
32 | },
33 | activeColor: Theme.of(context).accentColor,
34 | inactiveColor: Theme.of(context).accentColor.withOpacity(0.3),
35 | min: 0.0,
36 | max: 10.0,
37 | divisions: 10,
38 | label: '${_sliderItemA.toInt()}',
39 | ),
40 | ],
41 | ),
42 | SizedBox(height: 16.0,),
43 | Text('SliderValue: $_sliderItemA'),
44 | ],
45 | ),
46 | )
47 | );
48 | }
49 | }
--------------------------------------------------------------------------------
/lib/demo/sliver_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../model/post.dart';
3 |
4 | class SliverDemo extends StatelessWidget {
5 | @override
6 | Widget build(BuildContext context) {
7 | return Scaffold(
8 | body: CustomScrollView(
9 | slivers: [
10 | SliverAppBar(
11 | // title: Text('NINGHAO'),
12 | // pinned: true,
13 | floating: true,
14 | expandedHeight: 178.0,
15 | flexibleSpace: FlexibleSpaceBar(
16 | title: Text(
17 | 'Ninghao Flutter'.toUpperCase(),
18 | style: TextStyle(
19 | fontSize: 15.0,
20 | letterSpacing: 3.0,
21 | fontWeight: FontWeight.w400,
22 | ),
23 | ),
24 | background: Image.network(
25 | 'https://resources.ninghao.net/images/overkill.png',
26 | fit: BoxFit.cover,
27 | ),
28 | ),
29 | ),
30 | SliverSafeArea(
31 | sliver: SliverPadding(
32 | padding: EdgeInsets.all(8.0),
33 | sliver: SliverGridDemo()
34 | ),
35 | ),
36 | ],
37 | ),
38 | );
39 | }
40 | }
41 |
42 | class SliverListDemo extends StatelessWidget {
43 | @override
44 | Widget build(BuildContext context) {
45 | return SliverList(
46 | delegate: SliverChildBuilderDelegate(
47 | (BuildContext context, int index) {
48 | return Padding(
49 | padding: EdgeInsets.only(bottom: 32.0),
50 | child: Material(
51 | borderRadius: BorderRadius.circular(12.0),
52 | elevation: 14.0,
53 | shadowColor: Colors.grey.withOpacity(0.5),
54 | child: Stack(
55 | children: [
56 | AspectRatio(
57 | aspectRatio: 16/9,
58 | child: Image.network(
59 | posts[index].imageUrl,
60 | fit: BoxFit.cover,
61 | ),
62 | ),
63 | Positioned(
64 | top: 32.0,
65 | left: 32.0,
66 | child: Column(
67 | crossAxisAlignment: CrossAxisAlignment.start,
68 | children: [
69 | Text(
70 | posts[index].title,
71 | style: TextStyle(
72 | fontSize: 20.0,
73 | color: Colors.white
74 | ),
75 | ),
76 | Text(
77 | posts[index].author,
78 | style: TextStyle(
79 | fontSize: 13.0,
80 | color: Colors.white
81 | ),
82 | ),
83 | ],
84 | ),
85 | ),
86 | ],
87 | ),
88 | ),
89 | );
90 | },
91 | childCount: posts.length,
92 | ),
93 | );
94 | }
95 | }
96 |
97 | class SliverGridDemo extends StatelessWidget {
98 | @override
99 | Widget build(BuildContext context) {
100 | return SliverGrid(
101 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
102 | crossAxisCount: 2,
103 | crossAxisSpacing: 8.0,
104 | mainAxisSpacing: 8.0,
105 | childAspectRatio: 1.0,
106 | ),
107 | delegate: SliverChildBuilderDelegate(
108 | (BuildContext context, int index) {
109 | return Container(
110 | child: Image.network(
111 | posts[index].imageUrl,
112 | fit: BoxFit.cover,
113 | ),
114 | );
115 | },
116 | childCount: posts.length,
117 | ),
118 | );
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/lib/demo/snack_bar_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SnackBarDemo extends StatefulWidget {
4 | @override
5 | _SnackBarDemoState createState() => _SnackBarDemoState();
6 | }
7 |
8 | class _SnackBarDemoState extends State {
9 | @override
10 | Widget build(BuildContext context) {
11 | return Scaffold(
12 | appBar: AppBar(
13 | title: Text('SnackBarDemo'),
14 | elevation: 0.0,
15 | ),
16 | body: Container(
17 | padding: EdgeInsets.all(16.0),
18 | child: Column(
19 | mainAxisAlignment: MainAxisAlignment.center,
20 | children: [
21 | Row(
22 | mainAxisAlignment: MainAxisAlignment.center,
23 | children: [
24 | SnackBarButton(),
25 | ]
26 | ),
27 | ],
28 | ),
29 | ),
30 | );
31 | }
32 | }
33 |
34 | class SnackBarButton extends StatelessWidget {
35 | @override
36 | Widget build(BuildContext context) {
37 | return FlatButton(
38 | child: Text('Open SnackBar'),
39 | onPressed: () {
40 | Scaffold.of(context).showSnackBar(
41 | SnackBar(
42 | content: Text('Processing...'),
43 | action: SnackBarAction(
44 | label: 'OK',
45 | onPressed: () {},
46 | ),
47 | )
48 | );
49 | },
50 | );
51 | }
52 | }
--------------------------------------------------------------------------------
/lib/demo/state/state_management_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:scoped_model/scoped_model.dart';
3 |
4 | class StateManagementDemo extends StatelessWidget {
5 | @override
6 | Widget build(BuildContext context) {
7 | return ScopedModel(
8 | model: CounterModel(),
9 | child: Scaffold(
10 | appBar: AppBar(
11 | title: Text('StateManagementDemo'),
12 | elevation: 0.0,
13 | ),
14 | body: CounterWrapper(),
15 | floatingActionButton: ScopedModelDescendant(
16 | rebuildOnChange: false,
17 | builder: (context, _, model) => FloatingActionButton(
18 | child: Icon(Icons.add),
19 | onPressed: model.increaseCount,
20 | ),
21 | ),
22 | ),
23 | );
24 | }
25 | }
26 |
27 | class CounterWrapper extends StatelessWidget {
28 | @override
29 | Widget build(BuildContext context) {
30 | return Center(
31 | child: Counter(),
32 | );
33 | }
34 | }
35 |
36 | class Counter extends StatelessWidget {
37 | @override
38 | Widget build(BuildContext context) {
39 | return ScopedModelDescendant(
40 | builder: (context, _, model) => ActionChip(
41 | label: Text('${model.count}'),
42 | onPressed: model.increaseCount,
43 | ),
44 | );
45 | }
46 | }
47 |
48 | class CounterProvider extends InheritedWidget {
49 | final int count;
50 | final VoidCallback increaseCount;
51 | final Widget child;
52 |
53 | CounterProvider({
54 | this.count,
55 | this.increaseCount,
56 | this.child,
57 | }) : super(child: child);
58 |
59 | static CounterProvider of(BuildContext context) =>
60 | context.inheritFromWidgetOfExactType(CounterProvider);
61 |
62 | @override
63 | bool updateShouldNotify(InheritedWidget oldWidget) {
64 | return true;
65 | }
66 | }
67 |
68 | class CounterModel extends Model {
69 | int _count = 0;
70 | int get count => _count;
71 |
72 | void increaseCount() {
73 | _count += 1;
74 | notifyListeners();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/lib/demo/stepper_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class StepperDemo extends StatefulWidget {
4 | @override
5 | _StepperDemoState createState() => _StepperDemoState();
6 | }
7 |
8 | class _StepperDemoState extends State {
9 | int _currentStep = 0;
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('StepperDemo'),
16 | elevation: 0.0,
17 | ),
18 | body: Container(
19 | padding: EdgeInsets.all(16.0),
20 | child: Column(
21 | mainAxisAlignment: MainAxisAlignment.center,
22 | children: [
23 | Theme(
24 | data: Theme.of(context).copyWith(
25 | primaryColor: Colors.black,
26 | ),
27 | child: Stepper(
28 | currentStep: _currentStep,
29 | onStepTapped: (int value) {
30 | setState(() {
31 | _currentStep = value;
32 | });
33 | },
34 | onStepContinue: () {
35 | setState(() {
36 | _currentStep < 2 ? _currentStep += 1 : _currentStep = 0;
37 | });
38 | },
39 | onStepCancel: () {
40 | setState(() {
41 | _currentStep > 0 ? _currentStep -= 1 : _currentStep = 0;
42 | });
43 | },
44 | steps: [
45 | Step(
46 | title: Text('Login'),
47 | subtitle: Text('Login first'),
48 | content: Text('Magna exercitation duis non sint eu nostrud.'),
49 | isActive: _currentStep == 0,
50 | ),
51 | Step(
52 | title: Text('Choose Plan'),
53 | subtitle: Text('Choose you plan.'),
54 | content: Text('Magna exercitation duis non sint eu nostrud.'),
55 | isActive: _currentStep == 1,
56 | ),
57 | Step(
58 | title: Text('Confirm payment'),
59 | subtitle: Text('Confirm your payment method.'),
60 | content: Text('Magna exercitation duis non sint eu nostrud.'),
61 | isActive: _currentStep == 2,
62 | ),
63 | ],
64 | ),
65 | ),
66 | ],
67 | ),
68 | )
69 | );
70 | }
71 | }
--------------------------------------------------------------------------------
/lib/demo/stream/stream_demo.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | class StreamDemo extends StatelessWidget {
6 | @override
7 | Widget build(BuildContext context) {
8 | return Scaffold(
9 | appBar: AppBar(
10 | title: Text('StreamDemo'),
11 | elevation: 0.0,
12 | ),
13 | body: StreamDemoHome(),
14 | );
15 | }
16 | }
17 |
18 | class StreamDemoHome extends StatefulWidget {
19 | @override
20 | _StreamDemoHomeState createState() => _StreamDemoHomeState();
21 | }
22 |
23 | class _StreamDemoHomeState extends State {
24 | StreamSubscription _streamDemoSubscription;
25 | StreamController _streamDemo;
26 | StreamSink _sinkDemo;
27 | String _data = '...';
28 |
29 | @override
30 | void dispose() {
31 | _streamDemo.close();
32 | super.dispose();
33 | }
34 |
35 | @override
36 | void initState() {
37 | super.initState();
38 |
39 | print('Create a stream.');
40 | // Stream _streamDemo = Stream.fromFuture(fetchData());
41 | _streamDemo = StreamController.broadcast();
42 | _sinkDemo = _streamDemo.sink;
43 |
44 | print('Start listening on a stream.');
45 | _streamDemoSubscription =
46 | _streamDemo.stream.listen(onData, onError: onError, onDone: onDone);
47 |
48 | _streamDemo.stream.listen(onDataTwo, onError: onError, onDone: onDone);
49 |
50 | print('Initialize completed.');
51 | }
52 |
53 | void onDone() {
54 | print('Done!');
55 | }
56 |
57 | void onError(error) {
58 | print('Error: $error');
59 | }
60 |
61 | void onData(String data) {
62 | setState(() {
63 | _data = data;
64 | });
65 | print('$data');
66 | }
67 |
68 | void onDataTwo(String data) {
69 | print('onDataTwo: $data');
70 | }
71 |
72 | void _pauseStream() {
73 | print('Pause subscription');
74 | _streamDemoSubscription.pause();
75 | }
76 |
77 | void _resumeStream() {
78 | print('Resume subscription');
79 | _streamDemoSubscription.resume();
80 | }
81 |
82 | void _cancelStream() {
83 | print('Cancel subscription');
84 | _streamDemoSubscription.cancel();
85 | }
86 |
87 | void _addDataToStream() async {
88 | print('Add data to stream.');
89 |
90 | String data = await fetchData();
91 | // _streamDemo.add(data);
92 | _sinkDemo.add(data);
93 | }
94 |
95 | Future fetchData() async {
96 | await Future.delayed(Duration(seconds: 5));
97 | // throw 'Something happened';
98 | return 'hello ~';
99 | }
100 |
101 | @override
102 | Widget build(BuildContext context) {
103 | return Container(
104 | child: Center(
105 | child: Column(
106 | mainAxisAlignment: MainAxisAlignment.center,
107 | children: [
108 | // Text(_data),
109 | StreamBuilder(
110 | stream: _streamDemo.stream,
111 | initialData: '...',
112 | builder: (context, snapshot) {
113 | return Text('${snapshot.data}');
114 | },
115 | ),
116 | Row(
117 | mainAxisAlignment: MainAxisAlignment.center,
118 | children: [
119 | FlatButton(
120 | child: Text('Add'),
121 | onPressed: _addDataToStream,
122 | ),
123 | FlatButton(
124 | child: Text('Pause'),
125 | onPressed: _pauseStream,
126 | ),
127 | FlatButton(
128 | child: Text('Resume'),
129 | onPressed: _resumeStream,
130 | ),
131 | FlatButton(
132 | child: Text('Cancel'),
133 | onPressed: _cancelStream,
134 | ),
135 | ],
136 | ),
137 | ],
138 | ),
139 | ),
140 | );
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/lib/demo/switch_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class SwitchDemo extends StatefulWidget {
4 | @override
5 | _SwitchDemoState createState() => _SwitchDemoState();
6 | }
7 |
8 | class _SwitchDemoState extends State {
9 | bool _switchItemA = false;
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | title: Text('SwitchDemo'),
16 | elevation: 0.0,
17 | ),
18 | body: Container(
19 | padding: EdgeInsets.all(16.0),
20 | child: Column(
21 | mainAxisAlignment: MainAxisAlignment.center,
22 | children: [
23 | SwitchListTile(
24 | value: _switchItemA,
25 | onChanged: (value) {
26 | setState(() {
27 | _switchItemA = value;
28 | });
29 | },
30 | title: Text('Switch Item A'),
31 | subtitle: Text('Description'),
32 | secondary: Icon(_switchItemA ? Icons.visibility : Icons.visibility_off),
33 | selected: _switchItemA,
34 | ),
35 | Row(
36 | mainAxisAlignment: MainAxisAlignment.center,
37 | children: [
38 | // Text(_switchItemA ? '😁' : '😐', style: TextStyle(fontSize: 32.0),),
39 | // Switch(
40 | // value: _switchItemA,
41 | // onChanged: (value) {
42 | // setState(() {
43 | // _switchItemA = value;
44 | // });
45 | // },
46 | // ),
47 | ],
48 | ),
49 | ],
50 | ),
51 | )
52 | );
53 | }
54 | }
--------------------------------------------------------------------------------
/lib/demo/test/test_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class TestDemo extends StatelessWidget {
4 | @override
5 | Widget build(BuildContext context) {
6 | return Scaffold(
7 | appBar: AppBar(
8 | title: Text('TestDemo'),
9 | elevation: 0.0,
10 | ),
11 | body: TestDemoHome(),
12 | );
13 | }
14 | }
15 |
16 | class TestDemoHome extends StatefulWidget {
17 | @override
18 | _TestDemoHomeState createState() => _TestDemoHomeState();
19 | }
20 |
21 | class _TestDemoHomeState extends State {
22 | int count = 0;
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | return Row(
27 | children: [
28 | Chip(
29 | label: Text('hello'),
30 | ),
31 | ActionChip(
32 | key: Key('actionChip'),
33 | label: Text('$count', key: Key('actionChipLabelText')),
34 | onPressed: () {
35 | setState(() {
36 | count++;
37 | });
38 | },
39 | )
40 | ],
41 | );
42 | }
43 | }
44 |
45 | class NinghaoTestDemo {
46 | static greet(String name) {
47 | return 'hello $name ~~';
48 | }
49 | }
--------------------------------------------------------------------------------
/lib/demo/view_demo.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import '../model/post.dart';
3 |
4 | class ViewDemo extends StatelessWidget {
5 | @override
6 | Widget build(BuildContext context) {
7 | return GridViewBuilderDemo();
8 | }
9 | }
10 |
11 | class GridViewBuilderDemo extends StatelessWidget {
12 | Widget _gridItemBuilder(BuildContext context, int index) {
13 | return Container(
14 | child: Image.network(
15 | posts[index].imageUrl,
16 | fit: BoxFit.cover
17 | ),
18 | );
19 | }
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return GridView.builder(
24 | padding: EdgeInsets.all(8.0),
25 | itemCount: posts.length,
26 | itemBuilder: _gridItemBuilder,
27 | gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
28 | // crossAxisCount: 3,
29 | maxCrossAxisExtent: 150.0,
30 | crossAxisSpacing: 8.0,
31 | mainAxisSpacing: 8.0,
32 | ),
33 | );
34 | }
35 | }
36 |
37 | class GridViewExtentDemo extends StatelessWidget {
38 | List _buildTiles(int length) {
39 | return List.generate(length, (int index) {
40 | return Container(
41 | color: Colors.grey[300],
42 | alignment: Alignment(0.0, 0.0),
43 | child: Text('Item $index',
44 | style: TextStyle(fontSize: 18.0, color: Colors.grey)),
45 | );
46 | });
47 | }
48 |
49 | @override
50 | Widget build(BuildContext context) {
51 | return GridView.extent(
52 | maxCrossAxisExtent: 150.0,
53 | crossAxisSpacing: 16.0,
54 | mainAxisSpacing: 16.0,
55 | // scrollDirection: Axis.horizontal,
56 | children: _buildTiles(100),
57 | );
58 | }
59 | }
60 |
61 | class GridViewCountDemo extends StatelessWidget {
62 | List _buildTiles(int length) {
63 | return List.generate(length, (int index) {
64 | return Container(
65 | color: Colors.grey[300],
66 | alignment: Alignment(0.0, 0.0),
67 | child: Text('Item $index',
68 | style: TextStyle(fontSize: 18.0, color: Colors.grey)),
69 | );
70 | });
71 | }
72 |
73 | @override
74 | Widget build(BuildContext context) {
75 | return GridView.count(
76 | crossAxisCount: 3,
77 | crossAxisSpacing: 16.0,
78 | mainAxisSpacing: 16.0,
79 | scrollDirection: Axis.horizontal,
80 | children: _buildTiles(100),
81 | );
82 | }
83 | }
84 |
85 | class PageViewBuilderDemo extends StatelessWidget {
86 | Widget _pageItemBuilder(BuildContext context, int index) {
87 | return Stack(
88 | children: [
89 | SizedBox.expand(
90 | child: Image.network(posts[index].imageUrl, fit: BoxFit.cover),
91 | ),
92 | Positioned(
93 | bottom: 8.0,
94 | left: 8.0,
95 | child: Column(
96 | crossAxisAlignment: CrossAxisAlignment.start,
97 | children: [
98 | Text(posts[index].title,
99 | style: TextStyle(fontWeight: FontWeight.bold)),
100 | Text(posts[index].author),
101 | ],
102 | ),
103 | ),
104 | ],
105 | );
106 | }
107 |
108 | @override
109 | Widget build(BuildContext context) {
110 | // TODO: implement build
111 | return PageView.builder(
112 | itemCount: posts.length,
113 | itemBuilder: _pageItemBuilder,
114 | );
115 | }
116 | }
117 |
118 | class PageViewDemo extends StatelessWidget {
119 | @override
120 | Widget build(BuildContext context) {
121 | // TODO: implement build
122 | return PageView(
123 | // pageSnapping: false,
124 | // reverse: true,
125 | scrollDirection: Axis.vertical,
126 | onPageChanged: (currentPage) => debugPrint('Page: $currentPage'),
127 | controller: PageController(
128 | initialPage: 1,
129 | keepPage: false,
130 | viewportFraction: 0.85,
131 | ),
132 | children: [
133 | Container(
134 | color: Colors.brown[900],
135 | alignment: Alignment(0.0, 0.0),
136 | child: Text('ONE',
137 | style: TextStyle(fontSize: 32.0, color: Colors.white)),
138 | ),
139 | Container(
140 | color: Colors.grey[900],
141 | alignment: Alignment(0.0, 0.0),
142 | child: Text('TWO',
143 | style: TextStyle(fontSize: 32.0, color: Colors.white)),
144 | ),
145 | Container(
146 | color: Colors.blueGrey[900],
147 | alignment: Alignment(0.0, 0.0),
148 | child: Text('THREE',
149 | style: TextStyle(fontSize: 32.0, color: Colors.white)),
150 | ),
151 | ],
152 | );
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:ninghao_flutter/demo/animation/animation_demo.dart';
3 | import 'package:ninghao_flutter/demo/bloc/bloc_demo.dart';
4 | import 'package:ninghao_flutter/demo/http/http_demo.dart';
5 | import 'package:ninghao_flutter/demo/i18n/i18n_demo.dart';
6 | import 'package:ninghao_flutter/demo/rxdart/rxdart_demo.dart';
7 | import 'package:ninghao_flutter/demo/state/state_management_demo.dart';
8 | import 'package:ninghao_flutter/demo/stream/stream_demo.dart';
9 | import 'package:ninghao_flutter/demo/test/test_demo.dart';
10 | import './demo/drawer_demo.dart';
11 | import './demo/bottom_navigation_bar_demo.dart';
12 | import './demo/listview_demo.dart';
13 | import './demo/basic_demo.dart';
14 | import './demo/layout_demo.dart';
15 | import './demo/view_demo.dart';
16 | import './demo/sliver_demo.dart';
17 | import './demo/navigator_demo.dart';
18 | import './demo/form_demo.dart';
19 | import './demo/material_components.dart';
20 | import 'package:flutter_localizations/flutter_localizations.dart';
21 | // import 'package:ninghao_flutter/demo/i18n/map/ninghao_demo_localizations.dart';
22 | import 'package:ninghao_flutter/demo/i18n/intl/ninghao_demo_localizations.dart';
23 |
24 | void main() => runApp(App());
25 |
26 | class App extends StatelessWidget {
27 | @override
28 | Widget build(BuildContext context) {
29 | return MaterialApp(
30 | locale: Locale('en', 'US'),
31 | // locale: Locale('zh', 'CN'),
32 | // localeResolutionCallback: (Locale locale, Iterable supportedLocales) {
33 | // return Locale('en', 'US');
34 | // },
35 | localizationsDelegates: [
36 | NinghaoDemoLocalizationsDelegate(),
37 | GlobalMaterialLocalizations.delegate,
38 | GlobalWidgetsLocalizations.delegate,
39 | ],
40 | supportedLocales: [
41 | Locale('en', 'US'),
42 | Locale('zh', 'CN'),
43 | ],
44 | debugShowCheckedModeBanner: false,
45 | // home: NavigatorDemo(),
46 | initialRoute: '/',
47 | routes: {
48 | '/': (context) => Home(),
49 | '/about': (context) => Page(title: 'About'),
50 | '/form': (context) => FormDemo(),
51 | '/mdc': (context) => MaterialComponents(),
52 | '/state-management': (context) => StateManagementDemo(),
53 | '/stream': (context) => StreamDemo(),
54 | '/rxdart': (context) => RxDartDemo(),
55 | '/bloc': (context) => BlocDemo(),
56 | '/http': (context) => HttpDemo(),
57 | '/animation': (context) => AnimationDemo(),
58 | '/i18n': (context) => I18nDemo(),
59 | '/test': (context) => TestDemo(),
60 | },
61 | theme: ThemeData(
62 | primarySwatch: Colors.yellow,
63 | highlightColor: Color.fromRGBO(255, 255, 255, 0.5),
64 | splashColor: Colors.white70,
65 | accentColor: Color.fromRGBO(3, 54, 255, 1.0),
66 | ));
67 | }
68 | }
69 |
70 | class Home extends StatelessWidget {
71 | @override
72 | Widget build(BuildContext context) {
73 | return DefaultTabController(
74 | length: 4,
75 | child: Scaffold(
76 | backgroundColor: Colors.grey[100],
77 | appBar: AppBar(
78 | title: Text('NINGHAO'),
79 | actions: [
80 | IconButton(
81 | icon: Icon(Icons.search),
82 | tooltip: 'Search',
83 | onPressed: () => debugPrint('Search button is pressed.'),
84 | )
85 | ],
86 | elevation: 0.0,
87 | bottom: TabBar(
88 | unselectedLabelColor: Colors.black38,
89 | indicatorColor: Colors.black54,
90 | indicatorSize: TabBarIndicatorSize.label,
91 | indicatorWeight: 1.0,
92 | tabs: [
93 | Tab(icon: Icon(Icons.local_florist)),
94 | Tab(icon: Icon(Icons.change_history)),
95 | Tab(icon: Icon(Icons.directions_bike)),
96 | Tab(icon: Icon(Icons.view_quilt)),
97 | ],
98 | ),
99 | ),
100 | body: TabBarView(
101 | children: [
102 | ListViewDemo(),
103 | // Icon(Icons.change_history, size: 128.0, color: Colors.black12),
104 | BasicDemo(),
105 | // Icon(Icons.directions_bike, size: 128.0, color: Colors.black12),
106 | LayoutDemo(),
107 | SliverDemo(),
108 | ],
109 | ),
110 | drawer: DrawerDemo(),
111 | bottomNavigationBar: BottomNavigationBarDemo(),
112 | ),
113 | );
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/lib/model/post.dart:
--------------------------------------------------------------------------------
1 | class Post {
2 | Post({
3 | this.title,
4 | this.author,
5 | this.imageUrl,
6 | this.description,
7 | });
8 |
9 | final String title;
10 | final String author;
11 | final String imageUrl;
12 | final String description;
13 |
14 | bool selected = false;
15 | }
16 |
17 | final List posts = [
18 | Post(
19 | title: 'Candy Shop',
20 | author: 'Mohamed Chahin',
21 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
22 | imageUrl: 'https://resources.ninghao.org/images/candy-shop.jpg',
23 | ),
24 | Post(
25 | title: 'Childhood in a picture',
26 | author: 'Mohamed Chahin',
27 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
28 | imageUrl: 'https://resources.ninghao.org/images/childhood-in-a-picture.jpg',
29 | ),
30 | Post(
31 | title: 'Contained',
32 | author: 'Mohamed Chahin',
33 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
34 | imageUrl: 'https://resources.ninghao.org/images/contained.jpg',
35 | ),
36 | Post(
37 | title: 'Dragon',
38 | author: 'Mohamed Chahin',
39 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
40 | imageUrl: 'https://resources.ninghao.org/images/dragon.jpg',
41 | ),
42 | Post(
43 | title: 'Free Hugs',
44 | author: 'Mohamed Chahin',
45 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
46 | imageUrl: 'https://resources.ninghao.org/images/free_hugs.jpg',
47 | ),
48 | Post(
49 | title: 'Gravity Falls',
50 | author: 'Mohamed Chahin',
51 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
52 | imageUrl: 'https://resources.ninghao.org/images/gravity-falls.png',
53 | ),
54 | Post(
55 | title: 'Icecream Truck',
56 | author: 'Mohamed Chahin',
57 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
58 | imageUrl: 'https://resources.ninghao.org/images/icecreamtruck.png',
59 | ),
60 | Post(
61 | title: 'keyclack',
62 | author: 'Mohamed Chahin',
63 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
64 | imageUrl: 'https://resources.ninghao.org/images/keyclack.jpg',
65 | ),
66 | Post(
67 | title: 'Overkill',
68 | author: 'Mohamed Chahin',
69 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
70 | imageUrl: 'https://resources.ninghao.org/images/overkill.png',
71 | ),
72 | Post(
73 | title: 'Say Hello to Barry',
74 | author: 'Mohamed Chahin',
75 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
76 | imageUrl: 'https://resources.ninghao.org/images/say-hello-to-barry.jpg',
77 | ),
78 | Post(
79 | title: 'Space Skull',
80 | author: 'Mohamed Chahin',
81 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
82 | imageUrl: 'https://resources.ninghao.org/images/space-skull.jpg',
83 | ),
84 | Post(
85 | title: 'The Old Fashioned',
86 | author: 'Mohamed Chahin',
87 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
88 | imageUrl: 'https://resources.ninghao.org/images/the-old-fashioned.png',
89 | ),
90 | Post(
91 | title: 'Tornado',
92 | author: 'Mohamed Chahin',
93 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
94 | imageUrl: 'https://resources.ninghao.org/images/tornado.jpg',
95 | ),
96 | Post(
97 | title: 'Undo',
98 | author: 'Mohamed Chahin',
99 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
100 | imageUrl: 'https://resources.ninghao.org/images/undo.jpg',
101 | ),
102 | Post(
103 | title: 'White Dragon',
104 | author: 'Mohamed Chahin',
105 | description: 'Esse ut nulla velit reprehenderit veniam sint nostrud nulla exercitation ipsum. Officia deserunt aliquip aliquip excepteur eiusmod dolor. Elit amet ipsum labore sint occaecat dolore tempor officia irure voluptate ad. Veniam laboris deserunt aute excepteur sit deserunt dolor esse dolor velit sint nulla anim ut. Reprehenderit voluptate adipisicing culpa magna ea nulla ullamco consectetur. Cupidatat adipisicing consequat adipisicing sit consectetur dolor occaecat.',
106 | imageUrl: 'https://resources.ninghao.org/images/white-dragon.jpg',
107 | )
108 | ];
--------------------------------------------------------------------------------
/ninghao_flutter.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ninghao_flutter_android.iml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | analyzer:
5 | dependency: transitive
6 | description:
7 | name: analyzer
8 | url: "https://pub.flutter-io.cn"
9 | source: hosted
10 | version: "0.36.4"
11 | archive:
12 | dependency: transitive
13 | description:
14 | name: archive
15 | url: "https://pub.flutter-io.cn"
16 | source: hosted
17 | version: "2.0.10"
18 | args:
19 | dependency: transitive
20 | description:
21 | name: args
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "1.5.2"
25 | async:
26 | dependency: transitive
27 | description:
28 | name: async
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "2.3.0"
32 | boolean_selector:
33 | dependency: transitive
34 | description:
35 | name: boolean_selector
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.0.5"
39 | charcode:
40 | dependency: transitive
41 | description:
42 | name: charcode
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "1.1.2"
46 | collection:
47 | dependency: transitive
48 | description:
49 | name: collection
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "1.14.11"
53 | convert:
54 | dependency: transitive
55 | description:
56 | name: convert
57 | url: "https://pub.flutter-io.cn"
58 | source: hosted
59 | version: "2.1.1"
60 | crypto:
61 | dependency: transitive
62 | description:
63 | name: crypto
64 | url: "https://pub.flutter-io.cn"
65 | source: hosted
66 | version: "2.1.3"
67 | csslib:
68 | dependency: transitive
69 | description:
70 | name: csslib
71 | url: "https://pub.flutter-io.cn"
72 | source: hosted
73 | version: "0.14.6"
74 | cupertino_icons:
75 | dependency: "direct main"
76 | description:
77 | name: cupertino_icons
78 | url: "https://pub.flutter-io.cn"
79 | source: hosted
80 | version: "0.1.2"
81 | dart_style:
82 | dependency: transitive
83 | description:
84 | name: dart_style
85 | url: "https://pub.flutter-io.cn"
86 | source: hosted
87 | version: "1.2.9"
88 | file:
89 | dependency: transitive
90 | description:
91 | name: file
92 | url: "https://pub.flutter-io.cn"
93 | source: hosted
94 | version: "5.0.10"
95 | flutter:
96 | dependency: "direct main"
97 | description: flutter
98 | source: sdk
99 | version: "0.0.0"
100 | flutter_driver:
101 | dependency: "direct dev"
102 | description: flutter
103 | source: sdk
104 | version: "0.0.0"
105 | flutter_localizations:
106 | dependency: "direct main"
107 | description: flutter
108 | source: sdk
109 | version: "0.0.0"
110 | flutter_test:
111 | dependency: "direct dev"
112 | description: flutter
113 | source: sdk
114 | version: "0.0.0"
115 | front_end:
116 | dependency: transitive
117 | description:
118 | name: front_end
119 | url: "https://pub.flutter-io.cn"
120 | source: hosted
121 | version: "0.1.19"
122 | fuchsia_remote_debug_protocol:
123 | dependency: transitive
124 | description: flutter
125 | source: sdk
126 | version: "0.0.0"
127 | glob:
128 | dependency: transitive
129 | description:
130 | name: glob
131 | url: "https://pub.flutter-io.cn"
132 | source: hosted
133 | version: "1.1.7"
134 | html:
135 | dependency: transitive
136 | description:
137 | name: html
138 | url: "https://pub.flutter-io.cn"
139 | source: hosted
140 | version: "0.14.0+3"
141 | http:
142 | dependency: "direct main"
143 | description:
144 | name: http
145 | url: "https://pub.flutter-io.cn"
146 | source: hosted
147 | version: "0.12.0"
148 | http_multi_server:
149 | dependency: transitive
150 | description:
151 | name: http_multi_server
152 | url: "https://pub.flutter-io.cn"
153 | source: hosted
154 | version: "2.1.0"
155 | http_parser:
156 | dependency: transitive
157 | description:
158 | name: http_parser
159 | url: "https://pub.flutter-io.cn"
160 | source: hosted
161 | version: "3.1.3"
162 | image:
163 | dependency: transitive
164 | description:
165 | name: image
166 | url: "https://pub.flutter-io.cn"
167 | source: hosted
168 | version: "2.1.4"
169 | intl:
170 | dependency: "direct main"
171 | description:
172 | name: intl
173 | url: "https://pub.flutter-io.cn"
174 | source: hosted
175 | version: "0.16.0"
176 | intl_translation:
177 | dependency: "direct dev"
178 | description:
179 | name: intl_translation
180 | url: "https://pub.flutter-io.cn"
181 | source: hosted
182 | version: "0.17.7"
183 | io:
184 | dependency: transitive
185 | description:
186 | name: io
187 | url: "https://pub.flutter-io.cn"
188 | source: hosted
189 | version: "0.3.3"
190 | js:
191 | dependency: transitive
192 | description:
193 | name: js
194 | url: "https://pub.flutter-io.cn"
195 | source: hosted
196 | version: "0.6.1+1"
197 | json_rpc_2:
198 | dependency: transitive
199 | description:
200 | name: json_rpc_2
201 | url: "https://pub.flutter-io.cn"
202 | source: hosted
203 | version: "2.1.0"
204 | kernel:
205 | dependency: transitive
206 | description:
207 | name: kernel
208 | url: "https://pub.flutter-io.cn"
209 | source: hosted
210 | version: "0.3.19"
211 | logging:
212 | dependency: transitive
213 | description:
214 | name: logging
215 | url: "https://pub.flutter-io.cn"
216 | source: hosted
217 | version: "0.11.3+2"
218 | matcher:
219 | dependency: transitive
220 | description:
221 | name: matcher
222 | url: "https://pub.flutter-io.cn"
223 | source: hosted
224 | version: "0.12.5"
225 | meta:
226 | dependency: transitive
227 | description:
228 | name: meta
229 | url: "https://pub.flutter-io.cn"
230 | source: hosted
231 | version: "1.1.7"
232 | mime:
233 | dependency: transitive
234 | description:
235 | name: mime
236 | url: "https://pub.flutter-io.cn"
237 | source: hosted
238 | version: "0.9.6+3"
239 | multi_server_socket:
240 | dependency: transitive
241 | description:
242 | name: multi_server_socket
243 | url: "https://pub.flutter-io.cn"
244 | source: hosted
245 | version: "1.0.2"
246 | node_preamble:
247 | dependency: transitive
248 | description:
249 | name: node_preamble
250 | url: "https://pub.flutter-io.cn"
251 | source: hosted
252 | version: "1.4.8"
253 | package_config:
254 | dependency: transitive
255 | description:
256 | name: package_config
257 | url: "https://pub.flutter-io.cn"
258 | source: hosted
259 | version: "1.1.0"
260 | package_resolver:
261 | dependency: transitive
262 | description:
263 | name: package_resolver
264 | url: "https://pub.flutter-io.cn"
265 | source: hosted
266 | version: "1.0.10"
267 | path:
268 | dependency: transitive
269 | description:
270 | name: path
271 | url: "https://pub.flutter-io.cn"
272 | source: hosted
273 | version: "1.6.4"
274 | pedantic:
275 | dependency: transitive
276 | description:
277 | name: pedantic
278 | url: "https://pub.flutter-io.cn"
279 | source: hosted
280 | version: "1.8.0+1"
281 | petitparser:
282 | dependency: transitive
283 | description:
284 | name: petitparser
285 | url: "https://pub.flutter-io.cn"
286 | source: hosted
287 | version: "2.4.0"
288 | platform:
289 | dependency: transitive
290 | description:
291 | name: platform
292 | url: "https://pub.flutter-io.cn"
293 | source: hosted
294 | version: "2.2.1"
295 | pool:
296 | dependency: transitive
297 | description:
298 | name: pool
299 | url: "https://pub.flutter-io.cn"
300 | source: hosted
301 | version: "1.4.0"
302 | process:
303 | dependency: transitive
304 | description:
305 | name: process
306 | url: "https://pub.flutter-io.cn"
307 | source: hosted
308 | version: "3.0.12"
309 | pub_semver:
310 | dependency: transitive
311 | description:
312 | name: pub_semver
313 | url: "https://pub.flutter-io.cn"
314 | source: hosted
315 | version: "1.4.2"
316 | quiver:
317 | dependency: transitive
318 | description:
319 | name: quiver
320 | url: "https://pub.flutter-io.cn"
321 | source: hosted
322 | version: "2.0.5"
323 | rxdart:
324 | dependency: "direct main"
325 | description:
326 | name: rxdart
327 | url: "https://pub.flutter-io.cn"
328 | source: hosted
329 | version: "0.18.1"
330 | scoped_model:
331 | dependency: "direct main"
332 | description:
333 | name: scoped_model
334 | url: "https://pub.flutter-io.cn"
335 | source: hosted
336 | version: "0.3.0"
337 | shelf:
338 | dependency: transitive
339 | description:
340 | name: shelf
341 | url: "https://pub.flutter-io.cn"
342 | source: hosted
343 | version: "0.7.5"
344 | shelf_packages_handler:
345 | dependency: transitive
346 | description:
347 | name: shelf_packages_handler
348 | url: "https://pub.flutter-io.cn"
349 | source: hosted
350 | version: "1.0.4"
351 | shelf_static:
352 | dependency: transitive
353 | description:
354 | name: shelf_static
355 | url: "https://pub.flutter-io.cn"
356 | source: hosted
357 | version: "0.2.8"
358 | shelf_web_socket:
359 | dependency: transitive
360 | description:
361 | name: shelf_web_socket
362 | url: "https://pub.flutter-io.cn"
363 | source: hosted
364 | version: "0.2.3"
365 | sky_engine:
366 | dependency: transitive
367 | description: flutter
368 | source: sdk
369 | version: "0.0.99"
370 | source_map_stack_trace:
371 | dependency: transitive
372 | description:
373 | name: source_map_stack_trace
374 | url: "https://pub.flutter-io.cn"
375 | source: hosted
376 | version: "1.1.5"
377 | source_maps:
378 | dependency: transitive
379 | description:
380 | name: source_maps
381 | url: "https://pub.flutter-io.cn"
382 | source: hosted
383 | version: "0.10.8"
384 | source_span:
385 | dependency: transitive
386 | description:
387 | name: source_span
388 | url: "https://pub.flutter-io.cn"
389 | source: hosted
390 | version: "1.5.5"
391 | stack_trace:
392 | dependency: transitive
393 | description:
394 | name: stack_trace
395 | url: "https://pub.flutter-io.cn"
396 | source: hosted
397 | version: "1.9.3"
398 | stream_channel:
399 | dependency: transitive
400 | description:
401 | name: stream_channel
402 | url: "https://pub.flutter-io.cn"
403 | source: hosted
404 | version: "2.0.0"
405 | string_scanner:
406 | dependency: transitive
407 | description:
408 | name: string_scanner
409 | url: "https://pub.flutter-io.cn"
410 | source: hosted
411 | version: "1.0.5"
412 | term_glyph:
413 | dependency: transitive
414 | description:
415 | name: term_glyph
416 | url: "https://pub.flutter-io.cn"
417 | source: hosted
418 | version: "1.1.0"
419 | test:
420 | dependency: "direct dev"
421 | description:
422 | name: test
423 | url: "https://pub.flutter-io.cn"
424 | source: hosted
425 | version: "1.6.3"
426 | test_api:
427 | dependency: transitive
428 | description:
429 | name: test_api
430 | url: "https://pub.flutter-io.cn"
431 | source: hosted
432 | version: "0.2.5"
433 | test_core:
434 | dependency: transitive
435 | description:
436 | name: test_core
437 | url: "https://pub.flutter-io.cn"
438 | source: hosted
439 | version: "0.2.5"
440 | typed_data:
441 | dependency: transitive
442 | description:
443 | name: typed_data
444 | url: "https://pub.flutter-io.cn"
445 | source: hosted
446 | version: "1.1.6"
447 | vector_math:
448 | dependency: transitive
449 | description:
450 | name: vector_math
451 | url: "https://pub.flutter-io.cn"
452 | source: hosted
453 | version: "2.0.8"
454 | vm_service_client:
455 | dependency: transitive
456 | description:
457 | name: vm_service_client
458 | url: "https://pub.flutter-io.cn"
459 | source: hosted
460 | version: "0.2.6+2"
461 | watcher:
462 | dependency: transitive
463 | description:
464 | name: watcher
465 | url: "https://pub.flutter-io.cn"
466 | source: hosted
467 | version: "0.9.7+10"
468 | web_socket_channel:
469 | dependency: transitive
470 | description:
471 | name: web_socket_channel
472 | url: "https://pub.flutter-io.cn"
473 | source: hosted
474 | version: "1.0.15"
475 | xml:
476 | dependency: transitive
477 | description:
478 | name: xml
479 | url: "https://pub.flutter-io.cn"
480 | source: hosted
481 | version: "3.5.0"
482 | yaml:
483 | dependency: transitive
484 | description:
485 | name: yaml
486 | url: "https://pub.flutter-io.cn"
487 | source: hosted
488 | version: "2.1.15"
489 | sdks:
490 | dart: ">=2.4.0 <3.0.0"
491 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: ninghao_flutter
2 | description: A new Flutter project.
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # Read more about versioning at semver.org.
10 | version: 1.0.0+1
11 |
12 | dependencies:
13 | flutter:
14 | sdk: flutter
15 | intl: ^0.16.0
16 | scoped_model: ^0.3.0
17 | rxdart: ^0.18.1
18 | http: ^0.12.0
19 | flutter_localizations:
20 | sdk: flutter
21 |
22 | # The following adds the Cupertino Icons font to your application.
23 | # Use with the CupertinoIcons class for iOS style icons.
24 | cupertino_icons: ^0.1.2
25 |
26 | dev_dependencies:
27 | flutter_test:
28 | sdk: flutter
29 | flutter_driver:
30 | sdk: flutter
31 | intl_translation: ^0.17.2
32 | test: ^1.5.1
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 | # The following line ensures that the Material Icons font is
40 | # included with your application, so that you can use the icons in
41 | # the material Icons class.
42 | uses-material-design: true
43 | # To add assets to your application, add an assets section, like this:
44 | # assets:
45 | # - images/a_dot_burr.jpeg
46 | # - images/a_dot_ham.jpeg
47 | # An image asset can refer to one or more resolution-specific "variants", see
48 | # https://flutter.io/assets-and-images/#resolution-aware.
49 | # For details regarding adding assets from package dependencies, see
50 | # https://flutter.io/assets-and-images/#from-packages
51 | # To add custom fonts to your application, add a fonts section here,
52 | # in this "flutter" section. Each entry in this list should have a
53 | # "family" key with the font family name, and a "fonts" key with a
54 | # list giving the asset and other descriptors for the font. For
55 | # example:
56 | # fonts:
57 | # - family: Schyler
58 | # fonts:
59 | # - asset: fonts/Schyler-Regular.ttf
60 | # - asset: fonts/Schyler-Italic.ttf
61 | # style: italic
62 | # - family: Trajan Pro
63 | # fonts:
64 | # - asset: fonts/TrajanPro.ttf
65 | # - asset: fonts/TrajanPro_Bold.ttf
66 | # weight: 700
67 | #
68 | # For details regarding fonts from package dependencies,
69 | # see https://flutter.io/custom-fonts/#from-packages
70 |
--------------------------------------------------------------------------------
/test/ninghao_demo_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 | import 'package:ninghao_flutter/demo/test/test_demo.dart';
4 |
5 | void main() {
6 | test('should return hello + something.', () {
7 | var string = NinghaoTestDemo.greet('ninghao');
8 | expect(string, 'hello ninghao ~~');
9 | });
10 |
11 | testWidgets('widget testing demo', (WidgetTester tester) async {
12 | await tester.pumpWidget(
13 | MaterialApp(
14 | home: TestDemo()
15 | )
16 | );
17 |
18 | final labelText = find.text('hello');
19 |
20 | // expect(labelText, findsNothing);
21 | // expect(labelText, findsOneWidget);
22 | expect(labelText, findsNWidgets(1));
23 |
24 | final actionChipLabelText = find.text('0');
25 | expect(actionChipLabelText, findsOneWidget);
26 |
27 | final actionChip = find.byType(ActionChip);
28 | await tester.tap(actionChip);
29 | await tester.pump();
30 |
31 | final actionChipLabelTextAfterTap = find.text('1');
32 | expect(actionChipLabelTextAfterTap, findsOneWidget);
33 | expect(actionChipLabelText, findsNothing);
34 | });
35 | }
--------------------------------------------------------------------------------
/test_driver/app.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_driver/driver_extension.dart';
2 | import 'package:ninghao_flutter/main.dart' as app;
3 |
4 | void main() {
5 | enableFlutterDriverExtension();
6 |
7 | app.main();
8 | }
--------------------------------------------------------------------------------
/test_driver/app_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_driver/flutter_driver.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('App', () {
6 | FlutterDriver driver;
7 |
8 | final actionChip = find.byValueKey('actionChip');
9 | final actionChipLabelText = find.byValueKey('actionChipLabelText');
10 |
11 | setUpAll(() async {
12 | driver = await FlutterDriver.connect();
13 | });
14 |
15 | tearDownAll(() async {
16 | if (driver != null) {
17 | driver.close();
18 | }
19 | });
20 |
21 | test('starts at 0', () async {
22 | expect(await driver.getText(actionChipLabelText), '0');
23 | });
24 |
25 | test('increments the counter', () async {
26 | await driver.tap(actionChip);
27 |
28 | expect(await driver.getText(actionChipLabelText), '1');
29 | });
30 | });
31 | }
--------------------------------------------------------------------------------