├── .gitignore
├── .metadata
├── README.md
├── android
├── .gradle
│ ├── 4.10.2
│ │ ├── fileChanges
│ │ │ └── last-build.bin
│ │ ├── fileContent
│ │ │ └── fileContent.lock
│ │ ├── fileHashes
│ │ │ ├── fileHashes.bin
│ │ │ ├── fileHashes.lock
│ │ │ └── resourceHashesCache.bin
│ │ ├── gc.properties
│ │ ├── javaCompile
│ │ │ ├── classAnalysis.bin
│ │ │ ├── jarAnalysis.bin
│ │ │ ├── javaCompile.lock
│ │ │ └── taskHistory.bin
│ │ └── taskHistory
│ │ │ ├── taskHistory.bin
│ │ │ └── taskHistory.lock
│ ├── buildOutputCleanup
│ │ ├── buildOutputCleanup.lock
│ │ ├── cache.properties
│ │ └── outputFiles.bin
│ └── vcs-1
│ │ └── gc.properties
├── app
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ ├── com
│ │ │ └── example
│ │ │ │ └── maccmsapp
│ │ │ │ └── MainActivity.java
│ │ └── io
│ │ │ └── flutter
│ │ │ └── plugins
│ │ │ └── GeneratedPluginRegistrant.java
│ │ └── res
│ │ ├── drawable
│ │ └── launch_background.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── logo.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── logo.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── logo.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── logo.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── logo.png
│ │ └── values
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
├── flutter_01.png
├── fonts
└── base.ttf
├── images
├── about.png
├── avatar.png
├── avatar.png.abk
├── feedback.png
├── heji.png
├── history.png
├── icon_category.png
├── icon_category_active.png
├── icon_discovery.png
├── icon_discovery_active.png
├── icon_mine.png
├── icon_mine_active.png
├── index_discovery_logo2.png
├── setting.png
└── statement.png
├── ios
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ ├── Generated.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ └── contents.xcworkspacedata
└── Runner
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── GeneratedPluginRegistrant.h
│ ├── GeneratedPluginRegistrant.m
│ ├── Info.plist
│ └── main.m
├── lib
├── MyWidGet
│ ├── Base_Font.dart
│ └── pull_to_refresh_notification.dart
├── constant.dart
├── main.dart
└── pages
│ ├── About.dart
│ ├── App.dart
│ ├── Cate.dart
│ ├── Detail.dart
│ ├── Home.dart
│ ├── HomeBak.dart
│ ├── My.dart
│ ├── StartPage.dart
│ └── Statement.dart
├── maccms_app.iml
├── maccms_app_android.iml
├── pubspec.lock
├── pubspec.yaml
└── test
└── widget_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | # Visual Studio Code related
2 | .vscode/
3 |
4 | # Flutter/Dart/Pub related
5 | **/doc/api/
6 | .dart_tool/
7 | .flutter-plugins
8 | .packages
9 | .pub-cache/
10 | .pub/
11 | build/
12 |
13 | *.log
14 |
15 | android/key.properties
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.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: 72bf075e8d6961d2ca6df462b2228954f8d0e73a
8 | channel: beta
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 一个简陋的flutter影视APP半成品
2 |
3 | 萌新的第一个flutter应用,仿的一个叫neets的应用,没在iOS上测试过,播放页可能会有问题,没啥技术含量,因为第一次写,代码写的有点烂
4 | 目前完成了首页,类别,我的,播放页,关于,免责。
5 | 个人中心,登录/注册,设置,反馈,搜索,播放记录还没做,播放页切换集数还没写完。
6 | 后面慢慢加上去吧,恩...
7 |
8 | 开发:[vomicas](https://github.com/vomicas)
9 | ## 应用截图
10 |
11 | 首页
12 |
13 |
14 | 类别
15 |
16 |
17 | 我的
18 |
19 |
20 | 播放
21 |
22 |
23 |
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/fileChanges/last-build.bin:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/fileContent/fileContent.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/fileContent/fileContent.lock
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/fileHashes/fileHashes.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/fileHashes/fileHashes.bin
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/fileHashes/fileHashes.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/fileHashes/fileHashes.lock
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/fileHashes/resourceHashesCache.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/fileHashes/resourceHashesCache.bin
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/gc.properties
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/javaCompile/classAnalysis.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/javaCompile/classAnalysis.bin
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/javaCompile/jarAnalysis.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/javaCompile/jarAnalysis.bin
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/javaCompile/javaCompile.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/javaCompile/javaCompile.lock
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/javaCompile/taskHistory.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/javaCompile/taskHistory.bin
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/taskHistory/taskHistory.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/taskHistory/taskHistory.bin
--------------------------------------------------------------------------------
/android/.gradle/4.10.2/taskHistory/taskHistory.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/4.10.2/taskHistory/taskHistory.lock
--------------------------------------------------------------------------------
/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
--------------------------------------------------------------------------------
/android/.gradle/buildOutputCleanup/cache.properties:
--------------------------------------------------------------------------------
1 | #Fri Nov 16 09:19:04 CST 2018
2 | gradle.version=4.10.2
3 |
--------------------------------------------------------------------------------
/android/.gradle/buildOutputCleanup/outputFiles.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/buildOutputCleanup/outputFiles.bin
--------------------------------------------------------------------------------
/android/.gradle/vcs-1/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/.gradle/vcs-1/gc.properties
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | //def keystorePropertiesFile = rootProject.file("key.properties")
28 | //def keystoreProperties = new Properties()
29 | //keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
30 |
31 | android {
32 | compileSdkVersion 27
33 |
34 | lintOptions {
35 | disable 'InvalidPackage'
36 | }
37 |
38 | defaultConfig {
39 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
40 | applicationId "com.meioco.macapp"
41 | minSdkVersion 16
42 | targetSdkVersion 27
43 | versionCode 1
44 | versionName "0.0.1.1"
45 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
46 | }
47 |
48 | buildTypes {
49 | release {
50 | // TODO: Add your own signing config for the release build.
51 | // Signing with the debug keys for now, so `flutter run --release` works.
52 | signingConfig signingConfigs.debug
53 | }
54 | }
55 |
56 | /*
57 | signingConfigs {
58 | release {
59 | keyAlias keystoreProperties['keyAlias']
60 | keyPassword keystoreProperties['keyPassword']
61 | storeFile file(keystoreProperties['storeFile'])
62 | storePassword keystoreProperties['storePassword']
63 | }
64 | }
65 | buildTypes {
66 | release {
67 | signingConfig signingConfigs.release
68 | }
69 | }
70 | */
71 | }
72 |
73 | flutter {
74 | source '../..'
75 | }
76 |
77 | dependencies {
78 | testImplementation 'junit:junit:4.12'
79 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
80 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
81 | }
82 |
--------------------------------------------------------------------------------
/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/maccmsapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.maccmsapp;
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/java/io/flutter/plugins/GeneratedPluginRegistrant.java:
--------------------------------------------------------------------------------
1 | package io.flutter.plugins;
2 |
3 | import io.flutter.plugin.common.PluginRegistry;
4 | import io.flutter.plugins.videoplayer.VideoPlayerPlugin;
5 |
6 | /**
7 | * Generated file. Do not edit.
8 | */
9 | public final class GeneratedPluginRegistrant {
10 | public static void registerWith(PluginRegistry registry) {
11 | if (alreadyRegisteredWith(registry)) {
12 | return;
13 | }
14 | VideoPlayerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.videoplayer.VideoPlayerPlugin"));
15 | }
16 |
17 | private static boolean alreadyRegisteredWith(PluginRegistry registry) {
18 | final String key = GeneratedPluginRegistrant.class.getCanonicalName();
19 | if (registry.hasPlugin(key)) {
20 | return true;
21 | }
22 | registry.registrarFor(key);
23 | return false;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-hdpi/logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-mdpi/logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-xhdpi/logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-xxhdpi/logo.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/android/app/src/main/res/mipmap-xxxhdpi/logo.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.2.1'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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.10.2-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/local.properties:
--------------------------------------------------------------------------------
1 | flutter.sdk=F:\\Tool\\flutter
2 | flutter.versionName=1.0.0
3 | flutter.versionCode=1
4 | sdk.dir=F:\\Android SDK
5 | flutter.buildMode=release
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/flutter_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/flutter_01.png
--------------------------------------------------------------------------------
/fonts/base.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/fonts/base.ttf
--------------------------------------------------------------------------------
/images/about.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/about.png
--------------------------------------------------------------------------------
/images/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/avatar.png
--------------------------------------------------------------------------------
/images/avatar.png.abk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/avatar.png.abk
--------------------------------------------------------------------------------
/images/feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/feedback.png
--------------------------------------------------------------------------------
/images/heji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/heji.png
--------------------------------------------------------------------------------
/images/history.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/history.png
--------------------------------------------------------------------------------
/images/icon_category.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/icon_category.png
--------------------------------------------------------------------------------
/images/icon_category_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/icon_category_active.png
--------------------------------------------------------------------------------
/images/icon_discovery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/icon_discovery.png
--------------------------------------------------------------------------------
/images/icon_discovery_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/icon_discovery_active.png
--------------------------------------------------------------------------------
/images/icon_mine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/icon_mine.png
--------------------------------------------------------------------------------
/images/icon_mine_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/icon_mine_active.png
--------------------------------------------------------------------------------
/images/index_discovery_logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/index_discovery_logo2.png
--------------------------------------------------------------------------------
/images/setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/setting.png
--------------------------------------------------------------------------------
/images/statement.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/images/statement.png
--------------------------------------------------------------------------------
/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/Generated.xcconfig:
--------------------------------------------------------------------------------
1 | // This is a generated file; do not edit or check into version control.
2 | FLUTTER_ROOT=F:\Tool\flutter
3 | FLUTTER_APPLICATION_PATH=F:\Flutter\maccms_app
4 | FLUTTER_TARGET=lib/main.dart
5 | FLUTTER_BUILD_DIR=build
6 | SYMROOT=${SOURCE_ROOT}/../build\ios
7 | FLUTTER_FRAMEWORK_DIR=F:\Tool\flutter\bin\cache\artifacts\engine\ios
8 | FLUTTER_BUILD_NAME=1.0.0
9 | FLUTTER_BUILD_NUMBER=1
10 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
14 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
18 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
19 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
20 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
21 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
22 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXCopyFilesBuildPhase section */
26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
27 | isa = PBXCopyFilesBuildPhase;
28 | buildActionMask = 2147483647;
29 | dstPath = "";
30 | dstSubfolderSpec = 10;
31 | files = (
32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
34 | );
35 | name = "Embed Frameworks";
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXCopyFilesBuildPhase section */
39 |
40 | /* Begin PBXFileReference section */
41 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
42 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
43 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
44 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
45 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
47 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
48 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
49 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
50 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
51 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
52 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
54 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
55 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
56 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
57 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
66 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | /* End PBXFrameworksBuildPhase section */
71 |
72 | /* Begin PBXGroup section */
73 | 9740EEB11CF90186004384FC /* Flutter */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
77 | 3B80C3931E831B6300D905FE /* App.framework */,
78 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
79 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
81 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
82 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
83 | );
84 | name = Flutter;
85 | sourceTree = "";
86 | };
87 | 97C146E51CF9000F007C117D = {
88 | isa = PBXGroup;
89 | children = (
90 | 9740EEB11CF90186004384FC /* Flutter */,
91 | 97C146F01CF9000F007C117D /* Runner */,
92 | 97C146EF1CF9000F007C117D /* Products */,
93 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */,
94 | );
95 | sourceTree = "";
96 | };
97 | 97C146EF1CF9000F007C117D /* Products */ = {
98 | isa = PBXGroup;
99 | children = (
100 | 97C146EE1CF9000F007C117D /* Runner.app */,
101 | );
102 | name = Products;
103 | sourceTree = "";
104 | };
105 | 97C146F01CF9000F007C117D /* Runner */ = {
106 | isa = PBXGroup;
107 | children = (
108 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
109 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
110 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
111 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
112 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
113 | 97C147021CF9000F007C117D /* Info.plist */,
114 | 97C146F11CF9000F007C117D /* Supporting Files */,
115 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
116 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
117 | );
118 | path = Runner;
119 | sourceTree = "";
120 | };
121 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 97C146F21CF9000F007C117D /* main.m */,
125 | );
126 | name = "Supporting Files";
127 | sourceTree = "";
128 | };
129 | /* End PBXGroup section */
130 |
131 | /* Begin PBXNativeTarget section */
132 | 97C146ED1CF9000F007C117D /* Runner */ = {
133 | isa = PBXNativeTarget;
134 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
135 | buildPhases = (
136 | 9740EEB61CF901F6004384FC /* Run Script */,
137 | 97C146EA1CF9000F007C117D /* Sources */,
138 | 97C146EB1CF9000F007C117D /* Frameworks */,
139 | 97C146EC1CF9000F007C117D /* Resources */,
140 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
142 | );
143 | buildRules = (
144 | );
145 | dependencies = (
146 | );
147 | name = Runner;
148 | productName = Runner;
149 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
150 | productType = "com.apple.product-type.application";
151 | };
152 | /* End PBXNativeTarget section */
153 |
154 | /* Begin PBXProject section */
155 | 97C146E61CF9000F007C117D /* Project object */ = {
156 | isa = PBXProject;
157 | attributes = {
158 | LastUpgradeCheck = 0910;
159 | ORGANIZATIONNAME = "The Chromium Authors";
160 | TargetAttributes = {
161 | 97C146ED1CF9000F007C117D = {
162 | CreatedOnToolsVersion = 7.3.1;
163 | };
164 | };
165 | };
166 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
167 | compatibilityVersion = "Xcode 3.2";
168 | developmentRegion = English;
169 | hasScannedForEncodings = 0;
170 | knownRegions = (
171 | en,
172 | Base,
173 | );
174 | mainGroup = 97C146E51CF9000F007C117D;
175 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
176 | projectDirPath = "";
177 | projectRoot = "";
178 | targets = (
179 | 97C146ED1CF9000F007C117D /* Runner */,
180 | );
181 | };
182 | /* End PBXProject section */
183 |
184 | /* Begin PBXResourcesBuildPhase section */
185 | 97C146EC1CF9000F007C117D /* Resources */ = {
186 | isa = PBXResourcesBuildPhase;
187 | buildActionMask = 2147483647;
188 | files = (
189 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
190 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
191 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
192 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
193 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | };
198 | /* End PBXResourcesBuildPhase section */
199 |
200 | /* Begin PBXShellScriptBuildPhase section */
201 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
202 | isa = PBXShellScriptBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | );
206 | inputPaths = (
207 | );
208 | name = "Thin Binary";
209 | outputPaths = (
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | shellPath = /bin/sh;
213 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
214 | };
215 | 9740EEB61CF901F6004384FC /* Run Script */ = {
216 | isa = PBXShellScriptBuildPhase;
217 | buildActionMask = 2147483647;
218 | files = (
219 | );
220 | inputPaths = (
221 | );
222 | name = "Run Script";
223 | outputPaths = (
224 | );
225 | runOnlyForDeploymentPostprocessing = 0;
226 | shellPath = /bin/sh;
227 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
228 | };
229 | /* End PBXShellScriptBuildPhase section */
230 |
231 | /* Begin PBXSourcesBuildPhase section */
232 | 97C146EA1CF9000F007C117D /* Sources */ = {
233 | isa = PBXSourcesBuildPhase;
234 | buildActionMask = 2147483647;
235 | files = (
236 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
237 | 97C146F31CF9000F007C117D /* main.m in Sources */,
238 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
239 | );
240 | runOnlyForDeploymentPostprocessing = 0;
241 | };
242 | /* End PBXSourcesBuildPhase section */
243 |
244 | /* Begin PBXVariantGroup section */
245 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
246 | isa = PBXVariantGroup;
247 | children = (
248 | 97C146FB1CF9000F007C117D /* Base */,
249 | );
250 | name = Main.storyboard;
251 | sourceTree = "";
252 | };
253 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
254 | isa = PBXVariantGroup;
255 | children = (
256 | 97C147001CF9000F007C117D /* Base */,
257 | );
258 | name = LaunchScreen.storyboard;
259 | sourceTree = "";
260 | };
261 | /* End PBXVariantGroup section */
262 |
263 | /* Begin XCBuildConfiguration section */
264 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
265 | isa = XCBuildConfiguration;
266 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
267 | buildSettings = {
268 | ALWAYS_SEARCH_USER_PATHS = NO;
269 | CLANG_ANALYZER_NONNULL = YES;
270 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
271 | CLANG_CXX_LIBRARY = "libc++";
272 | CLANG_ENABLE_MODULES = YES;
273 | CLANG_ENABLE_OBJC_ARC = YES;
274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
275 | CLANG_WARN_BOOL_CONVERSION = YES;
276 | CLANG_WARN_COMMA = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
279 | CLANG_WARN_EMPTY_BODY = YES;
280 | CLANG_WARN_ENUM_CONVERSION = YES;
281 | CLANG_WARN_INFINITE_RECURSION = YES;
282 | CLANG_WARN_INT_CONVERSION = YES;
283 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
284 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
285 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
286 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
287 | CLANG_WARN_STRICT_PROTOTYPES = YES;
288 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
289 | CLANG_WARN_UNREACHABLE_CODE = YES;
290 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
291 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
292 | COPY_PHASE_STRIP = NO;
293 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
294 | ENABLE_NS_ASSERTIONS = NO;
295 | ENABLE_STRICT_OBJC_MSGSEND = YES;
296 | GCC_C_LANGUAGE_STANDARD = gnu99;
297 | GCC_NO_COMMON_BLOCKS = YES;
298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
300 | GCC_WARN_UNDECLARED_SELECTOR = YES;
301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
302 | GCC_WARN_UNUSED_FUNCTION = YES;
303 | GCC_WARN_UNUSED_VARIABLE = YES;
304 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
305 | MTL_ENABLE_DEBUG_INFO = NO;
306 | SDKROOT = iphoneos;
307 | TARGETED_DEVICE_FAMILY = "1,2";
308 | VALIDATE_PRODUCT = YES;
309 | };
310 | name = Profile;
311 | };
312 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
313 | isa = XCBuildConfiguration;
314 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
315 | buildSettings = {
316 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
317 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
318 | DEVELOPMENT_TEAM = S8QB4VV633;
319 | ENABLE_BITCODE = NO;
320 | FRAMEWORK_SEARCH_PATHS = (
321 | "$(inherited)",
322 | "$(PROJECT_DIR)/Flutter",
323 | );
324 | INFOPLIST_FILE = Runner/Info.plist;
325 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
326 | LIBRARY_SEARCH_PATHS = (
327 | "$(inherited)",
328 | "$(PROJECT_DIR)/Flutter",
329 | );
330 | PRODUCT_BUNDLE_IDENTIFIER = com.example.maccmsApp;
331 | PRODUCT_NAME = "$(TARGET_NAME)";
332 | VERSIONING_SYSTEM = "apple-generic";
333 | };
334 | name = Profile;
335 | };
336 | 97C147031CF9000F007C117D /* Debug */ = {
337 | isa = XCBuildConfiguration;
338 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
339 | buildSettings = {
340 | ALWAYS_SEARCH_USER_PATHS = NO;
341 | CLANG_ANALYZER_NONNULL = YES;
342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
343 | CLANG_CXX_LIBRARY = "libc++";
344 | CLANG_ENABLE_MODULES = YES;
345 | CLANG_ENABLE_OBJC_ARC = YES;
346 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
347 | CLANG_WARN_BOOL_CONVERSION = YES;
348 | CLANG_WARN_COMMA = YES;
349 | CLANG_WARN_CONSTANT_CONVERSION = YES;
350 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
351 | CLANG_WARN_EMPTY_BODY = YES;
352 | CLANG_WARN_ENUM_CONVERSION = YES;
353 | CLANG_WARN_INFINITE_RECURSION = YES;
354 | CLANG_WARN_INT_CONVERSION = YES;
355 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
356 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
357 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
358 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
359 | CLANG_WARN_STRICT_PROTOTYPES = YES;
360 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
361 | CLANG_WARN_UNREACHABLE_CODE = YES;
362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
364 | COPY_PHASE_STRIP = NO;
365 | DEBUG_INFORMATION_FORMAT = dwarf;
366 | ENABLE_STRICT_OBJC_MSGSEND = YES;
367 | ENABLE_TESTABILITY = YES;
368 | GCC_C_LANGUAGE_STANDARD = gnu99;
369 | GCC_DYNAMIC_NO_PIC = NO;
370 | GCC_NO_COMMON_BLOCKS = YES;
371 | GCC_OPTIMIZATION_LEVEL = 0;
372 | GCC_PREPROCESSOR_DEFINITIONS = (
373 | "DEBUG=1",
374 | "$(inherited)",
375 | );
376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
378 | GCC_WARN_UNDECLARED_SELECTOR = YES;
379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
380 | GCC_WARN_UNUSED_FUNCTION = YES;
381 | GCC_WARN_UNUSED_VARIABLE = YES;
382 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
383 | MTL_ENABLE_DEBUG_INFO = YES;
384 | ONLY_ACTIVE_ARCH = YES;
385 | SDKROOT = iphoneos;
386 | TARGETED_DEVICE_FAMILY = "1,2";
387 | };
388 | name = Debug;
389 | };
390 | 97C147041CF9000F007C117D /* Release */ = {
391 | isa = XCBuildConfiguration;
392 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
393 | buildSettings = {
394 | ALWAYS_SEARCH_USER_PATHS = NO;
395 | CLANG_ANALYZER_NONNULL = YES;
396 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
397 | CLANG_CXX_LIBRARY = "libc++";
398 | CLANG_ENABLE_MODULES = YES;
399 | CLANG_ENABLE_OBJC_ARC = YES;
400 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
401 | CLANG_WARN_BOOL_CONVERSION = YES;
402 | CLANG_WARN_COMMA = YES;
403 | CLANG_WARN_CONSTANT_CONVERSION = YES;
404 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
405 | CLANG_WARN_EMPTY_BODY = YES;
406 | CLANG_WARN_ENUM_CONVERSION = YES;
407 | CLANG_WARN_INFINITE_RECURSION = YES;
408 | CLANG_WARN_INT_CONVERSION = YES;
409 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
410 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
411 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
412 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
413 | CLANG_WARN_STRICT_PROTOTYPES = YES;
414 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
415 | CLANG_WARN_UNREACHABLE_CODE = YES;
416 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
417 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
418 | COPY_PHASE_STRIP = NO;
419 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
420 | ENABLE_NS_ASSERTIONS = NO;
421 | ENABLE_STRICT_OBJC_MSGSEND = YES;
422 | GCC_C_LANGUAGE_STANDARD = gnu99;
423 | GCC_NO_COMMON_BLOCKS = YES;
424 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
425 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
426 | GCC_WARN_UNDECLARED_SELECTOR = YES;
427 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
428 | GCC_WARN_UNUSED_FUNCTION = YES;
429 | GCC_WARN_UNUSED_VARIABLE = YES;
430 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
431 | MTL_ENABLE_DEBUG_INFO = NO;
432 | SDKROOT = iphoneos;
433 | TARGETED_DEVICE_FAMILY = "1,2";
434 | VALIDATE_PRODUCT = YES;
435 | };
436 | name = Release;
437 | };
438 | 97C147061CF9000F007C117D /* Debug */ = {
439 | isa = XCBuildConfiguration;
440 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
441 | buildSettings = {
442 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
443 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
444 | ENABLE_BITCODE = NO;
445 | FRAMEWORK_SEARCH_PATHS = (
446 | "$(inherited)",
447 | "$(PROJECT_DIR)/Flutter",
448 | );
449 | INFOPLIST_FILE = Runner/Info.plist;
450 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
451 | LIBRARY_SEARCH_PATHS = (
452 | "$(inherited)",
453 | "$(PROJECT_DIR)/Flutter",
454 | );
455 | PRODUCT_BUNDLE_IDENTIFIER = com.example.maccmsApp;
456 | PRODUCT_NAME = "$(TARGET_NAME)";
457 | VERSIONING_SYSTEM = "apple-generic";
458 | };
459 | name = Debug;
460 | };
461 | 97C147071CF9000F007C117D /* Release */ = {
462 | isa = XCBuildConfiguration;
463 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
464 | buildSettings = {
465 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
466 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
467 | ENABLE_BITCODE = NO;
468 | FRAMEWORK_SEARCH_PATHS = (
469 | "$(inherited)",
470 | "$(PROJECT_DIR)/Flutter",
471 | );
472 | INFOPLIST_FILE = Runner/Info.plist;
473 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
474 | LIBRARY_SEARCH_PATHS = (
475 | "$(inherited)",
476 | "$(PROJECT_DIR)/Flutter",
477 | );
478 | PRODUCT_BUNDLE_IDENTIFIER = com.example.maccmsApp;
479 | PRODUCT_NAME = "$(TARGET_NAME)";
480 | VERSIONING_SYSTEM = "apple-generic";
481 | };
482 | name = Release;
483 | };
484 | /* End XCBuildConfiguration section */
485 |
486 | /* Begin XCConfigurationList section */
487 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
488 | isa = XCConfigurationList;
489 | buildConfigurations = (
490 | 97C147031CF9000F007C117D /* Debug */,
491 | 97C147041CF9000F007C117D /* Release */,
492 | 249021D3217E4FDB00AE95B9 /* Profile */,
493 | );
494 | defaultConfigurationIsVisible = 0;
495 | defaultConfigurationName = Release;
496 | };
497 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
498 | isa = XCConfigurationList;
499 | buildConfigurations = (
500 | 97C147061CF9000F007C117D /* Debug */,
501 | 97C147071CF9000F007C117D /* Release */,
502 | 249021D4217E4FDB00AE95B9 /* Profile */,
503 | );
504 | defaultConfigurationIsVisible = 0;
505 | defaultConfigurationName = Release;
506 | };
507 | /* End XCConfigurationList section */
508 | };
509 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
510 | }
511 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/a-long-way/FlutterMovieApp/15a3e00e17d032f6e3aaad53a737f99450842340/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/GeneratedPluginRegistrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #ifndef GeneratedPluginRegistrant_h
6 | #define GeneratedPluginRegistrant_h
7 |
8 | #import
9 |
10 | @interface GeneratedPluginRegistrant : NSObject
11 | + (void)registerWithRegistry:(NSObject*)registry;
12 | @end
13 |
14 | #endif /* GeneratedPluginRegistrant_h */
15 |
--------------------------------------------------------------------------------
/ios/Runner/GeneratedPluginRegistrant.m:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | #import "GeneratedPluginRegistrant.h"
6 | #import
7 |
8 | @implementation GeneratedPluginRegistrant
9 |
10 | + (void)registerWithRegistry:(NSObject*)registry {
11 | [FLTVideoPlayerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTVideoPlayerPlugin"]];
12 | }
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/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 | maccms_app
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/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/MyWidGet/Base_Font.dart:
--------------------------------------------------------------------------------
1 | /// Flutter icons MyFlutterApp
2 | /// Copyright (C) 2018 by original authors @ fluttericon.com, fontello.com
3 | /// This font was generated by FlutterIcon.com, which is derived from Fontello.
4 | ///
5 | /// To use this font, place it in your fonts/ directory and include the
6 | /// following in your pubspec.yaml
7 | ///
8 | /// flutter:
9 | /// fonts:
10 | /// - family: MyFlutterApp
11 | /// fonts:
12 | /// - asset: fonts/MyFlutterApp.ttf
13 | ///
14 | ///
15 | ///
16 | import 'package:flutter/widgets.dart';
17 |
18 | class Base {
19 | Base._();
20 |
21 | static const _kFontFam = 'Base';
22 |
23 | static const IconData sousuo = const IconData(0xe800, fontFamily: _kFontFam);
24 | static const IconData lishi = const IconData(0xe801, fontFamily: _kFontFam);
25 | static const IconData sousuo1 = const IconData(0xe802, fontFamily: _kFontFam);
26 | static const IconData lishi1 = const IconData(0xe803, fontFamily: _kFontFam);
27 | static const IconData dingyue = const IconData(0xe804, fontFamily: _kFontFam);
28 | static const IconData fankui = const IconData(0xe805, fontFamily: _kFontFam);
29 | static const IconData fankuixuanzhong = const IconData(0xe806, fontFamily: _kFontFam);
30 | static const IconData guanyu = const IconData(0xe807, fontFamily: _kFontFam);
31 | static const IconData guanyuxuanzhong = const IconData(0xe808, fontFamily: _kFontFam);
32 | static const IconData heji = const IconData(0xe809, fontFamily: _kFontFam);
33 | static const IconData huati = const IconData(0xe80a, fontFamily: _kFontFam);
34 | static const IconData huatixuanzhong = const IconData(0xe80b, fontFamily: _kFontFam);
35 | static const IconData leibie = const IconData(0xe80c, fontFamily: _kFontFam);
36 | static const IconData leibiexuanzhong = const IconData(0xe80d, fontFamily: _kFontFam);
37 | static const IconData mianze = const IconData(0xe80e, fontFamily: _kFontFam);
38 | static const IconData mianzexuanzhong = const IconData(0xe80f, fontFamily: _kFontFam);
39 | static const IconData qingdan = const IconData(0xe810, fontFamily: _kFontFam);
40 | static const IconData qingdanxuanzhong = const IconData(0xe811, fontFamily: _kFontFam);
41 | static const IconData shezhi = const IconData(0xe812, fontFamily: _kFontFam);
42 | static const IconData shezhixuanzhong = const IconData(0xe813, fontFamily: _kFontFam);
43 | static const IconData zujixuanzhong = const IconData(0xe814, fontFamily: _kFontFam);
44 | static const IconData zuji = const IconData(0xe815, fontFamily: _kFontFam);
45 | static const IconData wodexuanzhong = const IconData(0xe816, fontFamily: _kFontFam);
46 | static const IconData wode = const IconData(0xe817, fontFamily: _kFontFam);
47 | static const IconData shouyexuanzhong = const IconData(0xe818, fontFamily: _kFontFam);
48 | static const IconData shouye = const IconData(0xe819, fontFamily: _kFontFam);
49 | static const IconData shoujihaoxuanzhong = const IconData(0xe81a, fontFamily: _kFontFam);
50 | static const IconData shoujihao = const IconData(0xe81b, fontFamily: _kFontFam);
51 | }
52 |
--------------------------------------------------------------------------------
/lib/MyWidGet/pull_to_refresh_notification.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 | import 'dart:math' as math;
4 |
5 | import 'package:flutter/material.dart';
6 | import 'package:flutter/widgets.dart';
7 | import 'package:flutter/foundation.dart';
8 | import 'package:flutter/cupertino.dart';
9 |
10 | // The over-scroll distance that moves the indicator to its maximum
11 | // displacement, as a percentage of the scrollable's container extent.
12 | const double _kDragContainerExtentPercentage = 0.25;
13 |
14 | // How much the scroll's drag gesture can overshoot the RefreshIndicator's
15 | // displacement; max displacement = _kDragSizeFactorLimit * displacement.
16 | const double _kDragSizeFactorLimit = 1.5;
17 |
18 | // When the scroll ends, the duration of the refresh indicator's animation
19 | // to the RefreshIndicator's displacement.
20 | const Duration _kIndicatorSnapDuration = Duration(milliseconds: 150);
21 |
22 | // The duration of the ScaleTransition that starts when the refresh action
23 | // has completed.
24 | const Duration _kIndicatorScaleDuration = Duration(milliseconds: 200);
25 |
26 | /// The signature for a function that's called when the user has dragged a
27 | /// [PullToRefreshNotification] far enough to demonstrate that they want the app to
28 | /// refresh. The returned [Future] must complete when the refresh operation is
29 | /// finished.
30 | ///
31 | /// Used by [PullToRefreshNotification.onRefresh].
32 | typedef RefreshCallback = Future Function();
33 |
34 | // The state machine moves through these modes only when the scrollable
35 | // identified by scrollableKey has been scrolled to its min or max limit.
36 | enum RefreshIndicatorMode {
37 | drag, // Pointer is down.
38 | armed, // Dragged far enough that an up event will run the onRefresh callback.
39 | snap, // Animating to the indicator's final "displacement".
40 | refresh, // Running the refresh callback.
41 | done, // Animating the indicator's fade-out after refreshing.
42 | canceled, // Animating the indicator's fade-out after not arming.
43 | error, //refresh failed
44 | }
45 |
46 | class PullToRefreshNotification extends StatefulWidget {
47 | /// Creates a refresh indicator.
48 | ///
49 | /// The [onRefresh], [child], and [notificationPredicate] arguments must be
50 | /// non-null. The default
51 | /// [displacement] is 40.0 logical pixels.
52 | const PullToRefreshNotification({
53 | Key key,
54 | @required this.child,
55 | @required this.onRefresh,
56 | this.color,
57 | this.pullBackOnRefresh: false,
58 | this.maxDragOffset,
59 | this.notificationPredicate = defaultNotificationPredicate,
60 | }) : assert(child != null),
61 | assert(onRefresh != null),
62 | assert(notificationPredicate != null),
63 | super(key: key);
64 |
65 | /// The widget below this widget in the tree.
66 | ///
67 | /// The refresh indicator will be stacked on top of this child. The indicator
68 | /// will appear when child's Scrollable descendant is over-scrolled.
69 | ///
70 | /// Typically a [ListView] or [CustomScrollView].
71 | final Widget child;
72 |
73 | /// A function that's called when the user has dragged the refresh indicator
74 | /// far enough to demonstrate that they want the app to refresh. The returned
75 | /// [Future] must complete when the refresh operation is finished.
76 | final RefreshCallback onRefresh;
77 |
78 | /// The progress indicator's foreground color. The current theme's
79 | /// /// [ThemeData.accentColor] by default. only for android
80 | final Color color;
81 |
82 | //whether start pull back animation when refresh.
83 | final bool pullBackOnRefresh;
84 |
85 | //the max drag offset
86 | final double maxDragOffset;
87 |
88 | //use in case much ScrollNotification from child
89 | final bool Function(ScrollNotification notification) notificationPredicate;
90 |
91 | @override
92 | PullToRefreshNotificationState createState() =>
93 | PullToRefreshNotificationState();
94 | }
95 |
96 | /// Contains the state for a [PullToRefreshNotification]. This class can be used to
97 | /// programmatically show the refresh indicator, see the [show] method.
98 | class PullToRefreshNotificationState extends State
99 | with TickerProviderStateMixin {
100 | final _onNoticed =
101 | new StreamController.broadcast();
102 | Stream get onNoticed =>
103 | _onNoticed.stream;
104 |
105 | AnimationController _positionController;
106 | AnimationController _scaleController;
107 | Animation _scaleFactor;
108 | Animation _value;
109 | Animation _valueColor;
110 |
111 | AnimationController _pullBackController;
112 | Animation _pullBackFactor;
113 |
114 | RefreshIndicatorMode _mode;
115 | RefreshIndicatorMode get _Mode => _mode;
116 | set _Mode(value) {
117 | if (_mode != value) {
118 | _mode = value;
119 | _onInnerNoticed();
120 | }
121 | }
122 |
123 | Future _pendingRefreshFuture;
124 | bool _isIndicatorAtTop;
125 | double _dragOffset;
126 | double get _DragOffset => _dragOffset;
127 | set _DragOffset(double value) {
128 | if (value != null) {
129 | value = math.min(value, widget.maxDragOffset ?? double.maxFinite);
130 | }
131 | if (_dragOffset != value) {
132 | _dragOffset = value;
133 | _onInnerNoticed();
134 | }
135 | }
136 |
137 | static final Animatable _threeQuarterTween =
138 | Tween(begin: 0.0, end: 0.75);
139 | static final Animatable _kDragSizeFactorLimitTween =
140 | Tween(begin: 0.0, end: _kDragSizeFactorLimit);
141 | static final Animatable _oneToZeroTween =
142 | Tween(begin: 1.0, end: 0.0);
143 |
144 | @override
145 | void initState() {
146 | super.initState();
147 | _positionController = AnimationController(vsync: this);
148 |
149 | _value = _positionController.drive(
150 | _threeQuarterTween); // The "value" of the circular progress indicator during a drag.
151 |
152 | _scaleController = AnimationController(vsync: this);
153 | _scaleFactor = _scaleController.drive(_oneToZeroTween);
154 |
155 | _pullBackController = AnimationController(vsync: this);
156 | }
157 |
158 | @override
159 | void didChangeDependencies() {
160 | final ThemeData theme = Theme.of(context);
161 | _valueColor = _positionController.drive(
162 | ColorTween(
163 | begin: (widget.color ?? theme.accentColor).withOpacity(0.0),
164 | end: (widget.color ?? theme.accentColor).withOpacity(1.0))
165 | .chain(CurveTween(
166 | curve: const Interval(0.0, 1.0 / _kDragSizeFactorLimit))),
167 | );
168 | super.didChangeDependencies();
169 | }
170 |
171 | @override
172 | void dispose() {
173 | _positionController.dispose();
174 | _scaleController.dispose();
175 | _pullBackController.dispose();
176 | _onNoticed.close();
177 | super.dispose();
178 | }
179 |
180 | double maxContainerExtent = 0.0;
181 | bool _handleScrollNotification(ScrollNotification notification) {
182 | var reuslt = _innerhandleScrollNotification(notification);
183 | //_onInnerNoticed();
184 | return reuslt;
185 | }
186 |
187 | bool _innerhandleScrollNotification(ScrollNotification notification) {
188 | if (!widget.notificationPredicate(notification)) return false;
189 | maxContainerExtent = math.max(
190 | notification.metrics.viewportDimension, this.maxContainerExtent);
191 | if (notification is ScrollStartNotification &&
192 | notification.metrics.extentBefore == 0.0 &&
193 | _Mode == null &&
194 | _start(notification.metrics.axisDirection)) {
195 | //setState(() {
196 | _mode = RefreshIndicatorMode.drag;
197 | //});
198 | return false;
199 | }
200 | bool indicatorAtTopNow;
201 | switch (notification.metrics.axisDirection) {
202 | case AxisDirection.down:
203 | indicatorAtTopNow = true;
204 | break;
205 | case AxisDirection.up:
206 | indicatorAtTopNow = false;
207 | break;
208 | case AxisDirection.left:
209 | case AxisDirection.right:
210 | indicatorAtTopNow = null;
211 | break;
212 | }
213 | if (indicatorAtTopNow != _isIndicatorAtTop) {
214 | if (_Mode == RefreshIndicatorMode.drag ||
215 | _Mode == RefreshIndicatorMode.armed)
216 | _dismiss(RefreshIndicatorMode.canceled);
217 | } else if (notification is ScrollUpdateNotification) {
218 | if (_Mode == RefreshIndicatorMode.drag ||
219 | _Mode == RefreshIndicatorMode.armed) {
220 | if (notification.metrics.extentBefore > 0.0) {
221 | _dismiss(RefreshIndicatorMode.canceled);
222 | } else {
223 | _DragOffset -= notification.scrollDelta;
224 | _checkDragOffset(maxContainerExtent);
225 | }
226 | }
227 | if (_Mode == RefreshIndicatorMode.armed &&
228 | notification.dragDetails == null) {
229 | // On iOS start the refresh when the Scrollable bounces back from the
230 | // overscroll (ScrollNotification indicating this don't have dragDetails
231 | // because the scroll activity is not directly triggered by a drag).
232 | _show();
233 | }
234 | } else if (notification is OverscrollNotification) {
235 | if (_Mode == RefreshIndicatorMode.drag ||
236 | _Mode == RefreshIndicatorMode.armed) {
237 | _DragOffset -= notification.overscroll / 2.0;
238 | _checkDragOffset(maxContainerExtent);
239 | }
240 | } else if (notification is ScrollEndNotification) {
241 | switch (_Mode) {
242 | case RefreshIndicatorMode.armed:
243 | _show();
244 | break;
245 | case RefreshIndicatorMode.drag:
246 | _dismiss(RefreshIndicatorMode.canceled);
247 | break;
248 | default:
249 | // do nothing
250 | break;
251 | }
252 | }
253 | //_onInnerNoticed();
254 | return false;
255 | }
256 |
257 | bool _handleGlowNotification(OverscrollIndicatorNotification notification) {
258 | if (notification.depth != 0 || !notification.leading) return false;
259 | if (_Mode == RefreshIndicatorMode.drag) {
260 | notification.disallowGlow();
261 | return true;
262 | }
263 | return false;
264 | }
265 |
266 | bool _start(AxisDirection direction) {
267 | assert(_Mode == null);
268 | assert(_isIndicatorAtTop == null);
269 | assert(_DragOffset == null);
270 | switch (direction) {
271 | case AxisDirection.down:
272 | _isIndicatorAtTop = true;
273 | break;
274 | case AxisDirection.up:
275 | _isIndicatorAtTop = false;
276 | break;
277 | case AxisDirection.left:
278 | case AxisDirection.right:
279 | _isIndicatorAtTop = null;
280 | // we do not support horizontal scroll views.
281 | return false;
282 | }
283 | _dragOffset = 0.0;
284 | _scaleController.value = 0.0;
285 | _positionController.value = 0.0;
286 | _pullBackFactor?.removeListener(pullBackListener);
287 | _pullBackController.reset();
288 | return true;
289 | }
290 |
291 | void _checkDragOffset(double containerExtent) {
292 | assert(_Mode == RefreshIndicatorMode.drag ||
293 | _Mode == RefreshIndicatorMode.armed);
294 | double newValue =
295 | _DragOffset / (containerExtent * _kDragContainerExtentPercentage);
296 | if (_Mode == RefreshIndicatorMode.armed)
297 | newValue = math.max(newValue, 1.0 / _kDragSizeFactorLimit);
298 | _positionController.value =
299 | newValue.clamp(0.0, 1.0); // this triggers various rebuilds
300 |
301 | if (_Mode == RefreshIndicatorMode.drag && _valueColor.value.alpha == 0xFF)
302 | _Mode = RefreshIndicatorMode.armed;
303 | }
304 |
305 | // Stop showing the refresh indicator.
306 | Future _dismiss(RefreshIndicatorMode newMode) async {
307 | await Future.value();
308 | // This can only be called from _show() when refreshing and
309 | // _handleScrollNotification in response to a ScrollEndNotification or
310 | // direction change.
311 | assert(newMode == RefreshIndicatorMode.canceled ||
312 | newMode == RefreshIndicatorMode.done);
313 | //setState(() {
314 | _Mode = newMode;
315 | //});
316 | switch (_Mode) {
317 | case RefreshIndicatorMode.done:
318 | await _scaleController.animateTo(1.0,
319 | duration: _kIndicatorScaleDuration);
320 | break;
321 | case RefreshIndicatorMode.canceled:
322 | await _positionController.animateTo(0.0,
323 | duration: _kIndicatorScaleDuration);
324 | break;
325 | default:
326 | assert(false);
327 | }
328 | if (mounted && _Mode == newMode) {
329 | _DragOffset = null;
330 | _isIndicatorAtTop = null;
331 | //setState(() {
332 | _Mode = null;
333 | // });
334 | }
335 | //_onInnerNoticed();
336 | }
337 |
338 | void _show() {
339 | assert(_Mode != RefreshIndicatorMode.refresh);
340 | assert(_Mode != RefreshIndicatorMode.snap);
341 | final Completer completer = Completer();
342 | _pendingRefreshFuture = completer.future;
343 | _Mode = RefreshIndicatorMode.snap;
344 | _positionController
345 | .animateTo(1.0 / _kDragSizeFactorLimit,
346 | duration: _kIndicatorSnapDuration)
347 | .then((void value) {
348 | if (mounted && _Mode == RefreshIndicatorMode.snap) {
349 | assert(widget.onRefresh != null);
350 | // setState(() {
351 | // Show the indeterminate progress indicator.
352 | _Mode = RefreshIndicatorMode.refresh;
353 | //});
354 |
355 | final Future refreshResult = widget.onRefresh();
356 | assert(() {
357 | if (refreshResult == null)
358 | FlutterError.reportError(FlutterErrorDetails(
359 | exception: FlutterError('The onRefresh callback returned null.\n'
360 | 'The RefreshIndicator onRefresh callback must return a Future.'),
361 | context: 'when calling onRefresh',
362 | library: 'material library',
363 | ));
364 | return true;
365 | }());
366 | if (refreshResult == null) return;
367 | refreshResult.then((bool success) {
368 | if (mounted && _Mode == RefreshIndicatorMode.refresh) {
369 | completer.complete();
370 | if (success) {
371 | _dismiss(RefreshIndicatorMode.done);
372 | } else
373 | _Mode = RefreshIndicatorMode.error;
374 | ;
375 | }
376 | });
377 | }
378 | });
379 | }
380 |
381 | /// Show the refresh indicator and run the refresh callback as if it had
382 | /// been started interactively. If this method is called while the refresh
383 | /// callback is running, it quietly does nothing.
384 | ///
385 | /// Creating the [PullToRefreshNotification] with a [GlobalKey]
386 | /// makes it possible to refer to the [PullToRefreshNotificationState].
387 | ///
388 | /// The future returned from this method completes when the
389 | /// [PullToRefreshNotification.onRefresh] callback's future completes.
390 | ///
391 | /// If you await the future returned by this function from a [State], you
392 | /// should check that the state is still [mounted] before calling [setState].
393 | ///
394 | /// When initiated in this manner, the refresh indicator is independent of any
395 | /// actual scroll view. It defaults to showing the indicator at the top. To
396 | /// show it at the bottom, set `atTop` to false.
397 | Future show({bool atTop = true}) {
398 | if (_Mode != RefreshIndicatorMode.refresh &&
399 | _Mode != RefreshIndicatorMode.snap) {
400 | if (_Mode == null) _start(atTop ? AxisDirection.down : AxisDirection.up);
401 | _show();
402 | }
403 | return _pendingRefreshFuture;
404 | }
405 |
406 | final GlobalKey _key = GlobalKey();
407 |
408 | @override
409 | Widget build(BuildContext context) {
410 | final Widget child = NotificationListener(
411 | key: _key,
412 | onNotification: _handleScrollNotification,
413 | child: NotificationListener(
414 | onNotification: _handleGlowNotification,
415 | child: widget.child,
416 | ),
417 | );
418 | // if (_Mode == null) {
419 | // assert(_DragOffset == null);
420 | // assert(_isIndicatorAtTop == null);
421 | // return child;
422 | // }
423 | // assert(_DragOffset != null);
424 | // assert(_isIndicatorAtTop != null);
425 | //
426 | // final bool showIndeterminateIndicator =
427 | // _Mode == RefreshIndicatorMode.refresh ||
428 | // _Mode == RefreshIndicatorMode.done;
429 | return child;
430 | //print(_value.value);
431 | // return Stack(
432 | // children: [
433 | // child,
434 | // Positioned(
435 | // top: _isIndicatorAtTop ? 0.0 : null,
436 | // bottom: !_isIndicatorAtTop ? 0.0 : null,
437 | // left: 0.0,
438 | // right: 0.0,
439 | // child: SizeTransition(
440 | // axisAlignment: _isIndicatorAtTop ? 1.0 : -1.0,
441 | // sizeFactor: _positionFactor, // this is what brings it down
442 | // child: Container(
443 | // padding: _isIndicatorAtTop
444 | // ? EdgeInsets.only(top: widget.displacement)
445 | // : EdgeInsets.only(bottom: widget.displacement),
446 | // alignment: _isIndicatorAtTop
447 | // ? Alignment.topCenter
448 | // : Alignment.bottomCenter,
449 | // child: ScaleTransition(
450 | // scale: _scaleFactor,
451 | // child: AnimatedBuilder(
452 | // animation: _positionController,
453 | // builder: (BuildContext context, Widget child) {
454 | // return RefreshProgressIndicator(
455 | // value: showIndeterminateIndicator ? null : _value.value,
456 | // valueColor: _valueColor,
457 | // backgroundColor: widget.backgroundColor,
458 | // );
459 | // },
460 | // ),
461 | // ),
462 | // ),
463 | // ),
464 | // ),
465 | // ],
466 | // );
467 | }
468 |
469 | void _onInnerNoticed() {
470 | if ((_dragOffset != null && _dragOffset > 0.0) &&
471 | ((_Mode == RefreshIndicatorMode.done && !widget.pullBackOnRefresh) ||
472 | (_Mode == RefreshIndicatorMode.refresh &&
473 | widget.pullBackOnRefresh) ||
474 | _Mode == RefreshIndicatorMode.canceled)) {
475 | _pullBack();
476 | return;
477 | }
478 |
479 | if (_pullBackController.isAnimating) {
480 | pullBackListener();
481 | } else {
482 | _onNoticed.add(PullToRefreshScrollNotificationInfo(
483 | _Mode, _DragOffset, _getRefreshWidget(), this));
484 | }
485 | }
486 |
487 | Widget _getRefreshWidget() {
488 | if (_Mode == null) return null;
489 | final bool showIndeterminateIndicator =
490 | _Mode == RefreshIndicatorMode.refresh ||
491 | _Mode == RefreshIndicatorMode.done;
492 | return ScaleTransition(
493 | scale: _scaleFactor,
494 | child: AnimatedBuilder(
495 | animation: _positionController,
496 | builder: (BuildContext context, Widget child) {
497 | if (Platform.isIOS) {
498 | return CupertinoActivityIndicator(
499 | animating: showIndeterminateIndicator,
500 | radius: 10.0,
501 | );
502 | } else {
503 | return RefreshProgressIndicator(
504 | value: showIndeterminateIndicator ? null : _value.value,
505 | valueColor: _valueColor,
506 | strokeWidth: 2.0,
507 | );
508 | }
509 | },
510 | ),
511 | );
512 | }
513 |
514 | void pullBackListener() {
515 | //print(_pullBackFactor.value);
516 | if (_dragOffset != _pullBackFactor.value) {
517 | _dragOffset = _pullBackFactor.value;
518 | _onNoticed.add(PullToRefreshScrollNotificationInfo(
519 | _Mode, _dragOffset, _getRefreshWidget(), this));
520 | if (_dragOffset == 0.0) {
521 | _dragOffset = null;
522 | }
523 | }
524 | }
525 |
526 | void _pullBack() {
527 | final Animatable _pullBackTween =
528 | Tween(begin: _DragOffset ?? 0.0, end: 0.0);
529 | _pullBackFactor?.removeListener(pullBackListener);
530 | _pullBackController.reset();
531 | _pullBackFactor = _pullBackController.drive(_pullBackTween);
532 | _pullBackFactor.addListener(pullBackListener);
533 | _pullBackController.animateTo(1.0,
534 | duration: Duration(milliseconds: 400), curve: Curves.linear);
535 | //_DragOffset=0.0;
536 | }
537 | }
538 |
539 | //return true so that we can handle inner scroll notification
540 | bool defaultNotificationPredicate(ScrollNotification notification) {
541 | return true;
542 | return notification.depth == 0;
543 | }
544 |
545 | class PullToRefreshScrollNotificationInfo {
546 | final RefreshIndicatorMode mode;
547 | final double dragOffset;
548 | final Widget refreshWiget;
549 | final PullToRefreshNotificationState pullToRefreshNotificationState;
550 | PullToRefreshScrollNotificationInfo(this.mode, this.dragOffset,
551 | this.refreshWiget, this.pullToRefreshNotificationState);
552 | }
553 |
554 | class PullToRefreshContainer extends StatefulWidget {
555 | final PullToRefreshContainerBuilder builder;
556 | PullToRefreshContainer(this.builder);
557 | @override
558 | _PullToRefreshContainerState createState() => _PullToRefreshContainerState();
559 | }
560 |
561 | class _PullToRefreshContainerState extends State {
562 | @override
563 | Widget build(BuildContext context) {
564 | PullToRefreshNotificationState ss = context
565 | .ancestorStateOfType(TypeMatcher());
566 | return StreamBuilder(
567 | builder: (c, s) {
568 | return widget.builder(s.data);
569 | },
570 | stream: ss?.onNoticed,
571 | );
572 | }
573 | }
574 |
575 | typedef PullToRefreshContainerBuilder = Widget Function(
576 | PullToRefreshScrollNotificationInfo info);
577 |
578 | class RefreshProgressIndicator extends CircularProgressIndicator {
579 | /// Creates a refresh progress indicator.
580 | ///
581 | /// Rather than creating a refresh progress indicator directly, consider using
582 | /// a [RefreshIndicator] together with a [Scrollable] widget.
583 | const RefreshProgressIndicator({
584 | Key key,
585 | double value,
586 | Color backgroundColor,
587 | Animation valueColor,
588 | double strokeWidth =
589 | 2.0, // Different default than CircularProgressIndicator.
590 | }) : super(
591 | key: key,
592 | value: value,
593 | backgroundColor: backgroundColor,
594 | valueColor: valueColor,
595 | strokeWidth: strokeWidth,
596 | );
597 |
598 | @override
599 | _RefreshProgressIndicatorState createState() =>
600 | _RefreshProgressIndicatorState();
601 | }
602 |
603 | class _RefreshProgressIndicatorState extends _CircularProgressIndicatorState {
604 | static const double _indicatorSize = 18.0;
605 |
606 | // Always show the indeterminate version of the circular progress indicator.
607 | // When value is non-null the sweep of the progress indicator arrow's arc
608 | // varies from 0 to about 270 degrees. When value is null the arrow animates
609 | // starting from wherever we left it.
610 | @override
611 | Widget build(BuildContext context) {
612 | if (widget.value != null)
613 | _controller.value = widget.value / 10.0;
614 | else if (!_controller.isAnimating) _controller.repeat();
615 | return _buildAnimation();
616 | }
617 |
618 | @override
619 | Widget _buildIndicator(BuildContext context, double headValue,
620 | double tailValue, int stepValue, double rotationValue) {
621 | final double arrowheadScale =
622 | widget.value == null ? 0.0 : (widget.value * 2.0).clamp(0.0, 1.0);
623 | return Container(
624 | alignment: Alignment.center,
625 | child: Container(
626 | width: _indicatorSize,
627 | height: _indicatorSize,
628 | //color: Colors.red,
629 | child: CustomPaint(
630 | painter: _RefreshProgressIndicatorPainter(
631 | valueColor: widget._getValueColor(context),
632 | value: null, // Draw the indeterminate progress indicator.
633 | headValue: headValue,
634 | tailValue: tailValue,
635 | stepValue: stepValue,
636 | rotationValue: rotationValue,
637 | strokeWidth: widget.strokeWidth,
638 | arrowheadScale: arrowheadScale,
639 | ),
640 | ),
641 | ),
642 | );
643 | }
644 | }
645 |
646 | const double _kLinearProgressIndicatorHeight = 6.0;
647 | const double _kMinCircularProgressIndicatorSize = 36.0;
648 | const int _kIndeterminateLinearDuration = 1800;
649 |
650 | final Animatable _kStrokeHeadTween = CurveTween(
651 | curve: const Interval(0.0, 0.5, curve: Curves.fastOutSlowIn),
652 | ).chain(CurveTween(
653 | curve: const SawTooth(5),
654 | ));
655 |
656 | final Animatable _kStrokeTailTween = CurveTween(
657 | curve: const Interval(0.5, 1.0, curve: Curves.fastOutSlowIn),
658 | ).chain(CurveTween(
659 | curve: const SawTooth(5),
660 | ));
661 |
662 | final Animatable _kStepTween = StepTween(begin: 0, end: 5);
663 |
664 | final Animatable _kRotationTween = CurveTween(curve: const SawTooth(5));
665 |
666 | class CircularProgressIndicator extends ProgressIndicator {
667 | /// Creates a circular progress indicator.
668 | ///
669 | /// The [value] argument can be either null (corresponding to an indeterminate
670 | /// progress indicator) or non-null (corresponding to a determinate progress
671 | /// indicator). See [value] for details.
672 | const CircularProgressIndicator({
673 | Key key,
674 | double value,
675 | Color backgroundColor,
676 | Animation valueColor,
677 | this.strokeWidth = 4.0,
678 | }) : super(
679 | key: key,
680 | value: value,
681 | backgroundColor: backgroundColor,
682 | valueColor: valueColor);
683 |
684 | /// The width of the line used to draw the circle.
685 | final double strokeWidth;
686 |
687 | @override
688 | _CircularProgressIndicatorState createState() =>
689 | _CircularProgressIndicatorState();
690 | }
691 |
692 | class _CircularProgressIndicatorState extends State
693 | with SingleTickerProviderStateMixin {
694 | AnimationController _controller;
695 |
696 | @override
697 | void initState() {
698 | super.initState();
699 | _controller = AnimationController(
700 | duration: const Duration(seconds: 5),
701 | vsync: this,
702 | );
703 | if (widget.value == null) _controller.repeat();
704 | }
705 |
706 | @override
707 | void didUpdateWidget(CircularProgressIndicator oldWidget) {
708 | super.didUpdateWidget(oldWidget);
709 | if (widget.value == null && !_controller.isAnimating)
710 | _controller.repeat();
711 | else if (widget.value != null && _controller.isAnimating)
712 | _controller.stop();
713 | }
714 |
715 | @override
716 | void dispose() {
717 | _controller.dispose();
718 | super.dispose();
719 | }
720 |
721 | Widget _buildIndicator(BuildContext context, double headValue,
722 | double tailValue, int stepValue, double rotationValue) {
723 | return Container(
724 | constraints: const BoxConstraints(
725 | minWidth: _kMinCircularProgressIndicatorSize,
726 | minHeight: _kMinCircularProgressIndicatorSize,
727 | ),
728 | child: CustomPaint(
729 | painter: _CircularProgressIndicatorPainter(
730 | valueColor: widget._getValueColor(context),
731 | value: widget.value, // may be null
732 | headValue:
733 | headValue, // remaining arguments are ignored if widget.value is not null
734 | tailValue: tailValue,
735 | stepValue: stepValue,
736 | rotationValue: rotationValue,
737 | strokeWidth: widget.strokeWidth,
738 | ),
739 | ),
740 | );
741 | }
742 |
743 | Widget _buildAnimation() {
744 | return AnimatedBuilder(
745 | animation: _controller,
746 | builder: (BuildContext context, Widget child) {
747 | return _buildIndicator(
748 | context,
749 | _kStrokeHeadTween.evaluate(_controller),
750 | _kStrokeTailTween.evaluate(_controller),
751 | _kStepTween.evaluate(_controller),
752 | _kRotationTween.evaluate(_controller),
753 | );
754 | },
755 | );
756 | }
757 |
758 | @override
759 | Widget build(BuildContext context) {
760 | if (widget.value != null) return _buildIndicator(context, 0.0, 0.0, 0, 0.0);
761 | return _buildAnimation();
762 | }
763 | }
764 |
765 | class _RefreshProgressIndicatorPainter
766 | extends _CircularProgressIndicatorPainter {
767 | _RefreshProgressIndicatorPainter({
768 | Color valueColor,
769 | double value,
770 | double headValue,
771 | double tailValue,
772 | int stepValue,
773 | double rotationValue,
774 | double strokeWidth,
775 | this.arrowheadScale,
776 | }) : super(
777 | valueColor: valueColor,
778 | value: value,
779 | headValue: headValue,
780 | tailValue: tailValue,
781 | stepValue: stepValue,
782 | rotationValue: rotationValue,
783 | strokeWidth: strokeWidth,
784 | );
785 |
786 | final double arrowheadScale;
787 |
788 | void paintArrowhead(Canvas canvas, Size size) {
789 | // ux, uy: a unit vector whose direction parallels the base of the arrowhead.
790 | // (So ux, -uy points in the direction the arrowhead points.)
791 | final double arcEnd = arcStart + arcSweep;
792 | final double ux = math.cos(arcEnd);
793 | final double uy = math.sin(arcEnd);
794 |
795 | assert(size.width == size.height);
796 | final double radius = size.width / 2.0;
797 | final double arrowheadPointX =
798 | radius + ux * radius + -uy * strokeWidth * 2.0 * arrowheadScale;
799 | final double arrowheadPointY =
800 | radius + uy * radius + ux * strokeWidth * 2.0 * arrowheadScale;
801 | final double arrowheadRadius = strokeWidth * 1.5 * arrowheadScale;
802 | final double innerRadius = radius - arrowheadRadius;
803 | final double outerRadius = radius + arrowheadRadius;
804 |
805 | final Path path = Path()
806 | ..moveTo(radius + ux * innerRadius, radius + uy * innerRadius)
807 | ..lineTo(radius + ux * outerRadius, radius + uy * outerRadius)
808 | ..lineTo(arrowheadPointX, arrowheadPointY)
809 | ..close();
810 | final Paint paint = Paint()
811 | ..color = valueColor
812 | ..strokeWidth = strokeWidth
813 | ..style = PaintingStyle.fill;
814 | canvas.drawPath(path, paint);
815 | }
816 |
817 | @override
818 | void paint(Canvas canvas, Size size) {
819 | super.paint(canvas, size);
820 | if (arrowheadScale > 0.0) paintArrowhead(canvas, size);
821 | }
822 | }
823 |
824 | class _CircularProgressIndicatorPainter extends CustomPainter {
825 | _CircularProgressIndicatorPainter({
826 | this.valueColor,
827 | this.value,
828 | this.headValue,
829 | this.tailValue,
830 | this.stepValue,
831 | this.rotationValue,
832 | this.strokeWidth,
833 | }) : arcStart = value != null
834 | ? _startAngle
835 | : _startAngle +
836 | tailValue * 3 / 2 * math.pi +
837 | rotationValue * math.pi * 1.7 -
838 | stepValue * 0.8 * math.pi,
839 | arcSweep = value != null
840 | ? value.clamp(0.0, 1.0) * _sweep
841 | : math.max(
842 | headValue * 3 / 2 * math.pi - tailValue * 3 / 2 * math.pi,
843 | _epsilon);
844 |
845 | final Color valueColor;
846 | final double value;
847 | final double headValue;
848 | final double tailValue;
849 | final int stepValue;
850 | final double rotationValue;
851 | final double strokeWidth;
852 | final double arcStart;
853 | final double arcSweep;
854 |
855 | static const double _twoPi = math.pi * 2.0;
856 | static const double _epsilon = .001;
857 | // Canvas.drawArc(r, 0, 2*PI) doesn't draw anything, so just get close.
858 | static const double _sweep = _twoPi - _epsilon;
859 | static const double _startAngle = -math.pi / 2.0;
860 |
861 | @override
862 | void paint(Canvas canvas, Size size) {
863 | final Paint paint = Paint()
864 | ..color = valueColor
865 | ..strokeWidth = strokeWidth
866 | ..style = PaintingStyle.stroke;
867 |
868 | if (value == null) // Indeterminate
869 | paint.strokeCap = StrokeCap.square;
870 |
871 | canvas.drawArc(Offset.zero & size, arcStart, arcSweep, false, paint);
872 | }
873 |
874 | @override
875 | bool shouldRepaint(_CircularProgressIndicatorPainter oldPainter) {
876 | return oldPainter.valueColor != valueColor ||
877 | oldPainter.value != value ||
878 | oldPainter.headValue != headValue ||
879 | oldPainter.tailValue != tailValue ||
880 | oldPainter.stepValue != stepValue ||
881 | oldPainter.rotationValue != rotationValue ||
882 | oldPainter.strokeWidth != strokeWidth;
883 | }
884 | }
885 |
886 | abstract class ProgressIndicator extends StatefulWidget {
887 | /// Creates a progress indicator.
888 | ///
889 | /// The [value] argument can be either null (corresponding to an indeterminate
890 | /// progress indicator) or non-null (corresponding to a determinate progress
891 | /// indicator). See [value] for details.
892 | const ProgressIndicator({
893 | Key key,
894 | this.value,
895 | this.backgroundColor,
896 | this.valueColor,
897 | }) : super(key: key);
898 |
899 | /// If non-null, the value of this progress indicator with 0.0 corresponding
900 | /// to no progress having been made and 1.0 corresponding to all the progress
901 | /// having been made.
902 | ///
903 | /// If null, this progress indicator is indeterminate, which means the
904 | /// indicator displays a predetermined animation that does not indicator how
905 | /// much actual progress is being made.
906 | final double value;
907 |
908 | /// The progress indicator's background color. The current theme's
909 | /// [ThemeData.backgroundColor] by default.
910 | final Color backgroundColor;
911 |
912 | /// The indicator's color is the animation's value. To specify a constant
913 | /// color use: `new AlwaysStoppedAnimation(color)`.
914 | ///
915 | /// If null, the progress indicator is rendered with the current theme's
916 | /// [ThemeData.accentColor].
917 | final Animation valueColor;
918 |
919 | Color _getBackgroundColor(BuildContext context) =>
920 | backgroundColor ?? Theme.of(context).backgroundColor;
921 | Color _getValueColor(BuildContext context) =>
922 | valueColor?.value ?? Theme.of(context).accentColor;
923 |
924 | @override
925 | void debugFillProperties(DiagnosticPropertiesBuilder properties) {
926 | super.debugFillProperties(properties);
927 | properties.add(PercentProperty('value', value,
928 | showName: false, ifNull: ''));
929 | }
930 | }
--------------------------------------------------------------------------------
/lib/constant.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | class Constant{
3 | static const String apiUrl = 'http://api.maccms.bteee.com/api.php/';
4 | static SlideTransition createTransition(
5 | Animation animation, Widget child) {
6 | return new SlideTransition(
7 | position: new Tween(
8 | begin: const Offset(1.0, 0.0),
9 | end: const Offset(0.0, 0.0),
10 | ).animate(animation),
11 | child: child,
12 | );
13 | }
14 | static const version = '0.0.1.1';
15 | static const logoImg = 'images/index_discovery_logo2.png';
16 | static const name = '萌新影视';
17 | }
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:maccms_app/pages/App.dart';
3 | import 'package:maccms_app/pages/StartPage.dart';
4 | import 'package:flutter/foundation.dart';
5 | import 'package:flutter/services.dart';
6 | import 'package:maccms_app/constant.dart';
7 |
8 | void main() {
9 |
10 | TargetPlatform platform = defaultTargetPlatform;
11 | if (platform != TargetPlatform.iOS)
12 | {
13 | SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.dark);
14 | SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
15 | //SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
16 | }
17 | SystemChrome.setPreferredOrientations([
18 | DeviceOrientation.portraitUp,
19 | DeviceOrientation.portraitDown
20 | ]);
21 |
22 | runApp( new MaterialApp(
23 | title:Constant.name,
24 | theme: new ThemeData(
25 | primarySwatch: Colors.orange
26 | ),
27 | home:new StartPage(),
28 | routes:{
29 | '/App':(BuildContext context)=>App(),
30 | },
31 | )
32 | );
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/lib/pages/About.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:maccms_app/constant.dart';
3 |
4 | class About extends StatefulWidget {
5 | About({Key key}) : super(key: key);
6 | @override
7 | _About createState() => _About();
8 | }
9 |
10 | class _About extends State {
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | centerTitle: true,
16 | backgroundColor: Colors.white,
17 | elevation: 1.0,
18 | leading: GestureDetector(
19 | child: Icon(Icons.chevron_left,color:Colors.black,size:25),
20 | onTap: (){
21 | Navigator.pop(context);
22 | },
23 | ),
24 | title: Text("关于",style: TextStyle(fontSize: 18,color: Colors.black),)
25 | ),
26 | body: Container(
27 | color: Colors.white,
28 | alignment: Alignment.center,
29 | width: MediaQuery.of(context).size.width,
30 | height: double.infinity,
31 | child: Column(
32 | mainAxisAlignment: MainAxisAlignment.start,
33 | crossAxisAlignment: CrossAxisAlignment.center,
34 | children: [
35 | Container(
36 | margin: EdgeInsets.only(top: 70,bottom: 18),
37 | child: Image.asset(Constant.logoImg,fit: BoxFit.fill,width: 130,height: 35,),
38 | ),
39 | Container(
40 | margin: EdgeInsets.only(bottom: 18),
41 | child: Text('您 的 私 人 影 视 大 院',style:TextStyle(fontSize:15,color:Color.fromARGB(255, 132, 132, 132))),
42 | ),
43 | Container(
44 | padding: EdgeInsets.fromLTRB(13, 5, 13, 5),
45 | decoration: BoxDecoration(
46 | border: Border.all(width: 1.0,color: Color.fromARGB(255, 132, 132, 132)),
47 | borderRadius: BorderRadius.circular(18)
48 | ),
49 | child: Text('V'+Constant.version,style:TextStyle(fontSize:15,color:Color.fromARGB(255, 132, 132, 132))),
50 | )
51 | ],
52 | ),
53 | ),
54 | );
55 | }
56 | }
--------------------------------------------------------------------------------
/lib/pages/App.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:maccms_app/pages/Home.dart';
3 | import 'package:maccms_app/pages/Cate.dart';
4 | import 'package:maccms_app/pages/My.dart';
5 | import 'package:maccms_app/MyWidGet/Base_Font.dart';
6 | import 'package:flutter_screenutil/flutter_screenutil.dart';
7 |
8 |
9 | //脚手架
10 | class App extends StatefulWidget{
11 | @override
12 | State createState() {
13 | return _AppState();
14 | }
15 | }
16 |
17 | class _AppState extends State{
18 | int _tabIndex = 0; //bottomNavigationBar选中的index
19 | var _pageController = new PageController(initialPage: 0);
20 | //1
21 | final Home _home = new Home();
22 | final Cate _cate = new Cate();
23 | final My _my = new My();
24 |
25 | List tabPush = [new Home(),new Cate(),new My()]; //bottomNavigationBar实例集合
26 | var tabTitles = ['首页','类别','我的']; //bottomNavigationBar标题集合
27 | @override
28 | //绘制页面
29 | Widget build(BuildContext context) {
30 | //初始化屏幕适配
31 | ScreenUtil.instance = ScreenUtil(width: 1080, height: 1920)..init(context);
32 | return Scaffold(
33 | backgroundColor: Color.fromARGB(255, 244, 244, 244),
34 | //appBar: appbars[_tabIndex],
35 | body: new PageView.builder(
36 | onPageChanged: (int index){setTapIndex(index);},
37 | controller: _pageController,
38 | physics: new NeverScrollableScrollPhysics(),
39 | itemCount: 3,
40 | itemBuilder: (BuildContext context,int index){
41 | return pageChooser(index);
42 | },
43 | ),
44 | bottomNavigationBar: BottomNavigationBar(
45 | items: [
46 | new BottomNavigationBarItem(icon: getTabImages(0),title: getTabTitle(0)),
47 | new BottomNavigationBarItem(icon: getTabImages(1),title: getTabTitle(1)),
48 | new BottomNavigationBarItem(icon: getTabImages(2),title: getTabTitle(2)),
49 | ],
50 | //设置显示的模式
51 | type: BottomNavigationBarType.fixed,
52 | //设置当前的索引
53 | currentIndex: _tabIndex,
54 | //tabBottom的点击监听
55 | onTap: (index) {
56 | setState(() {
57 | _pageController.jumpToPage(index);
58 | // _pageController.animateToPage(index, duration: Duration(milliseconds: 100),curve: ElasticOutCurve(2));
59 | setTapIndex(index);
60 | //_tabIndex = index;
61 | //Navigator.push(Widget.context, MaterialPageRoute(builder: (context) => tabPush[_tabIndex]));
62 | });
63 | },
64 | ),
65 | );
66 | }
67 | //appbar list
68 | final List appbars = [
69 | new AppBar( //首页搜索
70 | backgroundColor: Color.fromARGB(255, 255, 219, 79),
71 | primary: true,
72 | elevation: 0.0,
73 | title: new Container(
74 | decoration: new BoxDecoration(
75 | border: new Border.all(
76 | width: 1.0, color: Color.fromARGB(255, 226, 226, 226)),
77 | borderRadius: new BorderRadius.all(Radius.circular(5.0)),
78 | color: Color.fromARGB(255, 255, 255, 255)),
79 | alignment: Alignment.center,
80 | height: 30.0,
81 | child: new Row(
82 | children: [
83 | new Expanded(
84 | child: new Icon(Base.sousuo,
85 | size: 17.0, color: Color.fromARGB(255, 226, 226, 226)),
86 | flex: 1),
87 | new Expanded(
88 | child: new Text('热门',
89 | style: TextStyle(
90 | color: Color.fromARGB(255, 226, 226, 226),
91 | fontSize: 17.0)),
92 | flex: 9)
93 | ],
94 | ),
95 | ),
96 | ),
97 | new AppBar( //类别
98 | backgroundColor: Color.fromARGB(255, 255, 219, 79),
99 | primary: true,
100 | elevation: 0.0,
101 | title: new Center(child: Text('类别'))
102 | ),
103 | new AppBar(
104 | backgroundColor: Color.fromARGB(255, 255, 219, 79),
105 | primary: true,
106 | elevation: 0.0,
107 | )
108 | ];
109 |
110 | //设置状态
111 | void setTapIndex(int index){
112 | setState(() {
113 | this._tabIndex = index;
114 | });
115 | }
116 | //判断返回的对象实例
117 | Widget pageChooser(int index) {
118 | switch (index) {
119 | case 0:
120 | return _home;
121 |
122 |
123 | case 1:
124 | return _cate;
125 |
126 |
127 | case 2:
128 | return _my;
129 |
130 |
131 | default:
132 | return _home;
133 |
134 | }
135 | }
136 | //定义bottomNavigationBar ICON 图标
137 | var tabImages = [
138 | [
139 | 'icon_discovery.png',
140 | 'icon_discovery_active.png'
141 | ],
142 | [
143 | 'icon_category.png',
144 | 'icon_category_active.png'
145 | ],
146 | [
147 | 'icon_mine.png',
148 | 'icon_mine_active.png'
149 | ]
150 | ];
151 |
152 | Text getTabTitle(int curIndex){
153 | return new Text(tabTitles[curIndex],style: TextStyle(fontSize: 13,color: Colors.black),);
154 | }
155 |
156 | Widget getTabImages(int curIndex){
157 | if(_tabIndex==curIndex){
158 | return Image.asset(
159 | 'images/'+tabImages[curIndex][1],
160 | fit: BoxFit.fill,
161 | width: 24,
162 | height: 24,
163 | );
164 | }else{
165 | return Image.asset(
166 | 'images/'+tabImages[curIndex][0],
167 | fit: BoxFit.fill,
168 | width: 24,
169 | height: 24,
170 | );
171 | }
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/lib/pages/Cate.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:dio/dio.dart';
3 | import 'package:maccms_app/constant.dart';
4 | import 'package:maccms_app/pages/Detail.dart';
5 | import 'package:flutter_spinkit/flutter_spinkit.dart'; //loadding图标
6 | import 'package:lazy_load_scrollview/lazy_load_scrollview.dart';
7 |
8 |
9 | class Cate extends StatefulWidget {
10 | Cate({Key key}) : super(key: key);
11 | @override
12 | _CateState createState() => _CateState();
13 | }
14 |
15 | class _CateState extends State with AutomaticKeepAliveClientMixin {
16 | //Map data = {};
17 | int total; //total为数据总量
18 | List dataList = [];
19 | List classList = [];
20 | int prenetId = 0;
21 | int start = 0; //第几个开始
22 | int listCount = 0; //列表数
23 | int listState = 0; //列表状态 0=等待 1=加载 2=没有更多
24 | //{'parenet':'','type_class':'','type_area':'','type_year':'','by':'hits'};
25 | Map param = {0: '', 1: '不限', 2: '不限', 3: '不限', 4: '最新'};
26 | @override
27 | Widget build(BuildContext context) {
28 | super.build(context);
29 | return Scaffold(
30 | appBar: new AppBar( //类别
31 | backgroundColor: Color.fromARGB(255, 255, 219, 79),
32 | primary: true,
33 | elevation: 0.0,
34 | title: new Center(child: Text('类别'))
35 | ),
36 | body: getBody(),
37 | );
38 | }
39 | //加载菊花
40 | Widget getBody() {
41 | print(classList.length==0);
42 | if (classList.length!=0) {
43 | return LazyLoadScrollView(
44 | onEndOfPage: () {
45 | if (this.total == dataList.length && this.listState != 2) {
46 | setState(() {
47 | this.listState = 2; //设置状态为加载
48 | this.listCount += 1; //列表项+1
49 | });
50 | } else if (this.listState != 1 && this.listState != 2) {
51 | setState(() {
52 | this.listState = 1; //设置状态为加载
53 | this.listCount += 1; //列表项+1
54 | });
55 | loadMore(false);
56 | }
57 | print('listcount回调:' +
58 | this.total.toString() +
59 | 'datalist:' +
60 | dataList.length.toString());
61 | },
62 | scrollOffset: 500,
63 | child: ListView.builder(
64 | scrollDirection: Axis.vertical,
65 | itemCount: listCount,
66 | itemBuilder: (BuildContext context, int index) {
67 | return controller(index);
68 | },
69 | ),
70 | );
71 | } else {
72 | return SpinKitFadingCircle(
73 | itemBuilder: (_, int index) {
74 | return DecoratedBox(
75 | decoration: BoxDecoration(
76 | color: index.isEven ? Colors.yellow : Color.fromARGB(255, 255, 219, 79),
77 | ),
78 | );
79 | },
80 | );
81 | }
82 | }
83 |
84 | @override
85 | void initState() {
86 | super.initState();
87 | classGet();
88 | }
89 |
90 | void classGet() async {
91 | Dio dio = new Dio();
92 | Response data = await dio.get(Constant.apiUrl + 'app/classification');
93 | if (data.statusCode == 200) {
94 | setState(() {
95 | classList = data.data;
96 | listCount = classList.length + 2;
97 | //print(listCount);
98 | param[0] = classList[0]['id'];
99 | loadMore(true);
100 | });
101 | }
102 | }
103 |
104 |
105 | //加载更多
106 | void loadMore(bool isRefresh) async {
107 | if (isRefresh == true) {
108 | this.start = 0;
109 | listCount = classList.length + 2;
110 | } else {
111 | this.start += 21;
112 | }
113 | Dio dio = new Dio();
114 | Response data = await dio.get(Constant.apiUrl +
115 | 'app/list?tid=' +
116 | param[0] +
117 | '&class=' +
118 | param[1] +
119 | '&area=' +
120 | param[2] +
121 | '&year=' +
122 | param[3] +
123 | '&by=' +
124 | param[4] +
125 | '&start=' +
126 | start.toString());
127 | if (data.statusCode == 200) {
128 | if (isRefresh == true) {
129 | //如果isrefresh==true表示为刷新或者初始化 数据覆盖,否则则新增
130 | setState(() {
131 | //this.data = data.data;
132 | //print(this.data);
133 | this.listState = 0;
134 | total = data.data['total'];
135 | dataList = data.data['list'];
136 | listCount = classList.length + 2 + dataList.length;
137 | //print(dataList);
138 | });
139 | } else {
140 | setState(() {
141 | total = data.data['total'];
142 | if (data.data['list'] != null) {
143 | this.listCount -= 1;
144 | this.listState = 0;
145 | dataList.addAll(data.data['list']);
146 | listCount = classList.length + 2 + dataList.length;
147 | //this.listState = dataList.length==total?2:0;
148 | } else {
149 | this.listState = 2;
150 | }
151 |
152 | //print(dataList);
153 | });
154 | }
155 | }
156 | }
157 |
158 | //控制分类
159 | Widget controller(int index) {
160 | List arr;
161 | bool isBottom = false;
162 | if (index == 0) {
163 | //顶级分类
164 | arr = classList;
165 | return new Container(
166 | color: Color.fromARGB(255, 255, 255, 255),
167 | padding: EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 0.0),
168 | width: MediaQuery.of(context).size.width,
169 | height: 50.0,
170 | alignment: Alignment.center,
171 | child: new ListView.builder(
172 | scrollDirection: Axis.horizontal,
173 | itemCount: arr.length,
174 | itemBuilder: (context, int subindex) {
175 | return new GestureDetector(
176 | child: new Container(
177 | alignment: Alignment.center,
178 | padding: EdgeInsets.only(right: 20.0),
179 | child: new Text(arr[subindex]['type_name'],
180 | style: TextStyle(
181 | fontSize: 15.0,
182 | color: prenetId == subindex
183 | ? Color.fromARGB(255, 255, 219, 79)
184 | : Color.fromARGB(255, 0, 0, 0))),
185 | ),
186 | onTap: () {
187 | setState(() {
188 | param[0] = arr[subindex]['id'];
189 | prenetId = subindex;
190 | param[1] = '不限';
191 | param[2] = '不限';
192 | param[3] = '不限'; //每次点击顶级分类初始化子分类
193 | print(param);
194 | loadMore(true); //更新列表
195 | });
196 | },
197 | );
198 | }));
199 | } else if (index <= 4) {
200 | var paramId;
201 | switch (index) {
202 | case 1:
203 | paramId = 1;
204 | arr = classList[prenetId]['type_class'];
205 | break;
206 | case 2:
207 | paramId = 2;
208 | arr = classList[prenetId]['type_area'];
209 | break;
210 | case 3:
211 | paramId = 3;
212 | arr = classList[prenetId]['type_year'];
213 | break;
214 | case 4:
215 | paramId = 4;
216 | arr = ['最新', '最热'];
217 | isBottom = true;
218 | break;
219 | }
220 | return classScroll(paramId, arr, isBottom);
221 | } else {
222 | if (index == 5) {
223 | return new Container(
224 | width: MediaQuery.of(context).size.width,
225 | height: 15.0,
226 | );
227 | }
228 | //print('index:'+index.toString()+'listcount:'+listCount.toString());
229 | if (index == listCount - 1 && listState == 2) {
230 | return new Container(
231 | width: MediaQuery.of(context).size.width,
232 | color: Color.fromARGB(255, 255, 255, 255),
233 | height: 30.0,
234 | child: Center(
235 | child: Text('我也是有底线的-.-',
236 | style: TextStyle(fontSize: 15.0, color: Colors.grey)),
237 | ),
238 | );
239 | } else if (index == listCount - 1 && listState == 1) {
240 | return new Container(
241 | color: Color.fromARGB(255, 255, 255, 255),
242 | width: MediaQuery.of(context).size.width,
243 | height: 30.0,
244 | child: Row(
245 | mainAxisAlignment: MainAxisAlignment.center,
246 | crossAxisAlignment: CrossAxisAlignment.center,
247 | children: [
248 | SpinKitFadingCircle(
249 | size: 15.0,
250 | itemBuilder: (_, int index) {
251 | return DecoratedBox(
252 | decoration: BoxDecoration(
253 | color: index.isEven ? Colors.red : Colors.green,
254 | ),
255 | );
256 | },
257 | ),
258 | new Text('不要急嘛!等一下咯 -.-',
259 | style: TextStyle(fontSize: 15.0, color: Colors.grey))
260 | ],
261 | ),
262 | );
263 | }else{
264 | print(index);
265 | return item(dataList[index - 6]);
266 | }
267 | }
268 | }
269 |
270 | //顶级分类Scroll arr传入分类组,
271 | Widget classScroll(int paramId, List arr, bool isBottomView) {
272 | double itemContainerBottomPadding =
273 | isBottomView ? 10.0 : 0.0; //最后一个scroll加一个底部边距
274 | double itemContainerHeight = isBottomView ? 50.0 : 40.0; //最后一个高度加一个10.0
275 | Widget itemScroll = new Container(
276 | color: Color.fromARGB(255, 255, 255, 255),
277 | padding:
278 | EdgeInsets.fromLTRB(10.0, 10.0, 10.0, itemContainerBottomPadding),
279 | width: MediaQuery.of(context).size.width,
280 | alignment: Alignment.center,
281 | height: itemContainerHeight,
282 | child: new ListView.builder(
283 | scrollDirection: Axis.horizontal,
284 | itemCount: arr.length,
285 | itemBuilder: (context, int subindex) {
286 | return classButton(paramId, arr[subindex]);
287 | },
288 | ),
289 | );
290 | return itemScroll;
291 | }
292 |
293 | //分类的按钮 参数为index和一个按钮集 parenet 是那种分类,0是顶级,1是分类,2是地区,3是年代,4是排序
294 | Widget classButton(int paramId, String str) {
295 | var textColor = param[paramId] == str
296 | ? Color.fromARGB(255, 255, 219, 79)
297 | : Color.fromARGB(255, 0, 0, 0);
298 | return new GestureDetector(
299 | child: new Container(
300 | alignment: Alignment.center,
301 | child:
302 | new Text(str, style: TextStyle(fontSize: 15.0, color: textColor)),
303 | margin: EdgeInsets.only(right: 20.0),
304 | ),
305 | onTap: () {
306 | setState(() {
307 | param[paramId] = str;
308 | loadMore(true); //更新列表
309 | });
310 | },
311 | );
312 | }
313 |
314 | Widget item(Map data) {
315 | return new GestureDetector(
316 | child: new Container(
317 | width: MediaQuery.of(context).size.width,
318 | height: 140.0,
319 | padding: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 10.0),
320 | color: Color.fromARGB(255, 255, 255, 255),
321 | child: Row(
322 | children: [
323 | Expanded(
324 | flex: 2,
325 | child: Image.network(data['vod_pic'], fit: BoxFit.fill),
326 | ),
327 | Expanded(
328 | flex: 6,
329 | child: new Container(
330 | padding: EdgeInsets.only(left: 10.0, right: 10.0),
331 | child: new Column(
332 | mainAxisAlignment: MainAxisAlignment.spaceAround,
333 | crossAxisAlignment: CrossAxisAlignment.start,
334 | children: [
335 | new Text(
336 | data['vod_name'],
337 | style: TextStyle(
338 | fontSize: 18.0, color: Color.fromARGB(255, 0, 0, 0)),
339 | maxLines: 1,
340 | overflow: TextOverflow.clip,
341 | ),
342 | Text(
343 | data['vod_area'] +
344 | ' ' +
345 | data['vod_lang'] +
346 | ' ' +
347 | data['vod_year'],
348 | style: TextStyle(fontSize: 13.0, color: Colors.grey),
349 | maxLines: 1,
350 | overflow: TextOverflow.clip,
351 | ),
352 | Text(
353 | data['vod_director'] + ' ' + data['vod_actor'],
354 | style: TextStyle(fontSize: 13.0, color: Colors.grey),
355 | maxLines: 1,
356 | overflow: TextOverflow.clip,
357 | ),
358 | Text(
359 | data['vod_remarks'],
360 | style: TextStyle(fontSize: 13.0, color: Colors.grey),
361 | maxLines: 1,
362 | overflow: TextOverflow.clip,
363 | )
364 | ],
365 | ),
366 | ),
367 | )
368 | ],
369 | ),
370 | ),
371 | onTap: () {
372 | Navigator.push(context,
373 | new MaterialPageRoute(builder: (BuildContext context) {
374 | return new Detail(data['vod_id']);
375 | }));
376 | },
377 | );
378 | }
379 |
380 | @override
381 | bool get wantKeepAlive => true;
382 | }
383 |
--------------------------------------------------------------------------------
/lib/pages/Detail.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | //import 'package:custom_chewie/custom_chewie.dart';
3 | import 'package:video_player/video_player.dart';
4 | import 'package:chewie/chewie.dart';
5 | import 'package:dio/dio.dart';
6 | import 'package:maccms_app/constant.dart';
7 |
8 | class Detail extends StatefulWidget{
9 | final int id;
10 | final int rid;
11 | Detail(this.id,{this.rid=0});
12 | @override
13 | _DetailState createState() => _DetailState();
14 | }
15 |
16 | class _DetailState extends State{
17 | Map data={};
18 | List vodPlayList = [];
19 | int vodPlayCount = 0;
20 | int rid = 0;
21 | VideoPlayerController _controller = new VideoPlayerController.network(
22 | '',
23 | );
24 | bool isVideoExist = true;
25 | Dio dio;
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 | this.rid = widget.rid;
31 | dio = new Dio();
32 | print('电影id'+widget.id.toString());
33 | getDetail(widget.id);
34 | }
35 |
36 | @override
37 | void dispose() {
38 | print('销毁播放页面');
39 | _controller.dispose();
40 | super.dispose();
41 | }
42 |
43 | Future getPlay(String playfrom,String playurl) async{
44 | Response data = await dio.get(Constant.apiUrl+'app/play?playfrom='+playfrom+'&playurl='+playurl);
45 | if(data.statusCode==200&&data.data['code']==1){
46 | print(data.data['playurl'].toString());
47 | setState(() {
48 | _controller = new VideoPlayerController.network(
49 | data.data['playurl']
50 | );
51 | });
52 | }else{
53 | setState(() {
54 | isVideoExist = false;
55 | });
56 | }
57 |
58 | }
59 |
60 | Future getDetail(int id) async{
61 | Response data = await dio.get(Constant.apiUrl+'app/detail?id='+id.toString());
62 | if(data.statusCode==200){
63 | if(data.data['msg']=='获取成功'){
64 | setState(() {
65 | this.data = data.data['info'];
66 | this.vodPlayList = data.data['info']['vod_play_url'];
67 | print(vodPlayList);
68 | vodPlayCount = vodPlayList.length==null?0:vodPlayList.length;
69 | });
70 | getPlay(this.data['vod_play_from'],this.data['vod_play_url'][rid]['url']);
71 | }else{
72 | setState(() {
73 | this.isVideoExist=false;
74 | });
75 | }
76 | }
77 | }
78 | //影片标题
79 | Widget _title(){
80 | return Container(
81 | width: double.infinity,
82 | margin: EdgeInsets.fromLTRB(10, 0, 10, 10),
83 | alignment: Alignment.centerLeft,
84 | child: Text(data['vod_name'].toString(),style: TextStyle(fontSize: 20,fontWeight: FontWeight.w600),maxLines: 1,overflow: TextOverflow.clip,),
85 | );
86 | }
87 |
88 | Widget _laiyuan(){
89 | return Container(
90 | width: double.infinity,
91 | margin: EdgeInsets.fromLTRB(10, 0, 10, 5),
92 | alignment: Alignment.centerLeft,
93 | child: Text('来源:网络',style: TextStyle(fontSize: 12,fontWeight: FontWeight.w500,color: Colors.grey),maxLines: 1,overflow: TextOverflow.clip,),
94 | );
95 | }
96 |
97 | Widget _des(){
98 | return Container(
99 | width: double.infinity,
100 | margin: EdgeInsets.fromLTRB(10, 0, 10, 5),
101 | alignment: Alignment.centerLeft,
102 | child: Text(data['vod_blurb'].toString(),style: TextStyle(fontSize: 13,fontWeight: FontWeight.w500,color: Colors.grey),maxLines: 3,overflow: TextOverflow.clip,softWrap: true,),
103 | );
104 | }
105 |
106 | Widget _find(){
107 | return Container(
108 | margin: EdgeInsets.only(left: 10,right: 10,bottom: 0,top: 0),
109 | child: Builder(builder: (context){
110 | return Row(
111 | children: [
112 | IconButton(
113 | onPressed: (){
114 | Scaffold.of(context).showSnackBar(_snackBar('开发中,稍安勿躁-.-'));
115 | },
116 | icon: Icon(
117 | Icons.favorite_border,
118 | size: 25,
119 | color: Colors.grey[400],
120 | ),
121 | ),
122 | IconButton(
123 | onPressed: (){
124 | Scaffold.of(context).showSnackBar(_snackBar('开发中,稍安勿躁-.-'));
125 | },
126 | icon: Icon(
127 | Icons.file_download,
128 | size: 25,
129 | color: Colors.grey[400],
130 | ),
131 | ),
132 | IconButton(
133 | onPressed: (){
134 | Scaffold.of(context).showSnackBar(_snackBar('开发中,稍安勿躁-.-'));
135 | },
136 | icon: Icon(
137 | Icons.share,
138 | size: 25,
139 | color: Colors.grey[400],
140 | ),
141 | )
142 | ],
143 | );
144 | },
145 | )
146 | );
147 | }
148 |
149 | Widget _vodList(){
150 | return Container(
151 | width: MediaQuery.of(context).size.width-20,
152 | margin: EdgeInsets.fromLTRB(10, 0, 10, 5),
153 | child: Column(
154 | children: [
155 | Container(
156 | height: 22,
157 | margin: EdgeInsets.only(top: 5,bottom: 10),
158 | child: Row(
159 | crossAxisAlignment: CrossAxisAlignment.center,
160 | children: [
161 | Text('选集',style: TextStyle(fontSize: 15,fontWeight: FontWeight.w600,color: Colors.black),maxLines: 1,overflow: TextOverflow.clip),
162 | Container(
163 | width: MediaQuery.of(context).size.width-50,
164 | alignment: Alignment.centerRight,
165 | child: GestureDetector(
166 | child: Icon(Icons.keyboard_arrow_right,size: 22,color: Colors.grey,),
167 | onTap: (){
168 | print('选集更多被按下');
169 | },
170 | ),
171 | ),
172 | ],
173 | ),
174 | ),
175 | Container(
176 | width: MediaQuery.of(context).size.width-20,
177 | height: 50,
178 | child: ListView.builder(
179 | scrollDirection: Axis.horizontal,
180 | itemCount: vodPlayCount,
181 | itemBuilder: (BuildContext context,int index){
182 | return GestureDetector(
183 | child: Container(
184 | padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
185 | margin: EdgeInsets.only(right: 10),
186 | alignment: Alignment.center,
187 | decoration: BoxDecoration(
188 | color: Colors.grey[200],
189 | borderRadius: BorderRadius.circular(5)
190 | ),
191 | child: Text(vodPlayList[index]['name'].toString(),style: TextStyle(color: this.rid==index?Colors.orange:Colors.black87,),),
192 | ),
193 | onTap: (){
194 | print('第'+index.toString()+'集被按下');
195 | },
196 | );
197 | },
198 | ),
199 | ),
200 | Container(
201 | margin: EdgeInsets.only(top: 10),
202 | child: Divider(),
203 | )
204 | ],
205 | ),
206 | );
207 | }
208 |
209 | Widget _snackBar(String str){
210 | return SnackBar(
211 | content: Container(
212 | height: 20,
213 | width: MediaQuery.of(context).size.width,
214 | alignment: Alignment.center,
215 | child: Text(str,style: TextStyle(fontSize: 15,color: Colors.white),),
216 | ),
217 | backgroundColor: Color.fromARGB(100, 0, 0, 0),
218 | duration: Duration(seconds: 3),
219 | );
220 | }
221 |
222 |
223 |
224 | @override
225 | Widget build(BuildContext context) {
226 | return new Scaffold(
227 | body:Column(
228 | children: [
229 | Stack(
230 | children: [
231 | Container(
232 | height: 200,
233 | //padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
234 | color: Colors.black,
235 | width: MediaQuery.of(context).size.width,
236 | child: Chewie(
237 | _controller,
238 | aspectRatio: 16 / 9,
239 | autoInitialize: true,
240 | autoPlay: false,
241 | looping: true,
242 | materialProgressColors: new ChewieProgressColors(
243 | playedColor: Color.fromARGB(255, 255, 219, 79),
244 | handleColor: Color.fromARGB(255, 255, 219, 79),
245 | backgroundColor: Colors.grey,
246 | bufferedColor: Colors.lightGreen,
247 | ),
248 | // Try playing around with some of these other options:
249 |
250 | // showControls: false,
251 | // materialProgressColors: new ChewieProgressColors(
252 | // playedColor: Colors.red,
253 | // handleColor: Colors.blue,
254 | // backgroundColor: Colors.grey,
255 | // bufferedColor: Colors.lightGreen,
256 | // ),
257 | // placeholder: new Container(
258 | // color: Colors.grey,
259 | // ),
260 | // autoInitialize: true,
261 | ),
262 | ),
263 | Align(
264 | alignment: Alignment.topLeft,
265 | child: IconButton(
266 | padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
267 | icon: Icon(
268 | Icons.keyboard_arrow_left,
269 | color: Colors.white70,
270 | size: 32,
271 | ),
272 | onPressed: (){
273 | Navigator.of(context).pop();
274 | },
275 | ),
276 | ),
277 |
278 | ],
279 | ),
280 | Container(
281 | height: MediaQuery.of(context).size.height-200,
282 | width: MediaQuery.of(context).size.width,
283 | color: Colors.white,
284 | child: ListView(
285 | children: [
286 | _title(),
287 | _laiyuan(),
288 | _des(),
289 | _find(),
290 | Divider(),
291 | _vodList()
292 | ],
293 | ),
294 | ),
295 | ],
296 | )
297 | );
298 | }
299 | }
300 |
301 | /*
302 | Container(
303 | child: new Chewie(
304 | new VideoPlayerController.network(
305 | 'https://cdn.letv-cdn.com/2018/12/12/N5m3r36wCbDUbHWe/playlist.m3u8'
306 | ),
307 | aspectRatio: 16 / 9,
308 | autoPlay: true,
309 | looping: true,
310 | ),
311 | height: 200,
312 | color: Colors.black,
313 | )
314 | */
--------------------------------------------------------------------------------
/lib/pages/Home.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_swiper/flutter_swiper.dart';
3 | import 'package:dio/dio.dart';
4 | import 'package:maccms_app/constant.dart';
5 | import 'dart:async';
6 | import 'Detail.dart';
7 | import 'package:maccms_app/MyWidGet/Base_Font.dart';
8 |
9 | class Home extends StatefulWidget{
10 | Home({Key key}):super(key:key);
11 | @override
12 | _HomeState createState() => _HomeState();
13 | }
14 |
15 | class _HomeState extends State with AutomaticKeepAliveClientMixin{
16 | List body = [];
17 |
18 | @override
19 | bool get wantKeepAlive => true;
20 | @override
21 | Widget build(BuildContext context) {
22 | super.build(context);
23 | //headerSwiper();
24 | //bodyList();
25 | return Scaffold(
26 | appBar: AppBar( //首页搜索
27 | backgroundColor: Color.fromARGB(255, 255, 219, 79),
28 | primary: true,
29 | elevation: 0.0,
30 | title: new Container(
31 | decoration: new BoxDecoration(
32 | border: new Border.all(
33 | width: 1.0, color: Color.fromARGB(255, 226, 226, 226)),
34 | borderRadius: new BorderRadius.all(Radius.circular(5.0)),
35 | color: Color.fromARGB(255, 255, 255, 255)),
36 | alignment: Alignment.center,
37 | height: 30.0,
38 | child: new Row(
39 | children: [
40 | new Expanded(
41 | child: new Icon(Base.sousuo,
42 | size: 17.0, color: Color.fromARGB(255, 226, 226, 226)),
43 | flex: 1),
44 | new Expanded(
45 | child: new Text('热门',
46 | style: TextStyle(
47 | color: Color.fromARGB(255, 226, 226, 226),
48 | fontSize: 17.0)),
49 | flex: 9)
50 | ],
51 | ),
52 | ),
53 | ),
54 | body: CustomScrollView(
55 | scrollDirection: Axis.vertical,
56 | slivers:[
57 | new SliverToBoxAdapter(
58 | child: new Stack(children: [
59 | new Container(
60 | height: 160.0, color: Color.fromARGB(255, 244, 244, 244)),
61 | new Positioned(
62 | top: 0.0,
63 | left: 0.0,
64 | right: 0.0,
65 | child: new Container(
66 | decoration:
67 | new BoxDecoration(color: Color.fromARGB(255, 255, 219, 79)),
68 | height: 100.0,
69 | ),
70 | ),
71 | new Positioned(
72 | top: 0.0,
73 | left: 10.0,
74 | right: 10.0,
75 | child: new Container(
76 | height: 140.0,
77 | decoration: new BoxDecoration(
78 | color: Color.fromARGB(255, 132, 132, 132),
79 | ),
80 | child: new HeadSwiper(),
81 | ),
82 | )
83 | ])
84 | ),
85 | new BodyList()
86 | ]
87 | ),
88 | );
89 | }
90 |
91 | //头部轮播图
92 | void headerSwiper(){
93 | body.add(
94 | new SliverToBoxAdapter(
95 | child: new Stack(children: [
96 | new Container(
97 | height: 160.0, color: Color.fromARGB(255, 244, 244, 244)),
98 | new Positioned(
99 | top: 0.0,
100 | left: 0.0,
101 | right: 0.0,
102 | child: new Container(
103 | decoration:
104 | new BoxDecoration(color: Color.fromARGB(255, 255, 219, 79)),
105 | height: 100.0,
106 | ),
107 | ),
108 | new Positioned(
109 | top: 0.0,
110 | left: 10.0,
111 | right: 10.0,
112 | child: new Container(
113 | height: 140.0,
114 | decoration: new BoxDecoration(
115 | color: Color.fromARGB(255, 132, 132, 132),
116 | ),
117 | child: new HeadSwiper(),
118 | ),
119 | )
120 | ])
121 | )
122 | );
123 | }//end头部轮播
124 |
125 | //首页列表
126 | void bodyList(){
127 | body.add(BodyList());
128 | }//end首页列表
129 |
130 |
131 | }
132 |
133 | //轮播网络取数据类
134 | class HeadSwiper extends StatefulWidget {
135 | @override
136 | _HeadSwiperState createState() => _HeadSwiperState();
137 | }
138 |
139 | class _HeadSwiperState extends State {
140 | Response img;
141 | List imglist;
142 | int imgcount=0;
143 | @override
144 | Widget build(BuildContext context) {
145 | return new Swiper(
146 | autoplay: true,
147 | itemBuilder: (BuildContext context, int index) {
148 | return new Image.network(
149 | imglist[index]['src'],
150 | fit: BoxFit.fill,
151 | );
152 | },
153 | itemCount: imgcount,
154 | onTap: (int index){onTap(index);},
155 | );
156 | }
157 |
158 | onTap(int index){
159 | Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context){
160 | return new Detail(imglist[index]['id']);
161 | }));
162 | }
163 |
164 | Future imget() async {
165 | Dio dio = new Dio();
166 | img = await dio.get(Constant.apiUrl + 'app/swiper');
167 | if(img.statusCode==200){
168 | setState(() {
169 | imglist = img.data;
170 | imgcount = imglist.length;
171 | });
172 |
173 | }
174 | }
175 |
176 | static SlideTransition createTransition(
177 | Animation animation, Widget child) {
178 | return new SlideTransition(
179 | position: new Tween(
180 | begin: const Offset(1.0, 0.0),
181 | end: const Offset(0.0, 0.0),
182 | ).animate(animation),
183 | child: child,
184 | );
185 | }
186 | @override
187 | void initState(){
188 | super.initState();
189 | imget();
190 | }
191 | }//end轮播网络取数据类
192 |
193 |
194 | class BodyList extends StatefulWidget{
195 | @override
196 | State createState() {
197 | return _BodyListState();
198 | }
199 | }
200 |
201 | class _BodyListState extends State{
202 | List apiList;
203 | int apiCount=0;
204 | //List list = [];
205 | @override
206 | Widget build(BuildContext context) {
207 | return new SliverList(
208 | delegate: SliverChildBuilderDelegate((BuildContext context,int index){
209 | return buildItem(index);
210 | },childCount: apiCount),
211 | );
212 | }
213 |
214 | Future apiGet() async{
215 | Dio dio = new Dio();
216 | Response apidata = await dio.get(Constant.apiUrl+'app/home_category');
217 | if(apidata.statusCode==200){
218 | setState(() {
219 | this.apiList = apidata.data;
220 | apiCount = this.apiList.length;
221 | print(this.apiList[0]);
222 | });
223 | }
224 | }
225 |
226 | Widget buildItem(int index){
227 | List itemCount = apiList[index]['list'];
228 | //卡片内标题
229 | Widget headTitle = new Container(
230 | height: 50.0,
231 | padding: EdgeInsets.fromLTRB(5.0, 0.0, 0.0, 0.0),
232 | child: Row(
233 | crossAxisAlignment: CrossAxisAlignment.center,
234 | mainAxisAlignment: MainAxisAlignment.start,
235 | children: [
236 | Expanded(
237 | flex: 1,
238 | child:new Image.asset('images/heji.png',width: 30.0,height: 30.0) ,
239 | ),
240 | Expanded(
241 | flex: 9,
242 | child:new Text(apiList[index]['name'],
243 | style:TextStyle(
244 | fontSize: 20.0
245 | )
246 | )
247 | )
248 | ],
249 | ),
250 | );
251 | //卡片中左右滑动的列表
252 | Widget item =new Container(
253 | width: MediaQuery.of(context).size.width-10.0,
254 | height: 180.0,
255 | child: new ListView.builder(
256 | scrollDirection: Axis.horizontal,
257 | itemCount: itemCount.length==null?0:itemCount.length,
258 | itemBuilder: (BuildContext context,int subindex){
259 | return subItem(index,subindex);
260 | },
261 | )
262 | );
263 |
264 | return new Container(
265 | height: 240.0,
266 | color: Color.fromARGB(255, 255, 255, 255),
267 | margin: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 10.0),
268 | width: MediaQuery.of(context).size.width,
269 | child: Column(
270 | children: [
271 | headTitle,
272 | item
273 |
274 | //item
275 | ],
276 | ),
277 | );
278 | }
279 |
280 | Widget subItem(int index,int subindex){
281 | return GestureDetector(
282 | child:Container(
283 | width: 110.0,
284 | margin: EdgeInsets.fromLTRB(5.0, 0.0, 4.0, 0.0),
285 | child: Column(
286 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
287 | children: [
288 | new Image.network(apiList[index]['list'][subindex]['vod_pic'],fit: BoxFit.fill,height: 150.0,width: 110.0,),
289 | new Text(apiList[index]['list'][subindex]['vod_name'],overflow: TextOverflow.clip,maxLines: 1,)
290 | ],
291 | ),
292 | ),
293 | onTap: (){//被点击
294 | Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context){
295 | return new Detail(apiList[index]['list'][subindex]['vod_id']);
296 | }));
297 | },
298 | );
299 | }
300 | //跳转动画
301 |
302 |
303 | @override
304 | void initState(){
305 | super.initState();
306 | apiGet();
307 | }
308 | }
--------------------------------------------------------------------------------
/lib/pages/HomeBak.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:maccms_app/MyWidGet/Base_Font.dart';
3 | import 'package:flutter_swiper/flutter_swiper.dart';
4 | import 'package:dio/dio.dart';
5 | import 'package:maccms_app/constant.dart';
6 | import 'dart:async';
7 | import 'Detail.dart';
8 |
9 | class Homes extends StatelessWidget {
10 | @override
11 | Widget build(BuildContext context) {
12 | return Scaffold(
13 | appBar: new AppBar(
14 | backgroundColor: Color.fromARGB(255, 255, 219, 79),
15 | primary: true,
16 | elevation: 0.0,
17 | title: new Container(
18 | decoration: new BoxDecoration(
19 | border: new Border.all(
20 | width: 1.0, color: Color.fromARGB(255, 226, 226, 226)),
21 | borderRadius: new BorderRadius.all(Radius.circular(5.0)),
22 | color: Color.fromARGB(255, 255, 255, 255)),
23 | alignment: Alignment.center,
24 | height: 30.0,
25 | child: new Row(
26 | children: [
27 | new Expanded(
28 | child: new Icon(Base.sousuo,
29 | size: 17.0, color: Color.fromARGB(255, 226, 226, 226)),
30 | flex: 1),
31 | new Expanded(
32 | child: new Text('热门',
33 | style: TextStyle(
34 | color: Color.fromARGB(255, 226, 226, 226),
35 | fontSize: 17.0)),
36 | flex: 9)
37 | ],
38 | ),
39 | ),
40 | ),
41 | body: new Body(),
42 | );
43 | }
44 | }
45 |
46 | class Body extends StatelessWidget {
47 | @override
48 | Widget build(BuildContext context) {
49 | return new Container(
50 | child: CustomScrollView(
51 | scrollDirection: Axis.vertical,
52 | slivers:[
53 | new SliverToBoxAdapter(
54 | child: new Stack(children: [
55 | new Container(
56 | height: 160.0, color: Color.fromARGB(255, 244, 244, 244)),
57 | new Positioned(
58 | top: 0.0,
59 | left: 0.0,
60 | right: 0.0,
61 | child: new Container(
62 | decoration:
63 | new BoxDecoration(color: Color.fromARGB(255, 255, 219, 79)),
64 | height: 100.0,
65 | ),
66 | ),
67 | new Positioned(
68 | top: 0.0,
69 | left: 10.0,
70 | right: 10.0,
71 | child: new Container(
72 | height: 140.0,
73 | decoration: new BoxDecoration(
74 | color: Color.fromARGB(255, 132, 132, 132),
75 | ),
76 | child: new HeadSwiper(),
77 | ),
78 | )
79 | ])
80 | ),
81 | new SliverToBoxAdapter(
82 | child: new Container(
83 | height: 1000.0,
84 | color: Colors.pink,
85 | ),
86 | )
87 | ]
88 | ),
89 | );
90 | }
91 | }
92 |
93 | class HeadSwiper extends StatefulWidget {
94 | @override
95 | _HeadSwiperState createState() => _HeadSwiperState();
96 | }
97 |
98 | class _HeadSwiperState extends State {
99 | Response img;
100 | List imglist;
101 | int imgcount=0;
102 | @override
103 | Widget build(BuildContext context) {
104 | return new Swiper(
105 | autoplay: true,
106 | itemBuilder: (BuildContext context, int index) {
107 | return new Image.network(
108 | imglist[index]['src'],
109 | fit: BoxFit.fill,
110 | );
111 | },
112 | itemCount: imgcount,
113 | onTap: (int index){onTap(index);},
114 | );
115 | }
116 |
117 | onTap(int index){
118 | Navigator.of(context).push(new PageRouteBuilder(
119 | pageBuilder: (BuildContext context,
120 | Animation animation,
121 | Animation secondaryAnimation) {
122 | return new Detail(imglist[index]['id']);
123 | },
124 | transitionsBuilder: (
125 | BuildContext context,
126 | Animation animation,
127 | Animation secondaryAnimation,
128 | Widget child,
129 | ) {
130 | return createTransition(animation, child);
131 | }));
132 | }
133 |
134 | Future imget() async {
135 | Dio dio = new Dio();
136 | img = await dio.get(Constant.apiUrl + 'app/swiper');
137 | if(img.statusCode==200){
138 | setState(() {
139 | imglist = img.data;
140 | imgcount = imglist.length;
141 | });
142 |
143 | }
144 | }
145 |
146 | static SlideTransition createTransition(
147 | Animation animation, Widget child) {
148 | return new SlideTransition(
149 | position: new Tween(
150 | begin: const Offset(1.0, 0.0),
151 | end: const Offset(0.0, 0.0),
152 | ).animate(animation),
153 | child: child,
154 | );
155 | }
156 | @override
157 | void initState(){
158 | super.initState();
159 | imget();
160 | }
161 | }
162 |
163 | class Bodyinfo extends StatefulWidget{
164 | @override
165 | _BodyinfoState createState() => _BodyinfoState();
166 | }
167 |
168 | class _BodyinfoState extends State{
169 | List bodyinfo = [];
170 | @override
171 | Widget build(BuildContext context) {
172 |
173 | start();
174 | return ListView(
175 | children: bodyinfo,
176 | );
177 | }
178 |
179 | start(){
180 | for(int i=0;i<4;i++){
181 | List subitem = [];
182 | for(int ii=0;ii<2;ii++){
183 | List rowitem = [];
184 | for(int iii=0;iii<3;iii++){
185 | rowitem.add(
186 | new Card(
187 | child: Column(
188 | children: [
189 | new Container(
190 | width: 100.0,
191 | height: 140.0,
192 | color: Color.fromARGB(255, 222, 222, 222),
193 | ),
194 | new Container(
195 | width: 80.0,
196 | height: 20.0,
197 | color: Color.fromARGB(255, 222, 222, 222),
198 | margin: EdgeInsets.fromLTRB(0.0, 5.0, 0.0, 5.0),
199 | )
200 | ],
201 | ),
202 | )
203 | );
204 | }
205 | subitem.add(new Column(
206 | children: rowitem
207 | ));
208 | }
209 | bodyinfo.add(
210 | new Column(
211 | children: subitem,
212 | )
213 | );
214 | }
215 | }
216 |
217 |
218 | }
--------------------------------------------------------------------------------
/lib/pages/My.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:wave/wave.dart';
3 | import 'package:wave/config.dart';
4 | import 'package:maccms_app/pages/About.dart';
5 | import 'package:maccms_app/pages/Statement.dart';
6 |
7 | class My extends StatefulWidget {
8 | My({Key key}) : super(key: key);
9 | @override
10 | _MyState createState() => _MyState();
11 | }
12 |
13 | class _MyState extends State {
14 | bool isLogin = false;
15 | //头部
16 | _head(
17 | {Config config,
18 | Color backgroundColor = Colors.transparent,
19 | double width,
20 | double height}) {
21 | return Container(
22 | width: double.infinity,
23 | child: WaveWidget(
24 | config: config,
25 | backgroundColor: backgroundColor,
26 | size: Size(width, height),
27 | waveAmplitude: 0,
28 | ),
29 | );
30 | }
31 |
32 | //是否登录
33 | _isLogin() {
34 | if (isLogin == false) {
35 | return GestureDetector(
36 | child: Row(
37 | children: [
38 | Expanded(
39 | flex: 9,
40 | child: Column(
41 | crossAxisAlignment: CrossAxisAlignment.start,
42 | children: [
43 | Text('立即登录',
44 | style: TextStyle(
45 | color: Colors.black87,
46 | fontSize: 25,
47 | fontWeight: FontWeight.w100)),
48 | Text(
49 | '暂未开放注册,期待下一版本!',
50 | )
51 | ],
52 | ),
53 | ),
54 | Expanded(
55 | flex: 1,
56 | child: Icon(
57 | Icons.chevron_right,
58 | size: 25,
59 | ),
60 | )
61 | ],
62 | ),
63 | onTap: () {
64 | //点击事件
65 | print('登录被点击');
66 | },
67 | );
68 | }
69 | }
70 | //功能按钮列表
71 | Widget _buttonListview(){
72 | return ListView(
73 | children: [
74 | _buttonItem('history','images/history.png','足迹'),
75 | _buttonItem('feedback','images/feedback.png','反馈'),
76 | _buttonItem('setting','images/setting.png','设置'),
77 | _buttonItem('about','images/about.png','关于'),
78 | _buttonItem('statement','images/statement.png','免责声明')
79 | ],
80 | );
81 | }
82 | //单个块封装
83 | _buttonItem(String index,String image,String title){
84 | return GestureDetector(
85 | child: Container(
86 | padding: EdgeInsets.only(right: 15),
87 | height: 50,
88 | alignment: Alignment.center,
89 | child: Row(
90 | children: [
91 | Container(
92 | width: 50,
93 | alignment: Alignment.center,
94 | child: Image.asset(
95 | image,
96 | fit: BoxFit.fill,
97 | width: 25.0,
98 | height: 25.0,
99 | ),
100 | ),
101 | Expanded(
102 | flex: 7,
103 | child: Container(
104 | alignment: Alignment.centerLeft,
105 | height: 50,
106 | child: Text(title,style: TextStyle(fontSize: 15),),
107 | decoration: BoxDecoration(
108 | border: Border(
109 | bottom: Divider.createBorderSide(context, color: Colors.grey[350])
110 | )
111 | ),
112 | ),
113 | ),
114 | Container(
115 | height: 50,
116 | width: 25,
117 | alignment: Alignment.centerRight,
118 | child: Icon(
119 | Icons.chevron_right,
120 | size: 25,
121 | color: Color.fromARGB(255, 132, 132, 132),
122 | ),
123 | decoration: BoxDecoration(
124 | border: Border(
125 | bottom: Divider.createBorderSide(context, color: Colors.grey[350])
126 | )
127 | ),
128 | ),
129 | ],
130 | ),
131 | ),
132 | onTap: (){
133 | _buttonTap(index);
134 | },
135 | );
136 | }
137 |
138 | void _buttonTap(String index){
139 | switch (index){
140 | case 'about':
141 | Navigator.push(context,
142 | new MaterialPageRoute(builder: (BuildContext context) {
143 | return new About();
144 | }));
145 | break;
146 | case 'statement':
147 | Navigator.push(context,
148 | new MaterialPageRoute(builder: (BuildContext context) {
149 | return new Statement();
150 | }));
151 | break;
152 | default:
153 | print('null');
154 | break;
155 | }
156 | }
157 | @override
158 | Widget build(BuildContext context) {
159 | return Stack(
160 | children: [
161 | Card(
162 | elevation: 0.0,
163 | color: Color.fromARGB(255, 255, 219, 79),
164 | margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
165 | child: _head(
166 | config: CustomConfig(
167 | gradients: [
168 | [Colors.orange[300], Colors.white],
169 | [Colors.orange[200], Colors.white],
170 | [Colors.orange[100], Colors.white],
171 | [Colors.white, Colors.white],
172 | ],
173 | durations: [35000, 19440, 10800, 6000],
174 | heightPercentages: [0.79, 0.79, 0.81, 0.81],
175 | blur: MaskFilter.blur(BlurStyle.outer, 10),
176 | ),
177 | //backgroundColor: Color.fromARGB(255, 255, 219, 79),
178 | width: MediaQuery.of(context).size.width,
179 | height: kToolbarHeight + 115),
180 | ),
181 | Positioned(
182 | top: kToolbarHeight + 10,
183 | left: 15,
184 | //right: (MediaQuery.of(context).size.width/2)-50,
185 | child: Container(
186 | height: 70,
187 | width: 70,
188 | decoration: BoxDecoration(
189 | //color: Colors.red,
190 | image: DecorationImage(
191 | image: AssetImage('images/avatar.png'), fit: BoxFit.fill),
192 | borderRadius: BorderRadius.circular(90),
193 | /*boxShadow: [
194 | new BoxShadow(
195 | color: Colors.white,
196 | offset: Offset(0, 0),
197 | blurRadius: 1.0)
198 | ]*/
199 | ),
200 | ),
201 | ),
202 | Positioned(
203 | top: kToolbarHeight + 20,
204 | left: 100,
205 | child: Container(
206 | width: MediaQuery.of(context).size.width - 100,
207 | child: _isLogin(),
208 | ),
209 | ),
210 | Positioned(
211 | top: kToolbarHeight + 115,
212 | child: Container(
213 | color: Colors.white,
214 | width: MediaQuery.of(context).size.width,
215 | height: MediaQuery.of(context).size.height -
216 | MediaQuery.of(context).padding.top -
217 | kBottomNavigationBarHeight -
218 | kToolbarHeight + 115,
219 | child: _buttonListview(),
220 | ),
221 | )
222 | ],
223 | );
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/lib/pages/StartPage.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:flutter/widgets.dart';
3 |
4 |
5 | //启动页
6 | class StartPage extends StatefulWidget{
7 | @override
8 | State createState() {
9 | return _StatePageState();
10 | }
11 | }
12 |
13 | class _StatePageState extends State{
14 | @override
15 | Widget build(BuildContext context) {
16 | return new Container(
17 | child: Stack(
18 | children: [
19 | Container(color: Color.fromARGB(
20 | 255, 255, 219, 79),),
21 | ],
22 | ),
23 | );
24 | }
25 | @override
26 | void initState() {
27 | super.initState();
28 | countDown();
29 | }
30 | //倒计时
31 | void countDown() {
32 | var _duration = new Duration(seconds: 3);
33 | new Future.delayed(_duration, goToApp);
34 | }
35 | //路由跳转
36 | void goToApp(){
37 | Navigator.of(context).pushReplacementNamed('/App');
38 | }
39 | }
--------------------------------------------------------------------------------
/lib/pages/Statement.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:maccms_app/constant.dart';
3 |
4 | class Statement extends StatefulWidget {
5 | Statement({Key key}) : super(key: key);
6 | @override
7 | _Statement createState() => _Statement();
8 | }
9 |
10 | class _Statement extends State {
11 | @override
12 | Widget build(BuildContext context) {
13 | return Scaffold(
14 | appBar: AppBar(
15 | centerTitle: true,
16 | backgroundColor: Colors.white,
17 | elevation: 1.0,
18 | leading: GestureDetector(
19 | child: Icon(Icons.chevron_left,color:Colors.black,size:25),
20 | onTap: (){
21 | Navigator.pop(context);
22 | },
23 | ),
24 | title: Text("免责声明",style: TextStyle(fontSize: 18,color: Colors.black),)
25 | ),
26 | body: ListView(
27 | children: [
28 | Container(
29 | padding: EdgeInsets.fromLTRB(15, 15, 15, 15),
30 | color: Colors.white,
31 | child: Text('1. 本APP属非赢利性质,不提供任何视听上传服务,所有内容均来自视频分享站点所提供的公开引用资源,所有视频及图文版权均归原作者及其网站所有。本APP不存储,不修改界面内容。视频数据流也不经由本公司服务器中转或存储。本站将竭尽所能注明资源来源,但由于互联网转载的不可预性,无法确认所有内容的版权所有人。若原作者对本站所载视频作品版权的归属存有异议,请联系我们,我们将在第一时间予以删除。\n\n2. 任何存在于APP上的视频、图文资料均系他人制作或提供,仅为个人观点,不代表本APP立场。\n\n3. 本APP对网络视频的聚合和分类,是根据用户观看习惯做的浏览引导,这样可以方便用户更快捷的找到相应的视频,本APP并没有对任何视频做编辑和整理。\n\n4. 您应该对浏览使用本APP一切服务自行承担风险。我们不做任何形式的保证:不保证站内搜索结果满足您的要求,不保证网站服务不中断,不保证视频及图文资源的安全性、正确性、及时性、合法性。因网络状况、通讯线路、第三方网站等任何原因而导致您不能正常使用本APP,本APP不承担任何法律责任。\n\n5. 本APP尊重并保护所有使用本APP用户的个人隐私权,您注册的用户名、电子邮件地址等个人资料,非经您亲自许可或根据相关法律、法规的强制性规定,我们不会主动地泄露给第三方。\n\n6. 任何单位或个人认为通过我们提供的内容可能涉嫌侵犯其信息网络传播权,应该及时向我们提出书面权利通知,并提供相关证明、权属证明及详细侵权情况证明。我们在收到上述法律文件后,将会尽快采取措施并断开相关链接内容。\n\n7. 我们一切资源仅为学习交流娱乐所用,请在下载后24小时内删除,未经版权许可,任何单位或个人不得将本站内容或服务用于商业目的。\n\n8. 我们本着在未改变视频内容的提供主体情况下为用户提供视频链接的网络服务,并将竭力确保版权方并未失去对视频内容传播的控制权,我们将积极主动地维护广大网民及视频创造者的合法权益,维护公众利益共建和谐网络环境,以鼓励视频创造者创做更多优质内容让更多用户看到。在版权保护的道路上,我们愿意积极配合版权方做出快速有效的回应。'),
32 | )
33 | ],
34 | )
35 | );
36 | }
37 | }
--------------------------------------------------------------------------------
/maccms_app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/maccms_app_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://www.dartlang.org/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.flutter-io.cn"
9 | source: hosted
10 | version: "2.0.8"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.flutter-io.cn"
16 | source: hosted
17 | version: "1.0.4"
18 | charcode:
19 | dependency: transitive
20 | description:
21 | name: charcode
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "1.1.2"
25 | chewie:
26 | dependency: "direct main"
27 | description:
28 | name: chewie
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "0.8.0"
32 | collection:
33 | dependency: transitive
34 | description:
35 | name: collection
36 | url: "https://pub.flutter-io.cn"
37 | source: hosted
38 | version: "1.14.11"
39 | cookie_jar:
40 | dependency: transitive
41 | description:
42 | name: cookie_jar
43 | url: "https://pub.flutter-io.cn"
44 | source: hosted
45 | version: "0.0.7"
46 | cupertino_icons:
47 | dependency: "direct main"
48 | description:
49 | name: cupertino_icons
50 | url: "https://pub.flutter-io.cn"
51 | source: hosted
52 | version: "0.1.2"
53 | dio:
54 | dependency: "direct main"
55 | description:
56 | name: dio
57 | url: "https://pub.flutter-io.cn"
58 | source: hosted
59 | version: "1.0.9"
60 | flutter:
61 | dependency: "direct main"
62 | description: flutter
63 | source: sdk
64 | version: "0.0.0"
65 | flutter_page_indicator:
66 | dependency: transitive
67 | description:
68 | name: flutter_page_indicator
69 | url: "https://pub.flutter-io.cn"
70 | source: hosted
71 | version: "0.0.3"
72 | flutter_screenutil:
73 | dependency: "direct main"
74 | description:
75 | name: flutter_screenutil
76 | url: "https://pub.flutter-io.cn"
77 | source: hosted
78 | version: "0.4.1"
79 | flutter_spinkit:
80 | dependency: "direct main"
81 | description:
82 | name: flutter_spinkit
83 | url: "https://pub.flutter-io.cn"
84 | source: hosted
85 | version: "3.0.0"
86 | flutter_swiper:
87 | dependency: "direct main"
88 | description:
89 | name: flutter_swiper
90 | url: "https://pub.flutter-io.cn"
91 | source: hosted
92 | version: "1.1.4"
93 | flutter_test:
94 | dependency: "direct dev"
95 | description: flutter
96 | source: sdk
97 | version: "0.0.0"
98 | lazy_load_scrollview:
99 | dependency: "direct main"
100 | description:
101 | name: lazy_load_scrollview
102 | url: "https://pub.flutter-io.cn"
103 | source: hosted
104 | version: "0.0.2"
105 | matcher:
106 | dependency: transitive
107 | description:
108 | name: matcher
109 | url: "https://pub.flutter-io.cn"
110 | source: hosted
111 | version: "0.12.3+1"
112 | meta:
113 | dependency: transitive
114 | description:
115 | name: meta
116 | url: "https://pub.flutter-io.cn"
117 | source: hosted
118 | version: "1.1.6"
119 | open_iconic_flutter:
120 | dependency: transitive
121 | description:
122 | name: open_iconic_flutter
123 | url: "https://pub.flutter-io.cn"
124 | source: hosted
125 | version: "0.3.0"
126 | path:
127 | dependency: transitive
128 | description:
129 | name: path
130 | url: "https://pub.flutter-io.cn"
131 | source: hosted
132 | version: "1.6.2"
133 | quiver:
134 | dependency: transitive
135 | description:
136 | name: quiver
137 | url: "https://pub.flutter-io.cn"
138 | source: hosted
139 | version: "2.0.1"
140 | sky_engine:
141 | dependency: transitive
142 | description: flutter
143 | source: sdk
144 | version: "0.0.99"
145 | source_span:
146 | dependency: transitive
147 | description:
148 | name: source_span
149 | url: "https://pub.flutter-io.cn"
150 | source: hosted
151 | version: "1.4.1"
152 | stack_trace:
153 | dependency: transitive
154 | description:
155 | name: stack_trace
156 | url: "https://pub.flutter-io.cn"
157 | source: hosted
158 | version: "1.9.3"
159 | stream_channel:
160 | dependency: transitive
161 | description:
162 | name: stream_channel
163 | url: "https://pub.flutter-io.cn"
164 | source: hosted
165 | version: "1.6.8"
166 | string_scanner:
167 | dependency: transitive
168 | description:
169 | name: string_scanner
170 | url: "https://pub.flutter-io.cn"
171 | source: hosted
172 | version: "1.0.4"
173 | term_glyph:
174 | dependency: transitive
175 | description:
176 | name: term_glyph
177 | url: "https://pub.flutter-io.cn"
178 | source: hosted
179 | version: "1.0.1"
180 | test_api:
181 | dependency: transitive
182 | description:
183 | name: test_api
184 | url: "https://pub.flutter-io.cn"
185 | source: hosted
186 | version: "0.2.1"
187 | transformer_page_view:
188 | dependency: transitive
189 | description:
190 | name: transformer_page_view
191 | url: "https://pub.flutter-io.cn"
192 | source: hosted
193 | version: "0.1.4"
194 | typed_data:
195 | dependency: transitive
196 | description:
197 | name: typed_data
198 | url: "https://pub.flutter-io.cn"
199 | source: hosted
200 | version: "1.1.6"
201 | vector_math:
202 | dependency: transitive
203 | description:
204 | name: vector_math
205 | url: "https://pub.flutter-io.cn"
206 | source: hosted
207 | version: "2.0.8"
208 | video_player:
209 | dependency: transitive
210 | description:
211 | name: video_player
212 | url: "https://pub.flutter-io.cn"
213 | source: hosted
214 | version: "0.7.2"
215 | wave:
216 | dependency: "direct main"
217 | description:
218 | name: wave
219 | url: "https://pub.flutter-io.cn"
220 | source: hosted
221 | version: "0.0.7"
222 | sdks:
223 | dart: ">=2.0.0 <3.0.0"
224 | flutter: ">=0.2.5 <2.0.0"
225 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: maccms_app
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 | environment:
13 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
14 |
15 | dependencies:
16 | flutter:
17 | sdk: flutter
18 |
19 | # The following adds the Cupertino Icons font to your application.
20 | # Use with the CupertinoIcons class for iOS style icons.
21 | cupertino_icons: ^0.1.2
22 | flutter_swiper : ^1.1.4
23 | dio : ^1.0.9
24 | flutter_screenutil: ^0.4.1
25 | flutter_spinkit: ^3.0.0
26 | lazy_load_scrollview: ^0.0.1
27 | wave: ^0.0.7
28 | # custom_chewie: ^0.7.0
29 | chewie: ^0.8.0
30 |
31 | dev_dependencies:
32 | flutter_test:
33 | sdk: flutter
34 |
35 |
36 | # For information on the generic Dart part of this file, see the
37 | # following page: https://www.dartlang.org/tools/pub/pubspec
38 |
39 | # The following section is specific to Flutter.
40 | flutter:
41 |
42 | # The following line ensures that the Material Icons font is
43 | # included with your application, so that you can use the icons in
44 | # the material Icons class.
45 | uses-material-design: true
46 |
47 | # To add assets to your application, add an assets section, like this:
48 | assets:
49 | - images/
50 | - images/history.png
51 | - images/feedback.png
52 | - images/setting.png
53 | - images/about.png
54 | - images/statement.png
55 | - images/icon_discovery.png
56 | - images/icon_discovery_active.png
57 | - images/icon_category.png
58 | - images/icon_category_active.png
59 | - images/icon_mine.png
60 | - images/icon_mine_active.png
61 | - images/index_discovery_logo2.png
62 | # - images/a_dot_burr.jpeg
63 | # - images/a_dot_ham.jpeg
64 |
65 | # An image asset can refer to one or more resolution-specific "variants", see
66 | # https://flutter.io/assets-and-images/#resolution-aware.
67 |
68 | # For details regarding adding assets from package dependencies, see
69 | # https://flutter.io/assets-and-images/#from-packages
70 |
71 | # To add custom fonts to your application, add a fonts section here,
72 | # in this "flutter" section. Each entry in this list should have a
73 | # "family" key with the font family name, and a "fonts" key with a
74 | # list giving the asset and other descriptors for the font. For
75 | # example:
76 | # fonts:
77 | # - family: Schyler
78 | # fonts:
79 | # - asset: fonts/Schyler-Regular.ttf
80 | # - asset: fonts/Schyler-Italic.ttf
81 | # style: italic
82 | # - family: Trajan Pro
83 | # fonts:
84 | # - asset: fonts/TrajanPro.ttf
85 | # - asset: fonts/TrajanPro_Bold.ttf
86 | # weight: 700
87 | #
88 | # For details regarding fonts from package dependencies,
89 | # see https://flutter.io/custom-fonts/#from-packages
90 | fonts:
91 | - family: base
92 | fonts:
93 | - asset: fonts/base.ttf
94 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:maccms_app/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------