├── android ├── gradle.properties ├── key.jks ├── key.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── drawable │ │ │ │ │ └── launch_background.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── flutterdemo │ │ │ │ │ └── MainActivity.java │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── preview ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── 10.png ├── 11.png └── 12.png ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── AppDelegate.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── 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-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── main.m │ ├── AppDelegate.m │ ├── Info.plist │ └── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard ├── Runner.xcworkspace │ └── contents.xcworkspacedata ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj └── Podfile ├── .metadata ├── lib ├── util │ ├── request.dart │ └── api.dart ├── assets │ └── math.json └── main.dart ├── LICENSE ├── test └── widget_test.dart ├── .gitignore ├── pubspec.yaml ├── pubspec.lock └── README.md /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /preview/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/1.png -------------------------------------------------------------------------------- /preview/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/2.png -------------------------------------------------------------------------------- /preview/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/3.png -------------------------------------------------------------------------------- /preview/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/4.png -------------------------------------------------------------------------------- /preview/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/5.png -------------------------------------------------------------------------------- /preview/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/6.png -------------------------------------------------------------------------------- /preview/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/7.png -------------------------------------------------------------------------------- /preview/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/8.png -------------------------------------------------------------------------------- /preview/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/9.png -------------------------------------------------------------------------------- /android/key.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/android/key.jks -------------------------------------------------------------------------------- /preview/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/10.png -------------------------------------------------------------------------------- /preview/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/11.png -------------------------------------------------------------------------------- /preview/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/preview/12.png -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/key.properties: -------------------------------------------------------------------------------- 1 | storePassword=123456789 2 | keyPassword=123456789 3 | keyAlias=key 4 | storeFile=/Users/shuirong/code/TodayX/android/key.jks -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/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/shuiRong/TodayX/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shuiRong/TodayX/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | #Flutter Wrapper 2 | -keep class io.flutter.app.** { *; } 3 | -keep class io.flutter.plugin.** { *; } 4 | -keep class io.flutter.util.** { *; } 5 | -keep class io.flutter.view.** { *; } 6 | -keep class io.flutter.** { *; } 7 | -keep class io.flutter.plugins.** { *; } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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: 8661d8aecd626f7f57ccbcb735553edc05a2e713 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/example/flutterdemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.flutterdemo; 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/util/request.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart' as http; 2 | 3 | class Request { 4 | // get请求的封装,传入的两个参数分别是请求URL和请求参数,请求参数以map的形式传入,会在方法体中自动拼接到URL后面 5 | static Future get(String url, {Map params}) async { 6 | if (params != null && params.isNotEmpty) { 7 | // 如果参数不为空,则将参数拼接到URL后面 8 | StringBuffer stringBuffer = StringBuffer("?"); 9 | params.forEach((key, value) { 10 | stringBuffer.write("$key" + "=" + "$value" + "&"); 11 | }); 12 | String paramStr = stringBuffer.toString(); 13 | paramStr = paramStr.substring(0, paramStr.length - 1); 14 | url += paramStr; 15 | } 16 | http.Response res = await http.get(url); 17 | return res.body; 18 | } 19 | 20 | // post请求 21 | static Future post(String url, {Map params}) async { 22 | http.Response res = await http.post(url, body: params); 23 | return res.body; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 https://github.com/shuiRong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /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:flutterdemo/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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /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 | flutterdemo 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/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 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 10 | 14 | 21 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 37 | # referring to absolute paths on developers' machines. 38 | system('rm -rf .symlinks') 39 | system('mkdir -p .symlinks/plugins') 40 | 41 | # Flutter Pods 42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 43 | if generated_xcode_build_settings.empty? 44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 45 | end 46 | generated_xcode_build_settings.map { |p| 47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 48 | symlink = File.join('.symlinks', 'flutter') 49 | File.symlink(File.dirname(p[:path]), symlink) 50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 51 | end 52 | } 53 | 54 | # Plugin Pods 55 | plugin_pods = parse_KV_file('../.flutter-plugins') 56 | plugin_pods.map { |p| 57 | symlink = File.join('.symlinks', 'plugins', p[:name]) 58 | File.symlink(p[:path], symlink) 59 | pod p[:name], :path => File.join(symlink, 'ios') 60 | } 61 | end 62 | 63 | post_install do |installer| 64 | installer.pods_project.targets.each do |target| 65 | target.build_configurations.each do |config| 66 | config.build_settings['ENABLE_BITCODE'] = 'NO' 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | 28 | def keystoreProperties = new Properties() 29 | def keystorePropertiesFile = rootProject.file('key.properties') 30 | if (keystorePropertiesFile.exists()) { 31 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 32 | } 33 | 34 | android { 35 | compileSdkVersion 28 36 | 37 | lintOptions { 38 | disable 'InvalidPackage' 39 | } 40 | 41 | defaultConfig { 42 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 43 | applicationId "com.example.flutterdemo" 44 | minSdkVersion 16 45 | targetSdkVersion 28 46 | versionCode flutterVersionCode.toInteger() 47 | versionName flutterVersionName 48 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 49 | } 50 | 51 | signingConfigs { 52 | release { 53 | keyAlias keystoreProperties['keyAlias'] 54 | keyPassword keystoreProperties['keyPassword'] 55 | storeFile file(keystoreProperties['storeFile']) 56 | storePassword keystoreProperties['storePassword'] 57 | } 58 | } 59 | buildTypes { 60 | release { 61 | signingConfig signingConfigs.release 62 | 63 | minifyEnabled false 64 | useProguard true 65 | 66 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 67 | } 68 | } 69 | } 70 | 71 | flutter { 72 | source '../..' 73 | } 74 | 75 | dependencies { 76 | testImplementation 'junit:junit:4.12' 77 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 78 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 79 | } 80 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutterdemo 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.2.2 <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | http: ^0.12.0+2 23 | flutter_easyrefresh: ^1.2.7 24 | audioplayers: ^0.12.0 25 | auto_size_text: ^1.1.2 26 | flutter_icons: ^0.1.4 27 | url_launcher: ^5.0.2 28 | 29 | # The following adds the Cupertino Icons font to your application. 30 | # Use with the CupertinoIcons class for iOS style icons. 31 | cupertino_icons: ^0.1.2 32 | 33 | dev_dependencies: 34 | flutter_test: 35 | sdk: flutter 36 | 37 | 38 | # For information on the generic Dart part of this file, see the 39 | # following page: https://www.dartlang.org/tools/pub/pubspec 40 | 41 | # The following section is specific to Flutter. 42 | flutter: 43 | 44 | # The following line ensures that the Material Icons font is 45 | # included with your application, so that you can use the icons in 46 | # the material Icons class. 47 | uses-material-design: true 48 | 49 | # To add assets to your application, add an assets section, like this: 50 | assets: 51 | - ./lib/assets/math.json 52 | - ./lib/assets/chemical.json 53 | 54 | # An image asset can refer to one or more resolution-specific "variants", see 55 | # https://flutter.io/assets-and-images/#resolution-aware. 56 | 57 | # For details regarding adding assets from package dependencies, see 58 | # https://flutter.io/assets-and-images/#from-packages 59 | 60 | # To add custom fonts to your application, add a fonts section here, 61 | # in this "flutter" section. Each entry in this list should have a 62 | # "family" key with the font family name, and a "fonts" key with a 63 | # list giving the asset and other descriptors for the font. For 64 | # example: 65 | # fonts: 66 | # - family: Schyler 67 | # fonts: 68 | # - asset: fonts/Schyler-Regular.ttf 69 | # - asset: fonts/Schyler-Italic.ttf 70 | # style: italic 71 | # - family: Trajan Pro 72 | # fonts: 73 | # - asset: fonts/TrajanPro.ttf 74 | # - asset: fonts/TrajanPro_Bold.ttf 75 | # weight: 700 76 | # 77 | # For details regarding fonts from package dependencies, 78 | # see https://flutter.io/custom-fonts/#from-packages 79 | -------------------------------------------------------------------------------- /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.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 | -------------------------------------------------------------------------------- /lib/util/api.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:math'; 3 | import './request.dart'; 4 | import 'dart:convert'; 5 | 6 | class API { 7 | static Future poetry() async { 8 | var url = "https://api.gushi.ci/all.json"; 9 | String body = await Request.get(url); 10 | var obj = json.decode(body); 11 | return obj; 12 | } 13 | 14 | static Future sentence() async { 15 | var url = "https://v1.hitokoto.cn/"; 16 | String body = await Request.get(url); 17 | try { 18 | var obj = json.decode(body); 19 | var hitokoto = obj['hitokoto']; 20 | var from = obj['from']; 21 | 22 | return {'hitokoto': hitokoto, 'from': '—— ' + from}; 23 | } catch (e) { 24 | print('接口又返回html而不是json了'); 25 | return {'hitokoto': '', 'from': ''}; 26 | } 27 | } 28 | 29 | static Future picture() async { 30 | var url = "https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1"; 31 | String body = await Request.get(url); 32 | var obj = json.decode(body); 33 | var image = obj['images'][0]; 34 | 35 | return image; 36 | } 37 | 38 | static Future music() async { 39 | var url = "https://music.aityp.com/playlist/detail?id=145787433"; 40 | String body = await Request.get(url); 41 | var obj = json.decode(body); 42 | var tracks = obj['playlist']['tracks']; 43 | 44 | var randomIndex = new Random().nextInt(tracks.length); 45 | var song = tracks[randomIndex]; 46 | var songId = song['id']; 47 | 48 | var musicUrl = await getMusicUrl(songId); 49 | 50 | return { 51 | 'url': musicUrl, 52 | 'author': song['ar'][0]['name'], 53 | 'picUrl': song['al']['picUrl'], 54 | 'name': song['name'] 55 | }; 56 | } 57 | 58 | static Future getMusicUrl(id) async { 59 | var url = "https://music.aityp.com/song/url?id=$id"; 60 | String body = await Request.get(url); 61 | var obj = json.decode(body); 62 | var musicUrl = obj['data'][0]['url']; 63 | 64 | return musicUrl; 65 | } 66 | 67 | static Future musicComment() async { 68 | var url = "https://api.comments.hk/"; 69 | String body = await Request.get(url); 70 | var obj = json.decode(body); 71 | 72 | return { 73 | 'comment': obj['comment_content'], 74 | 'nickname': obj['comment_nickname'], 75 | 'title': obj['title'], 76 | 'author': obj['author'] 77 | }; 78 | } 79 | 80 | static Future randomColor() async { 81 | String url = "https://randoma11y.com/stats"; 82 | String body = await Request.get(url); 83 | Map obj = json.decode(body); 84 | int index = new Random().nextInt(20); 85 | Map color = obj['most_active_20'][index]; 86 | 87 | String colorOne = color['color_one'].toUpperCase(); 88 | String colorTwo = color['color_two'].toUpperCase(); 89 | 90 | return { 91 | 'color_one': '0xff' + colorOne.replaceAll(new RegExp('#'), ''), 92 | 'color_two': '0xff' + colorTwo.replaceAll(new RegExp('#'), ''), 93 | 'color_one_origin': colorOne, 94 | 'color_two_origin': colorTwo, 95 | }; 96 | } 97 | 98 | static Future repo() async { 99 | String url = "https://github-trending-api.now.sh/repositories"; 100 | String body = await Request.get(url); 101 | List list = json.decode(body); 102 | int index = new Random().nextInt(25); 103 | Map repo = list[index]; 104 | 105 | return { 106 | ...repo, 107 | 'name': repo['author'] + ' / ' + repo['name'], 108 | 'stars': repo['stars'].toString(), 109 | 'forks': repo['forks'].toString() 110 | }; 111 | } 112 | 113 | static Future zhihuDaily() async { 114 | String url = "https://news-at.zhihu.com/api/4/news/latest"; 115 | String body = await Request.get(url); 116 | Map data = json.decode(body); 117 | List stories = data['stories']; 118 | stories.addAll(data['top_stories']); 119 | int index = new Random().nextInt(8); 120 | Map repo = stories[index]; 121 | 122 | return repo; 123 | } 124 | 125 | static Future todayInHistory() async { 126 | String url = "https://api.ooopn.com/history/api.php?type=json"; 127 | String body = await Request.get(url); 128 | Map data = json.decode(body); 129 | List content = data['content']; 130 | int index = new Random().nextInt(content.length); 131 | 132 | return {'day': data['day'], 'content': content[index]}; 133 | } 134 | 135 | static Future oneArticle() async { 136 | var url = "https://interface.meiriyiwen.com/article/today?dev=1"; 137 | String body = await Request.get(url); 138 | var obj = json.decode(body); 139 | String content = obj['data']['content']; 140 | content = content.replaceAll('\<\/p\>',''); 141 | content = content.replaceFirst('\',' '); 142 | content = content.replaceAll('\','\n '); 143 | return { 144 | 'author': obj['data']['author'], 145 | 'title': obj['data']['title'], 146 | 'content': content 147 | }; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /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.1.0" 11 | audioplayers: 12 | dependency: "direct main" 13 | description: 14 | name: audioplayers 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "0.12.0" 18 | auto_size_text: 19 | dependency: "direct main" 20 | description: 21 | name: auto_size_text 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "1.1.2" 25 | boolean_selector: 26 | dependency: transitive 27 | description: 28 | name: boolean_selector 29 | url: "https://pub.flutter-io.cn" 30 | source: hosted 31 | version: "1.0.4" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "1.1.2" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "1.14.11" 46 | convert: 47 | dependency: transitive 48 | description: 49 | name: convert 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "2.1.1" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "2.0.6" 60 | cupertino_icons: 61 | dependency: "direct main" 62 | description: 63 | name: cupertino_icons 64 | url: "https://pub.flutter-io.cn" 65 | source: hosted 66 | version: "0.1.2" 67 | flutter: 68 | dependency: "direct main" 69 | description: flutter 70 | source: sdk 71 | version: "0.0.0" 72 | flutter_easyrefresh: 73 | dependency: "direct main" 74 | description: 75 | name: flutter_easyrefresh 76 | url: "https://pub.flutter-io.cn" 77 | source: hosted 78 | version: "1.2.7" 79 | flutter_icons: 80 | dependency: "direct main" 81 | description: 82 | name: flutter_icons 83 | url: "https://pub.flutter-io.cn" 84 | source: hosted 85 | version: "0.1.4" 86 | flutter_test: 87 | dependency: "direct dev" 88 | description: flutter 89 | source: sdk 90 | version: "0.0.0" 91 | http: 92 | dependency: "direct main" 93 | description: 94 | name: http 95 | url: "https://pub.flutter-io.cn" 96 | source: hosted 97 | version: "0.12.0+2" 98 | http_parser: 99 | dependency: transitive 100 | description: 101 | name: http_parser 102 | url: "https://pub.flutter-io.cn" 103 | source: hosted 104 | version: "3.1.3" 105 | matcher: 106 | dependency: transitive 107 | description: 108 | name: matcher 109 | url: "https://pub.flutter-io.cn" 110 | source: hosted 111 | version: "0.12.5" 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 | path: 120 | dependency: transitive 121 | description: 122 | name: path 123 | url: "https://pub.flutter-io.cn" 124 | source: hosted 125 | version: "1.6.2" 126 | path_provider: 127 | dependency: transitive 128 | description: 129 | name: path_provider 130 | url: "https://pub.flutter-io.cn" 131 | source: hosted 132 | version: "1.1.0" 133 | pedantic: 134 | dependency: transitive 135 | description: 136 | name: pedantic 137 | url: "https://pub.flutter-io.cn" 138 | source: hosted 139 | version: "1.5.0" 140 | quiver: 141 | dependency: transitive 142 | description: 143 | name: quiver 144 | url: "https://pub.flutter-io.cn" 145 | source: hosted 146 | version: "2.0.2" 147 | sky_engine: 148 | dependency: transitive 149 | description: flutter 150 | source: sdk 151 | version: "0.0.99" 152 | source_span: 153 | dependency: transitive 154 | description: 155 | name: source_span 156 | url: "https://pub.flutter-io.cn" 157 | source: hosted 158 | version: "1.5.5" 159 | stack_trace: 160 | dependency: transitive 161 | description: 162 | name: stack_trace 163 | url: "https://pub.flutter-io.cn" 164 | source: hosted 165 | version: "1.9.3" 166 | stream_channel: 167 | dependency: transitive 168 | description: 169 | name: stream_channel 170 | url: "https://pub.flutter-io.cn" 171 | source: hosted 172 | version: "2.0.0" 173 | string_scanner: 174 | dependency: transitive 175 | description: 176 | name: string_scanner 177 | url: "https://pub.flutter-io.cn" 178 | source: hosted 179 | version: "1.0.4" 180 | term_glyph: 181 | dependency: transitive 182 | description: 183 | name: term_glyph 184 | url: "https://pub.flutter-io.cn" 185 | source: hosted 186 | version: "1.1.0" 187 | test_api: 188 | dependency: transitive 189 | description: 190 | name: test_api 191 | url: "https://pub.flutter-io.cn" 192 | source: hosted 193 | version: "0.2.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 | url_launcher: 202 | dependency: "direct main" 203 | description: 204 | name: url_launcher 205 | url: "https://pub.flutter-io.cn" 206 | source: hosted 207 | version: "5.0.2" 208 | uuid: 209 | dependency: transitive 210 | description: 211 | name: uuid 212 | url: "https://pub.flutter-io.cn" 213 | source: hosted 214 | version: "2.0.1" 215 | vector_math: 216 | dependency: transitive 217 | description: 218 | name: vector_math 219 | url: "https://pub.flutter-io.cn" 220 | source: hosted 221 | version: "2.0.8" 222 | sdks: 223 | dart: ">=2.2.2 <3.0.0" 224 | flutter: ">=0.5.6 <2.0.0" 225 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 今日份的X 2 | 3 | > 这是一个`Flutter`写的**一个无聊的App** 4 | > 5 | > **每天推荐一个不同的:图片、诗歌、名言、音乐、乐评、高等数学、两种配色、化学方程式、Github Repo、知乎问题、文章。** 6 | > 7 | > (P.S. 除图片来自Bing首页,每天仅有一张外,其他页面支持下拉刷新来更新内容) 8 | 9 | **[下载APK](https://github.com/shuiRong/TodayX/releases)** 10 | 11 | 12 | 13 | #### 效果预览 14 | 15 | ------ 16 | 17 | | ![TodayX](./preview/1.png) | ![TodayX](./preview/2.png) | ![TodayX](./preview/3.png) | 18 | | --------------------------- | --------------------------- | --------------------------- | 19 | | ![TodayX](./preview/4.png) | ![TodayX](./preview/5.png) | ![TodayX](./preview/6.png) | 20 | | ![TodayX](./preview/7.png) | ![TodayX](./preview/8.png) | ![TodayX](./preview/9.png) | 21 | | ![TodayX](./preview/10.png) | ![TodayX](./preview/11.png) | ![TodayX](./preview/12.png) | 22 | 23 | 24 | 25 | > **Flutter初试感受**:去玩`Swift`了 :p 26 | 27 | #### 如何运行: 28 | 29 | --- 30 | 31 | 首先确保你本地有 Flutter 项目所需环境,官方文档 [英文教程](https://flutter.dev/docs/get-started/install) [中文文档](https://flutter-io.cn/docs) 32 | 33 | **下载项目:** 34 | 35 | ```bash 36 | git clone https://github.com/shuiRong/TodayX 37 | cd ./TodayX 38 | ``` 39 | 40 | 41 | 42 | 运行项目前需要通过 USB 将手机连接到电脑上或者启动模拟器,遵循官方教程即可。 43 | 44 | 然后**运行项目**: 45 | 46 | (如果你使用 Visual Studio Code 来开发,也可以不通过下述命令行,而是通过全程通过VSC来操作:请参看[第2、3小节](https://flutter-io.cn/docs/get-started/editor?tab=vscode)) 47 | 48 | ```bash 49 | // 安装项目依赖 50 | flutter packages get 51 | // 运行项目 52 | flutter run 53 | ``` 54 | 55 | 56 | 57 | #### 项目中用到的第三方数据 58 | 59 | --- 60 | 61 | 感谢作者 62 | 63 | 64 | 65 | * 诗歌:`https://api.gushi.ci/all.json` 66 | 67 | ```bash 68 | // 20190526231929 69 | { 70 | "content": "墉集欺猫鼠,林藏逐雀鹯。", 71 | "origin": "中秋咏怀借杜子美秋日述怀一百韵和寄柳州假鸣桑先生", 72 | "author": "徐威", 73 | "category": "古诗文-动物-写猫" 74 | } 75 | ``` 76 | 77 | * 名言:`https://v1.hitokoto.cn/` 78 | 79 | ```bash 80 | // 20190526232311 81 | { 82 | "id": 14, 83 | "hitokoto": "用你的笑容去改变这个世界,别让这个世界改变了你的笑容。", 84 | "type": "a", 85 | "from": "网络", 86 | "creator": "酱七", 87 | "created_at": "1468605909" 88 | } 89 | ``` 90 | 91 | * Bing首页图:`https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1` 92 | 93 | ```bash 94 | // 20190526232348 95 | { 96 | "images": [ 97 | { 98 | "startdate": "20190525", 99 | "fullstartdate": "201905251600", 100 | "enddate": "20190526", 101 | "url": "/th?id=OHR.MarathonduMont_ZH-CN5049722437_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp", 102 | "urlbase": "/th?id=OHR.MarathonduMont_ZH-CN5049722437", 103 | "copyright": "圣米歇尔山 (© Leroy Francis/Getty Images)", 104 | "copyrightlink": "http://www.bing.com/search?q=%E5%9C%A3%E7%B1%B3%E6%AD%87%E5%B0%94%E5%B1%B1&form=hpcapt&mkt=zh-cn", 105 | "title": "", 106 | "quiz": "/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20190525_MarathonduMont%22&FORM=HPQUIZ", 107 | "wp": true, 108 | "hsh": "02a3db999f76ec114c45de97cecc30ac", 109 | "drk": 1, 110 | "top": 1, 111 | "bot": 1, 112 | "hs": [ 113 | ] 114 | } 115 | ], 116 | "tooltips": { 117 | "loading": "正在加载...", 118 | "previous": "上一个图像", 119 | "next": "下一个图像", 120 | "walle": "此图片不能下载用作壁纸。", 121 | "walls": "下载今日美图。仅限用作桌面壁纸。" 122 | } 123 | } 124 | ``` 125 | 126 | * 音乐:`https://music.aityp.com/playlist/detail?id=145787433` 127 | 128 | ``` 129 | // 详细接口文档见:https://binaryify.github.io/NeteaseCloudMusicApi 130 | 内容过多不便展示 131 | ``` 132 | 133 | * 网易云评论:`https://api.comments.hk/` 134 | 135 | ```bash 136 | // 20190526232507 137 | { 138 | "song_id": 480426313, 139 | "title": "There For You", 140 | "images": "https://p2.music.126.net/E_ffmvXrVZoTugVf_Zf4Cg==/18520173860179248.jpg", 141 | "author": "Martin Garrix", 142 | "album": "There For You", 143 | "description": "歌手:Martin Garrix。所属专辑:There For You。", 144 | "mp3_url": "https://api.comments.hk/music/480426313", 145 | "pub_date": "2017-05-25 16:00:00", 146 | "comment_id": 393094070, 147 | "comment_user_id": 267009137, 148 | "comment_nickname": "我不吃鱼肉", 149 | "comment_avatar_url": "https://p1.music.126.net/HC5zku5foEI_rIP9YShyoQ==/109951164014518098.jpg", 150 | "comment_liked_count": 25271, 151 | "comment_content": "恭喜\"小马戳\"组合的新单出世!!好期待他们的下一次合作 也希望马丁不要弯不要弯不要弯啊哈哈哈哈哈哈[爱心][爱心][爱心][爱心]", 152 | "comment_pub_date": "2017-05-25 16:01:38" 153 | } 154 | ``` 155 | 156 | * 随机配色:`https://randoma11y.com/stats` 157 | 158 | ``` 159 | 内容过多不便展示 160 | ``` 161 | 162 | * Github Trending:`https://github-trending-api.now.sh/repositories` 163 | 164 | ``` 165 | 内容过多不便展示 166 | ``` 167 | 168 | * 知乎日报:`https://news-at.zhihu.com/api/4/news/latest` 169 | 170 | ```bash 171 | // 20190526232635 172 | { 173 | "date": "20190526", 174 | "stories": [ 175 | { 176 | "images": [ 177 | "https://pic2.zhimg.com/v2-58b5abf70967054a9a057d4f1da8f811.jpg" 178 | ], 179 | "type": 0, 180 | "id": 9711762, 181 | "ga_prefix": "052622", 182 | "title": "小事 · 你会付出多少去挽救父母的生命?" 183 | } 184 | ... 185 | ], 186 | "top_stories": [ 187 | { 188 | "image": "https://pic2.zhimg.com/v2-0dc73b026624fc19637c5cb25ff679a9.jpg", 189 | "type": 0, 190 | "id": 9711735, 191 | "ga_prefix": "052507", 192 | "title": "为什么牛奶卖不完,宁可倒掉也不免费送人?" 193 | } 194 | ... 195 | ] 196 | } 197 | ``` 198 | 199 | * 历史上的今天:`https://api.ooopn.com/history/api.php?type=json` 200 | 201 | ```bash 202 | // 20190526232721 203 | { 204 | "code": "200", 205 | "day": "2019年05月26日", 206 | "content": [ 207 | "刘宋顺帝刘准让帝位于萧道成", 208 | "爱德华波特亚历山大出生", 209 | "第一次鸦片战争英军首次进攻广州城", 210 | "清朝将领和春逝世", 211 | "英国兼英属自治领皇后玛丽皇后出生", 212 | "美国记者查尔斯道创造的股票指数道琼斯指数首次发布", 213 | "俄国沙皇尼古拉二世在圣彼得堡登基", 214 | "美国影星约翰韦恩出生", 215 | "曼联足球俱乐部主帅马特巴斯比出生", 216 | "美国记者雅各布里斯逝世", 217 | "日本军将领白川义则逝世", 218 | "中国首次成功发射地对地中程导弹", 219 | "日本漫画家和月伸宏出生", 220 | "德国哲学家马丁海德格尔逝世", 221 | "京剧艺术家孟小冬逝世" 222 | ] 223 | } 224 | ``` 225 | 226 | * 每日一文:`https://interface.meiriyiwen.com/article/today?dev=1` 227 | 228 | ```json 229 | { 230 | "data": { 231 | "date": { 232 | "curr": "20170217", 233 | "prev": "20170216", 234 | "next": "20170218" 235 | }, 236 | "author": "契诃夫", 237 | "title": "散戏之后", 238 | "digest": "娜卡.戴莱尼同她母亲从戏园里回来,那天,戏园里演了一出戏名叫《叶甫盖尼.奥涅金》的戏剧。她跑到自己的屋子里去,很快脱去衣服,散开发辫,穿了一", 239 | "content": "

娜卡.戴莱尼同她母亲从戏园里回来,那天,戏园里演了一出戏名叫《叶甫盖尼.奥涅金》的戏剧。她跑到自己的屋子里去,很快脱去衣服,散开发辫,穿了一条短裙和衬衣,坐在桌子旁边,想仿照达吉雅娜的笔调写一封信。

她写道——

“我爱你,可是你不爱我,不爱我!”

她写着写着就笑了起来。

她那时候不过十六岁,她还没有爱上谁,却知道军官戈尔南和学生格罗兹杰夫都很爱她。可自从那天晚上看完戏以后,她对于他们的爱情忽然生出疑惑。做不被人爱的、不幸的人——那多有趣啊!她觉得一个人爱得深,而另一个却很冷淡,是一件很有意思,很动人,并且含着诗味的事情。

在那出戏里,奥涅金以绝不爱人为乐趣,达吉雅娜却老迷着他,因为她很爱他,假如他们能够互相恋爱,享受幸福,那这件事情也就枯涩无味了。

娜卡想起军官戈尔南来,就往下写道:

“你也不用在我面前坚持说你爱我,我也不能够信你。你很聪明,很有学问,很严正;你是绝对的天才,光明的未来正等着你,我却是一个低微的不幸女人,并且你也深知我只会成为你生活上的阻碍。虽然你还在注意我,想着用你自己的理想来迎合我,然而这一定是错误的,现在你一定已经后悔,并且自问道:我为什么要同那姑娘亲热呢?可不过因为你这个人太善良,所以你还不愿意承认呢!……”

娜卡写到这里,觉得自己身世飘零,禁不住就流下泪来,继续写道:

“我很不忍离开我那亲爱的母亲和兄弟,要不然我就披上袈裟,只身遁去,到那人迹不到的地方去另讨生活。那你也就成了自由的人,可以另爱别人了。唉,我还不如一死呢!”

娜卡含着一泡眼泪,也辨别不出写的是什么,只看见桌子上,地板上和顶棚上,一条一条的彩虹不住地在那里摇荡着,仿佛是从三棱镜里看见的一样。她也写不上来,就往椅子背上一靠,想起戈尔南来。

男子真有趣,却真能撩人呀!娜卡想起他们一块儿谈论音乐的时候,他那又温柔,又口吃,并且时常错误的言辞是何等的有趣!他也总是竭力地使自己的嗓音不流露出激烈的声调。在社交场合,即使有冷静的头脑和骄傲的习气,受过高等教育,有着道德高尚的表征,自己的嗜好也不得不收藏在一边。戈尔南也知道这样藏着,可是终有时要流露出来,所以大家都知道他对于音乐十分嗜好。有人不免要不断地议论音乐,或者有不了解音乐的人偏要发出那可笑的言论,他却还保持着常态,好像恐惧胆小似的一句话也不说。他钢琴弹得很好,和真正的钢琴家弹的一样。假如他不做军官,他一定会成为一位有名的音乐家呢。

眼睛里的泪也干了。娜卡回忆起戈尔南曾在音乐会上和她讲过爱情,后来在穿衣架旁边也讲过一次,那时候正徐徐地吹着微风,她又往下继续写道:

“我很高兴你跟格罗兹杰夫认识了,他是一个很聪明的人,你一定也爱他,昨天他在我家里,坐到两点钟才走。那天晚上我们都很快乐,可惜你却没有来。他讲了许多有趣的话。”

娜卡手按在桌上,头枕着手,她的头发遮没了那封信。她记得学生格罗兹杰夫也很爱她,他也应当有一封和戈尔南同样的信才好。不过要怎样给格罗兹杰夫写信呢?不知什么缘故她的胸中忽然掀起了一股的欢乐:起初这股欢乐还小,仿佛在胸问摇荡着一个小橡皮球儿一样,然后那快乐就慢慢地扩大,竟像波浪起伏一样。娜卡也忘记想戈尔南和格罗兹杰夫,因为她的思想已经错乱,可是那快乐却越发地增长起来,从胸脯达到手足四肢,欢乐好像轻微的冷风似的吹进头脑里来,掠着头发过去。她耸着肩膀不住地微笑,连桌子和灯上的玻璃都慢慢地颤动起来,眼泪也进了出来,落在那张信纸上面。她的笑好久没能止住,她想要停止来着。为了表明自己不是无端发笑,她打算赶紧想出一件可笑的事情来。她觉得自己笑得快透不过气来了,赶紧说道:

“这只小狗真可笑!这只小狗真可笑!”

她记起,昨天喝茶后格罗兹杰夫同小狗马克新闹着玩,之后他就讲起一只聪明小狗的故事来:

那只小狗在院子里追赶乌鸦,乌鸦却回头看着它说道:

“哼,你这个坏蛋!”

小狗并不知道那被他追赶的乌鸦是很有学问的,一下子就呆住了,疑惑了好一会儿,然后就狂吠起来。

想到这里,娜卡决然道:“不,我还是爱格罗兹杰夫的好。”说完这话,她立刻把刚才那封信撕掉了。

她开始想着那学生的爱情和自己的爱情,可不料她脑筋里的念头总是摇摆不定。于是她就乱想起来:母亲、街市、铅笔、风琴……她想得很高兴,她认为世界上所有的东西都是好的,美妙的,并且她的欢乐还告诉她说这并不算稀奇,还有更好的在后面。很快春天过去,夏天到来,她就可以同母亲到戈尔比基去,戈尔南也告假往那里去,同她一块儿在花园里闲逛,顺便谈谈心事。格罗兹杰夫也跑来同她一起打棒球和网球,给她讲可笑或奇异的事情。他十分喜欢花园、黑夜、青天和繁星。她重新又耸着肩笑起来,她仿佛觉得室内一阵阵的花香从窗外透将进来,沁人人的心脾。

她走到她前,坐了下来,也不知道那使她沉溺的欢乐是从哪里来的,她目不转睛地瞧着挂在床背后面的神像,喃喃地说道:“上帝!上帝!上帝!”

", 240 | "wc": 1963 241 | } 242 | } 243 | ``` 244 | > 解析: 245 | > 246 | > date:日期 247 | > curr:今日日期,yyyyMMdd 格式 248 | > prev:昨日日期,yyyyMMdd 格式 249 | > next:明日日期,yyyyMMdd 格式 250 | > author:作者 251 | > title:标题 252 | > digest:首段 253 | > content:正文内容 254 | > wc:??? 255 | -------------------------------------------------------------------------------- /lib/assets/math.json: -------------------------------------------------------------------------------- 1 | { 2 | "0":"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", 3 | "1":"iVBORw0KGgoAAAANSUhEUgAAAGoAAAA0CAYAAABipa0QAAAFn0lEQVR42u2b7yutWRTH7z/hhbwQifyI5FcRkiTmksyV5AUSSZIoIimSJFJEzZWSUnMjUgpJd5QkSVKSIs2NNLdorjRX3uzps2vrOc+c48c5x3FG68XqnGefvZ+99/qu9V1r7c2H+/v7DyL+L6IEAUpEgBKgRAQoEQFKgBIRoEQEKAFKRIASeW2gtre31adfP6mysjL17c9vSpTqh0AdHx+rkJAQFRAQoKWmpkaA8keg2tvb1dTUlMrOztZADQ0NCVD+CFRWVpa6vr5WP//5qfAuUaifAhUeHq5OTk48BujH3z8Uwve7uzsB3JtA4UXQ3dbWlseK7e/vVzExMWp5eVnx/T0oFgP2Jsu4PfDq6koDtbCw4JXFDA8Pq/T0dPVePIq9REZGvj1QpOIANTEx4ZXFTE5OqqioqHdDexcXF6qkpOTtgTo6OtJADQwMeLyYvb09NTc3py0Q+nsPQH35/YtXadwj5QJUR0fHsxdzc3Pzn754JAUz3+vq6nS6/9z3kXE+NR+x9LE4a6Xy29vbZ80NPbvqa9obGhrUxsaGeiqJenWgSCIAqr6+Xj2VdPT29upkgeKYE4zHlPecDJE5Q0ND9fvi4uIU1mvts7KyouNdcHCwCgoK0hR0dnamrMqsrKxUYWFhKj4+XsfZ5ORkNTs76/CenZ0dvd7R0dGHjBQvSUhI0OMODg4e+o+Pj+u1sCZoPCMjQ4OJsRB/MzMzH/ru7++roqIiFRERoZqamtSrArW+vq6BYsOu+rDQgoICfWJxfn6uAUpLS1Mo0t1MMycnR1EWoETaqqqqNBiHh4f6+Y+vX/UzxsEzyucZ5RqP7uvrUxTrKN4Az17sQBUWFqrAwEANCh5HP5Rs9y7ay8vL1eXlpe6Xm5ur12n0ZE5vxsbG9N67urpenDS5DRSxhMmxOFd9WltbVW1trYMlY3Xupq3QInN2d3cra6zEeo0CKcLxFKsi8CjGDQ4O6rbi4mLV0tKirAaQkpLiNIMlaUpKStIGhtLtvwM677O2see2tjaHNmI5xlJaWqp8GqMWFxf15k18scvp6ammO8PZWC6LbG5udpv2Kioq9Jx2qrNnoijVGcDQDc/Gg6CjmZmZJ6mYWAhYzhIq9ognWdsxHGegd3Z2up0luw3U0tKS3qzdmoz09PRoSoCKWGBsbKx2eU8yH2j0sZLAxE3ijbV9bW1Nt6NAnolX5nwSgdqceYuV3qAv+ykMRsc+rW2bm5uaLr//9d2p90HVPgUKrmWTrmoFvIdYkpeXpzfjjaMm41HEA7si+SQO8juJhtVLMBbrOH5jzOrqqvZyYhhAuLqmoXRITU1Vn3/77PB7YmKiQ0LBezFcu6EYwaONsfgMKGOlrmIUlAg92k8zsCp35ySzYk4UC/2hGBKE6Ojoh2QCOqOPtR5DwVbKzM/Pd4hzKNscYTmjPbwAj8NQrL+RVVpLBJiDcsUal42QSKCPj798fFirT4DCxR/L+khpqYugAOITi8QqX1InOauLCPqGslAUCrYqEIUCJHOhEAQLhzZNH4BiLMojvtCH/pwmmD7V1dVqZGREx1SoEkCYC2bgfYzjEyNgHP2mp6f1nklUmMPMjecaAyXB4r182mnzVYDa3d3VynJmPYYGKPqgP+oFrJLg6yn9QU/QlamhsGJ7IY1nQDEGSJRi7YMS8U4USoYISPaSgTHELlMGmGyRvuzdxGlOU6DA+fn5h0KX+Edmy1rZe2NjowMN08bcL0nRPT5CYmFyDeHH1xy4O0B5km6L+PA+igpfFOnnN7zwu6e1kYgPgCKjkT9o+R8ARfbkSbot4iOgqKH4A0xRpJ8BxckCdQT1BZdiFJqe3C2JvBJQ5tDTiPWqQMSPgMJ7OBWgsuYy0NnVuoj8N4cAJSJAiQhQApSIACUiQAlQIgKUiAAlQIm8ifwLH/dH2g1cPkgAAAAASUVORK5CYII=", 4 | "2":"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", 5 | "3":"iVBORw0KGgoAAAANSUhEUgAAAGgAAAAtCAYAAABCiS5+AAAEuklEQVR42u2bX0RteRTHe4goSaKSklJRUpKSmksPkUjSnUQivRWlSBRJkkRRzE2SSOaSJCIlvUSSuZLMfUkPJXMlmUsyNzE3a+bzY2ffM/vU+Tft/bAelpy991n7t9fn91vru377FCUiUWreNQ2CAlJTQApITQGpKSAFpOY9QEtLS/Lup3fS2dkp3//+LhpUDwFaXl7+10PUsy0uLoYF6MsfX+T8/FwhRwpQbW2tfPz1o6SmpkpsbKwcHh6GFFygFBYWSnp6usTHx8vg4KBCChfQt7++SXFxsQnk/f29MPtD9TU6Oipf//xqvn90dCQxMTGCTwUUBqDj42PJyMiIWBAfHx9lf39f2tvbpa6uTuGEC2h7e9uko0gNZG5uThITE02qpLa9dO3t7a2rAC8uLt6sVob8xdXVVSMMSHWRHNDe3p5JcVbKs6fUmZkZKSoqkpKSElcBUS+Tk5O9DQh5DaD/Yyaxkm5ubn7we3p6akQE97Rqn1vG2BBIngb04ZcPJlgU9UgMhB4KW1tbc1xB2MbGhicAoVwRNp4GNDk5aYK1tbUV9ECfnp4EUWB9Li0tlejoaOOPv/Pz8+Iv/fkDZE+1+A61aX4pZVtj7ujoMIImVD9vAogZRLBWVlb8DuTTb5+kvr5epqenxQLD97KysiQzM1M+//5Zgq1PvoCYIA0NDRIXF2fSYltbmxEaCQkJfhtnWoKuri5paWl5Ps/Kpb6lpKQI6dt+/ezsrFGsiCImD9cBK1g/bwqIZpJgob78XVNdXW1WBDDu7u6MhKaWhCMgfAFlZ2c/72SMjIyY+zC7+ZyUlOR4r+HhYZNGgUq7MD4+7jjRmFCMmQmAcsR3RUWFlJeXSzB+XAHU19dngjA1NSWvbd/k5ORIQUGBEOBwFZ4vIFKJBcje3BI0jjnVMuzh4cGs7vz8fBkaGnK8BuA1NTU/nGttbZWenh4Jxo8rgBgkAZiYmHh1UAQOSJGQ4E41iFnMcYJlV4Ic81WDvlZWVuaoRM/OziQtLU18ey7S1/r6ugTqxzVAvb29JgBjY2MSiCggf9PgeQ0QadhJlLA777siDg4OTMp2WpX+/LgGqL+/P+AVRFNLCkCaewkQ6Zem9+f37/9zDbXNLmJQhaS73NxcCcaPa4AGBgZMACyF9lJ6a25uNvWnqakprAdge4l7kmbsgXOqQag4jr20iYtcvry8NKrS9xw1zO6PCUndpQYF48c1QBRQAuBvVSA9ERCkiqurK/Ow5HTSHLMwlP00VJOlzqyVYa0qbGdnxxw7OTl57qtYvXYfpKHGxkazbbS5uWnOsSJRYdQRS8gwRp6N+/AMSGYkPLK6qqrKqNdA/LjeqPrrNbq7u428pheyjpEiSHU8RLD3I/j2l4NWmrMfs9Ic9c5+zJ7m6FMAvLCwIPaejnda9r6FoLPfRqrjO9ZKoalGDATqxzVANG+vNapqLgICDICs2aXmMUBssQDIyr9qHgNEbQHQ7u6uAvIioOvrawPILgLUPParHhpEJLQG0qOA8vLyFI6XAPG7N3qDyspKYTPR/h5EzQOA2Bi1N4BOu7pqLgJiv4n3Ovx4g5dTGkD97wYFpEFQQGoKSAGpKSA1BaSA1CJt/wB7zXn8mefcWAAAAABJRU5ErkJggg==", 6 | "4":"iVBORw0KGgoAAAANSUhEUgAAAH4AAAAyCAYAAACauW+fAAAG4klEQVR42u2bcUTeWxjH+2NEM5WmMktKxZKlP8q0uyTdTWSm3clmJImiFBmNJEmiKO4ySUzubGYiZpPZ1T/JnZncJemPkjtJ7sjcZdzlufdzODn9+r29v9/7ytv7vuePR/X7nXN+55zv8zzf53nOKUFEEqzEn9hNsMBbscBbscBbscBbscB7k89/fZb9/X2xGx1HwAN6WlqafPn7iwU+noD/5fZtSUxMtMDHE/BPnjyRqakpOXfunAU+XoDf2dmRjo4OBbYFPoaBx7Kv/XRNWlpa5Me/P+TBgweyvb0tX79+VRa/ublpgY814HHpCf8PoWVyclLOnj17IDzjJ17AbnYMAX/jxg15+ttTyczMlKSkJFlYWDgEsHX1MQj8t3++SXFxsQIVt0765mxjgY9B4D98+CBZWVkW1HgD/vXr1yp4s5voTQh8/fb5/v27rK2tuXrTiAH//PlzFbzh8sOZwPs/3kthYaHs7u4ejLO3t6eygmAbeRpphLmba9FSVFQki4uLvua7tLQkFy9elNra2tMDPGkcwKORoY7x6tUrVdZ98eKFGmN1dVUqKyslNTVVzpw5I/n5+TI7O3tkfFLGjIwM1SY9PV36+voirgAvX76UgoIClcXgCS9cuCDDw8NivmetMzMzvuY6PT0tg4ODpwf4R78+UsD71WItKExycrJMTEyo/lhva2vrgbWwYEq+bOTGxoaYCkcaye/r6+ty6dIlNY+HDx9GDHy8FnPFqlkHLvrq1atqXsxXtxsbG5OUlBRZXl72PNfGxsYj2VJEgR8aGlILw2pD6V9RUaEs2lQkNsxsU1ZWpr7x5s0b9Ryl0IpiWgRtSkpKxE9G4rUK6aUdFskc7t69K6ZXclNIaA2lOG48TjR1TMC6gsUHodBtyMDjXlkYG++3LxpM366uLjkusMFdYvHHcfnbt2/VWE4ehGtRTp1yas6sqqqS8+fPS3Nzc9B58+1gsQaC14N2GFcHYgB2+fLlI3zf39+v5vv7u3fiBiBej3GgBQJorSSMy7v6+vqDflAk34D2TM9yosB3d3erBYyPj/sGnvIufQPxHRtJGZg2LPa4sXCftHv27Jk4FQKu5d3o6KjaRKzQz/0Ar8Aj7ANFrOzsbPUdAHazVK2oTU1N4vQupaWl0tvbq/p9+vOTUnxtHD09PQfURyo9MDAQktGFDXxnZ6dagBnAeBW0lL4Ec27v0XhdBg4WEGERuM9A7wEgJydHampqfM/TD/BaCbF8FABudlMyLJd1mTSHENQyV/MZ8zbXjhfDsxHXhBvThNyxvb1dLSCUiBMw6XucC8fqcWu0I8p3S5GwHqwgWPCD1XjxTIBsCsADlPksUF88DvMkC+F35n3v3j1xS0N5Z9ZAiFuuXLlyqC17w/fd1o1nCCebCgt4jl5ZgFNLvVoSfYNZE++J/N2CSPgwLy/PUyqH+7xz544nTnc7ZDLFLeDDc2Hl13++LiY49Ec5ne1RVt7pYJZswMn5zBnLdpsn3uHx48eRAR4rCtXi4S76cnwbrK1Oi+Bo5w0fkydxq4GiWwI66OWkXL3OcMz5NDQ0qGdQopvFoyja9ROcmW04ys7NzRXGcKMKAkfWHxHgdboyMjLiewLaGj5+/Bi0OkewxOkf/Gbydl1dnQqCdAUPWnDjcQI7eJJgcWVlRU4CeGiE9dy8eVOcwa/TMLa2ttRzij38PT8/f0gp8QJ4J4DlmNstr6euAf9HBHhcEQsg/w5VacxI/P79+wfVLtwp7pONJB5gc8w7AARQ5j0ALQRX2vUSPJH/M0+etbW1qbH56TUw8go8PMzc4W1cO98HGKqKAO0W1WtrxoIp6lAEQjEJ3kg7oTHmimfFrd+6dUtlJ7qSSZpKdI8RudHJiRdw3LQymJCqAB4pilmIwbrhP3gdfmPh5gEF/XCRbqAjusJHHzID0/XCoTwjPfSa0vmJ6qnGQSmAj7JWV1e7VuhQOuZqKjP7APgUrFgjz1g/Vo8HIF9nTLN4RWyDJ/Sbv4cNvM6fQ80l0WDcXSinVtEsAErVMmqPZXWpVB+waEtzll0DCS6Qkye4MF5AhxZJ+cJNxSIKPOkVwMM5uFhSEjgN90hVyevhBu4K2oh10IlNoJq5ublTsdawTqQAnoWgyZqLKbzAc5qrggknbHBjrF/Rgr8J2qL+Bo5OS1AA5zuqUH7Pna1E0S1bInC3e/OkGPaSZQwDr4sQpnDd2nlSZiXKgecwhACuvLxcFSnMs2GESpx18TEIvL5EoIV7ZOYlBwI6qlictwc6crUShcCTtnH2Tf5tpmyUQvWJkz5GjbfCjP03aSsWeCsWeCsWeCsWeCsWeCsWeCsWeCsWeCsWeCvhy3+xIewPK8tQrgAAAABJRU5ErkJggg==", 7 | "5":"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", 8 | "6":"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", 9 | "7":"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" 10 | } -------------------------------------------------------------------------------- /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 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 15 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 17 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 18 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 19 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 20 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 21 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXCopyFilesBuildPhase section */ 25 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 26 | isa = PBXCopyFilesBuildPhase; 27 | buildActionMask = 2147483647; 28 | dstPath = ""; 29 | dstSubfolderSpec = 10; 30 | files = ( 31 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 32 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 33 | ); 34 | name = "Embed Frameworks"; 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXCopyFilesBuildPhase section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 41 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 42 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 43 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 44 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 45 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 46 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 47 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 48 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 49 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 50 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 52 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 53 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 54 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 55 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 64 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 9740EEB11CF90186004384FC /* Flutter */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 3B80C3931E831B6300D905FE /* App.framework */, 75 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 76 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 77 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 78 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 79 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 80 | ); 81 | name = Flutter; 82 | sourceTree = ""; 83 | }; 84 | 97C146E51CF9000F007C117D = { 85 | isa = PBXGroup; 86 | children = ( 87 | 9740EEB11CF90186004384FC /* Flutter */, 88 | 97C146F01CF9000F007C117D /* Runner */, 89 | 97C146EF1CF9000F007C117D /* Products */, 90 | CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, 91 | ); 92 | sourceTree = ""; 93 | }; 94 | 97C146EF1CF9000F007C117D /* Products */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 97C146EE1CF9000F007C117D /* Runner.app */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | 97C146F01CF9000F007C117D /* Runner */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 106 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 107 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 108 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 109 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 110 | 97C147021CF9000F007C117D /* Info.plist */, 111 | 97C146F11CF9000F007C117D /* Supporting Files */, 112 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 113 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 114 | ); 115 | path = Runner; 116 | sourceTree = ""; 117 | }; 118 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 97C146F21CF9000F007C117D /* main.m */, 122 | ); 123 | name = "Supporting Files"; 124 | sourceTree = ""; 125 | }; 126 | /* End PBXGroup section */ 127 | 128 | /* Begin PBXNativeTarget section */ 129 | 97C146ED1CF9000F007C117D /* Runner */ = { 130 | isa = PBXNativeTarget; 131 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 132 | buildPhases = ( 133 | 9740EEB61CF901F6004384FC /* Run Script */, 134 | 97C146EA1CF9000F007C117D /* Sources */, 135 | 97C146EB1CF9000F007C117D /* Frameworks */, 136 | 97C146EC1CF9000F007C117D /* Resources */, 137 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 138 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 139 | ); 140 | buildRules = ( 141 | ); 142 | dependencies = ( 143 | ); 144 | name = Runner; 145 | productName = Runner; 146 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 147 | productType = "com.apple.product-type.application"; 148 | }; 149 | /* End PBXNativeTarget section */ 150 | 151 | /* Begin PBXProject section */ 152 | 97C146E61CF9000F007C117D /* Project object */ = { 153 | isa = PBXProject; 154 | attributes = { 155 | LastUpgradeCheck = 0910; 156 | ORGANIZATIONNAME = "The Chromium Authors"; 157 | TargetAttributes = { 158 | 97C146ED1CF9000F007C117D = { 159 | CreatedOnToolsVersion = 7.3.1; 160 | }; 161 | }; 162 | }; 163 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 164 | compatibilityVersion = "Xcode 3.2"; 165 | developmentRegion = English; 166 | hasScannedForEncodings = 0; 167 | knownRegions = ( 168 | en, 169 | Base, 170 | ); 171 | mainGroup = 97C146E51CF9000F007C117D; 172 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 173 | projectDirPath = ""; 174 | projectRoot = ""; 175 | targets = ( 176 | 97C146ED1CF9000F007C117D /* Runner */, 177 | ); 178 | }; 179 | /* End PBXProject section */ 180 | 181 | /* Begin PBXResourcesBuildPhase section */ 182 | 97C146EC1CF9000F007C117D /* Resources */ = { 183 | isa = PBXResourcesBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 187 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 188 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 189 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 190 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | /* End PBXResourcesBuildPhase section */ 195 | 196 | /* Begin PBXShellScriptBuildPhase section */ 197 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 198 | isa = PBXShellScriptBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | ); 202 | inputPaths = ( 203 | ); 204 | name = "Thin Binary"; 205 | outputPaths = ( 206 | ); 207 | runOnlyForDeploymentPostprocessing = 0; 208 | shellPath = /bin/sh; 209 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 210 | }; 211 | 9740EEB61CF901F6004384FC /* Run Script */ = { 212 | isa = PBXShellScriptBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | ); 216 | inputPaths = ( 217 | ); 218 | name = "Run Script"; 219 | outputPaths = ( 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | shellPath = /bin/sh; 223 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 224 | }; 225 | /* End PBXShellScriptBuildPhase section */ 226 | 227 | /* Begin PBXSourcesBuildPhase section */ 228 | 97C146EA1CF9000F007C117D /* Sources */ = { 229 | isa = PBXSourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 233 | 97C146F31CF9000F007C117D /* main.m in Sources */, 234 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | /* End PBXSourcesBuildPhase section */ 239 | 240 | /* Begin PBXVariantGroup section */ 241 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 242 | isa = PBXVariantGroup; 243 | children = ( 244 | 97C146FB1CF9000F007C117D /* Base */, 245 | ); 246 | name = Main.storyboard; 247 | sourceTree = ""; 248 | }; 249 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 250 | isa = PBXVariantGroup; 251 | children = ( 252 | 97C147001CF9000F007C117D /* Base */, 253 | ); 254 | name = LaunchScreen.storyboard; 255 | sourceTree = ""; 256 | }; 257 | /* End PBXVariantGroup section */ 258 | 259 | /* Begin XCBuildConfiguration section */ 260 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 261 | isa = XCBuildConfiguration; 262 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 263 | buildSettings = { 264 | ALWAYS_SEARCH_USER_PATHS = NO; 265 | CLANG_ANALYZER_NONNULL = YES; 266 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 267 | CLANG_CXX_LIBRARY = "libc++"; 268 | CLANG_ENABLE_MODULES = YES; 269 | CLANG_ENABLE_OBJC_ARC = YES; 270 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 271 | CLANG_WARN_BOOL_CONVERSION = YES; 272 | CLANG_WARN_COMMA = YES; 273 | CLANG_WARN_CONSTANT_CONVERSION = YES; 274 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 275 | CLANG_WARN_EMPTY_BODY = YES; 276 | CLANG_WARN_ENUM_CONVERSION = YES; 277 | CLANG_WARN_INFINITE_RECURSION = YES; 278 | CLANG_WARN_INT_CONVERSION = YES; 279 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 280 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 283 | CLANG_WARN_STRICT_PROTOTYPES = YES; 284 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 285 | CLANG_WARN_UNREACHABLE_CODE = YES; 286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 288 | COPY_PHASE_STRIP = NO; 289 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 290 | ENABLE_NS_ASSERTIONS = NO; 291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 292 | GCC_C_LANGUAGE_STANDARD = gnu99; 293 | GCC_NO_COMMON_BLOCKS = YES; 294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 296 | GCC_WARN_UNDECLARED_SELECTOR = YES; 297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 298 | GCC_WARN_UNUSED_FUNCTION = YES; 299 | GCC_WARN_UNUSED_VARIABLE = YES; 300 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 301 | MTL_ENABLE_DEBUG_INFO = NO; 302 | SDKROOT = iphoneos; 303 | TARGETED_DEVICE_FAMILY = "1,2"; 304 | VALIDATE_PRODUCT = YES; 305 | }; 306 | name = Profile; 307 | }; 308 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 309 | isa = XCBuildConfiguration; 310 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 311 | buildSettings = { 312 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 313 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 314 | DEVELOPMENT_TEAM = S8QB4VV633; 315 | ENABLE_BITCODE = NO; 316 | FRAMEWORK_SEARCH_PATHS = ( 317 | "$(inherited)", 318 | "$(PROJECT_DIR)/Flutter", 319 | ); 320 | INFOPLIST_FILE = Runner/Info.plist; 321 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 322 | LIBRARY_SEARCH_PATHS = ( 323 | "$(inherited)", 324 | "$(PROJECT_DIR)/Flutter", 325 | ); 326 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterdemo; 327 | PRODUCT_NAME = "$(TARGET_NAME)"; 328 | VERSIONING_SYSTEM = "apple-generic"; 329 | }; 330 | name = Profile; 331 | }; 332 | 97C147031CF9000F007C117D /* Debug */ = { 333 | isa = XCBuildConfiguration; 334 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_ANALYZER_NONNULL = YES; 338 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 339 | CLANG_CXX_LIBRARY = "libc++"; 340 | CLANG_ENABLE_MODULES = YES; 341 | CLANG_ENABLE_OBJC_ARC = YES; 342 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 343 | CLANG_WARN_BOOL_CONVERSION = YES; 344 | CLANG_WARN_COMMA = YES; 345 | CLANG_WARN_CONSTANT_CONVERSION = YES; 346 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 347 | CLANG_WARN_EMPTY_BODY = YES; 348 | CLANG_WARN_ENUM_CONVERSION = YES; 349 | CLANG_WARN_INFINITE_RECURSION = YES; 350 | CLANG_WARN_INT_CONVERSION = YES; 351 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 352 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 353 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 354 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 355 | CLANG_WARN_STRICT_PROTOTYPES = YES; 356 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 357 | CLANG_WARN_UNREACHABLE_CODE = YES; 358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 359 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 360 | COPY_PHASE_STRIP = NO; 361 | DEBUG_INFORMATION_FORMAT = dwarf; 362 | ENABLE_STRICT_OBJC_MSGSEND = YES; 363 | ENABLE_TESTABILITY = YES; 364 | GCC_C_LANGUAGE_STANDARD = gnu99; 365 | GCC_DYNAMIC_NO_PIC = NO; 366 | GCC_NO_COMMON_BLOCKS = YES; 367 | GCC_OPTIMIZATION_LEVEL = 0; 368 | GCC_PREPROCESSOR_DEFINITIONS = ( 369 | "DEBUG=1", 370 | "$(inherited)", 371 | ); 372 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 373 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 374 | GCC_WARN_UNDECLARED_SELECTOR = YES; 375 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 376 | GCC_WARN_UNUSED_FUNCTION = YES; 377 | GCC_WARN_UNUSED_VARIABLE = YES; 378 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 379 | MTL_ENABLE_DEBUG_INFO = YES; 380 | ONLY_ACTIVE_ARCH = YES; 381 | SDKROOT = iphoneos; 382 | TARGETED_DEVICE_FAMILY = "1,2"; 383 | }; 384 | name = Debug; 385 | }; 386 | 97C147041CF9000F007C117D /* Release */ = { 387 | isa = XCBuildConfiguration; 388 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 397 | CLANG_WARN_BOOL_CONVERSION = YES; 398 | CLANG_WARN_COMMA = YES; 399 | CLANG_WARN_CONSTANT_CONVERSION = YES; 400 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 401 | CLANG_WARN_EMPTY_BODY = YES; 402 | CLANG_WARN_ENUM_CONVERSION = YES; 403 | CLANG_WARN_INFINITE_RECURSION = YES; 404 | CLANG_WARN_INT_CONVERSION = YES; 405 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 406 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 407 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 408 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 409 | CLANG_WARN_STRICT_PROTOTYPES = YES; 410 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 411 | CLANG_WARN_UNREACHABLE_CODE = YES; 412 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 413 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 414 | COPY_PHASE_STRIP = NO; 415 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 416 | ENABLE_NS_ASSERTIONS = NO; 417 | ENABLE_STRICT_OBJC_MSGSEND = YES; 418 | GCC_C_LANGUAGE_STANDARD = gnu99; 419 | GCC_NO_COMMON_BLOCKS = YES; 420 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 421 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 422 | GCC_WARN_UNDECLARED_SELECTOR = YES; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 427 | MTL_ENABLE_DEBUG_INFO = NO; 428 | SDKROOT = iphoneos; 429 | TARGETED_DEVICE_FAMILY = "1,2"; 430 | VALIDATE_PRODUCT = YES; 431 | }; 432 | name = Release; 433 | }; 434 | 97C147061CF9000F007C117D /* Debug */ = { 435 | isa = XCBuildConfiguration; 436 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 437 | buildSettings = { 438 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 439 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 440 | ENABLE_BITCODE = NO; 441 | FRAMEWORK_SEARCH_PATHS = ( 442 | "$(inherited)", 443 | "$(PROJECT_DIR)/Flutter", 444 | ); 445 | INFOPLIST_FILE = Runner/Info.plist; 446 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 447 | LIBRARY_SEARCH_PATHS = ( 448 | "$(inherited)", 449 | "$(PROJECT_DIR)/Flutter", 450 | ); 451 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterdemo; 452 | PRODUCT_NAME = "$(TARGET_NAME)"; 453 | VERSIONING_SYSTEM = "apple-generic"; 454 | }; 455 | name = Debug; 456 | }; 457 | 97C147071CF9000F007C117D /* Release */ = { 458 | isa = XCBuildConfiguration; 459 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 460 | buildSettings = { 461 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 462 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 463 | ENABLE_BITCODE = NO; 464 | FRAMEWORK_SEARCH_PATHS = ( 465 | "$(inherited)", 466 | "$(PROJECT_DIR)/Flutter", 467 | ); 468 | INFOPLIST_FILE = Runner/Info.plist; 469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 470 | LIBRARY_SEARCH_PATHS = ( 471 | "$(inherited)", 472 | "$(PROJECT_DIR)/Flutter", 473 | ); 474 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterdemo; 475 | PRODUCT_NAME = "$(TARGET_NAME)"; 476 | VERSIONING_SYSTEM = "apple-generic"; 477 | }; 478 | name = Release; 479 | }; 480 | /* End XCBuildConfiguration section */ 481 | 482 | /* Begin XCConfigurationList section */ 483 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 484 | isa = XCConfigurationList; 485 | buildConfigurations = ( 486 | 97C147031CF9000F007C117D /* Debug */, 487 | 97C147041CF9000F007C117D /* Release */, 488 | 249021D3217E4FDB00AE95B9 /* Profile */, 489 | ); 490 | defaultConfigurationIsVisible = 0; 491 | defaultConfigurationName = Release; 492 | }; 493 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 494 | isa = XCConfigurationList; 495 | buildConfigurations = ( 496 | 97C147061CF9000F007C117D /* Debug */, 497 | 97C147071CF9000F007C117D /* Release */, 498 | 249021D4217E4FDB00AE95B9 /* Profile */, 499 | ); 500 | defaultConfigurationIsVisible = 0; 501 | defaultConfigurationName = Release; 502 | }; 503 | /* End XCConfigurationList section */ 504 | }; 505 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 506 | } 507 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:flutter/material.dart'; 3 | import 'dart:convert'; 4 | import './util/api.dart'; 5 | import 'package:flutter_easyrefresh/easy_refresh.dart'; 6 | import 'package:audioplayers/audioplayers.dart'; 7 | import 'package:flutter_easyrefresh/material_header.dart'; 8 | import 'package:auto_size_text/auto_size_text.dart'; 9 | import 'package:flutter_icons/flutter_icons.dart'; 10 | import 'package:url_launcher/url_launcher.dart'; 11 | import 'package:flutter/services.dart'; 12 | import 'package:flutter/rendering.dart'; 13 | 14 | void main() { 15 | runApp(MyApp()); 16 | SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( 17 | systemNavigationBarColor: Colors.black, 18 | statusBarColor: Colors.transparent, 19 | )); 20 | debugPaintSizeEnabled = false; 21 | } 22 | 23 | class MyApp extends StatelessWidget { 24 | @override 25 | Widget build(BuildContext context) { 26 | return MaterialApp( 27 | debugShowCheckedModeBanner: false, 28 | theme: ThemeData(primaryColor: Colors.white), 29 | home: RandomWords(), 30 | ); 31 | } 32 | } 33 | 34 | class RandomWords extends StatefulWidget { 35 | @override 36 | RandomWordsState createState() => RandomWordsState(); 37 | } 38 | 39 | class RandomWordsState extends State 40 | with SingleTickerProviderStateMixin { 41 | Map picture = {'url': '', 'copyright': '', 'copyrightlink': ''}; 42 | Map sentence = {'hitokoto': '', 'from': ''}; 43 | Map poetry = {'content': '', 'origin': '', 'author': ''}; 44 | Map music = {'url': '', 'picUrl': '', 'author': '', 'name': ''}; 45 | Map musicComment = {'comment': '', 'nickname': '', 'title': '', 'author': ''}; 46 | Map randomColor = { 47 | 'color_one': '0xFFFFCDB2', 48 | 'color_two': '0xFF6D6875', 49 | 'color_one_origin': 'FFCDB2', 50 | 'color_two_origin': '6D6875' 51 | }; 52 | String math = ''; 53 | String chemical = ''; 54 | Map repo = { 55 | 'author': '', 56 | 'description': '', 57 | 'name': '', 58 | 'url': '', 59 | 'stars': '', 60 | 'forks': '' 61 | }; 62 | Map zhihuDaily = {'title': ''}; 63 | Map today = {'day': '', 'content': ''}; 64 | Map oneArticle = {'author': '', 'title': '', 'content': ''}; 65 | 66 | TabController _tabController; 67 | AudioPlayer audioPlayer = AudioPlayer(); 68 | bool isPlaying = false; 69 | GlobalKey _headerKey1 = GlobalKey(); 70 | GlobalKey _headerKey2 = GlobalKey(); 71 | GlobalKey _headerKey3 = GlobalKey(); 72 | GlobalKey _headerKey4 = GlobalKey(); 73 | GlobalKey _headerKey5 = GlobalKey(); 74 | GlobalKey _headerKey6 = GlobalKey(); 75 | GlobalKey _headerKey7 = GlobalKey(); 76 | GlobalKey _headerKey8 = GlobalKey(); 77 | GlobalKey _headerKey9 = GlobalKey(); 78 | GlobalKey _headerKey10 = GlobalKey(); 79 | GlobalKey _headerKey11 = GlobalKey(); 80 | GlobalKey _headerKey12 = GlobalKey(); 81 | 82 | @override 83 | void initState() { 84 | super.initState(); 85 | _tabController = TabController(vsync: this, length: 12); 86 | } 87 | 88 | @override 89 | void didChangeDependencies() { 90 | super.didChangeDependencies(); 91 | _loadPicture(); 92 | _loadSentence(); 93 | _loadPoetry(); 94 | _loadMusic(); 95 | _loadMusicComment(); 96 | _loadMath(); 97 | _loadRandomColor(); 98 | _loadChemical(); 99 | _loadRepo(); 100 | _loadZhihuDaily(); 101 | _loadTodayInHistory(); 102 | _loadOneArticle(); 103 | } 104 | 105 | @override 106 | void dispose() { 107 | _tabController.dispose(); 108 | super.dispose(); 109 | } 110 | 111 | Widget getListTile(String title, int index) { 112 | return ListTile( 113 | title: Text(title, style: TextStyle(color: Color(0xff9ABD97))), 114 | onTap: () { 115 | to(index); 116 | }, 117 | ); 118 | } 119 | 120 | @override 121 | Widget build(BuildContext context) { 122 | return Scaffold( 123 | body: DefaultTabController( 124 | length: 12, 125 | child: Scaffold( 126 | appBar: null, 127 | body: TabBarView( 128 | controller: _tabController, 129 | children: [ 130 | _buildPicture(), 131 | _buildSentence(), 132 | _buildMusic(), 133 | _buildMusicComment(), 134 | _buildPoetry(), 135 | _buildMath(), 136 | _buildRandomColor(), 137 | _buildChemical(), 138 | _buildRepo(), 139 | _buildZhihuDaily(), 140 | _buildTodayInHistory(), 141 | _buildOneArticle(), 142 | ], 143 | ), 144 | ), 145 | ), 146 | drawer: Drawer( 147 | child: ListView( 148 | padding: EdgeInsets.zero, 149 | children: [ 150 | Container( 151 | color: Color(0xff9ABD97), 152 | child: Padding( 153 | padding: EdgeInsets.fromLTRB(20, 50, 0, 50), 154 | child: Text('今日份的X', 155 | style: TextStyle( 156 | fontSize: 25, 157 | fontWeight: FontWeight.bold, 158 | color: Colors.white))), 159 | ), 160 | Container( 161 | margin: EdgeInsets.fromLTRB(10, 0, 0, 10), 162 | child: Column(children: [ 163 | ListTile( 164 | title: Text('图片'), 165 | onTap: () { 166 | to(0); 167 | }, 168 | ), 169 | ListTile( 170 | title: Text('名言'), 171 | onTap: () { 172 | to(1); 173 | }, 174 | ), 175 | ListTile( 176 | title: Text('音乐'), 177 | onTap: () { 178 | to(2); 179 | }, 180 | ), 181 | ListTile( 182 | title: Text('乐评'), 183 | onTap: () { 184 | to(3); 185 | }, 186 | ), 187 | ListTile( 188 | title: Text('诗歌'), 189 | onTap: () { 190 | to(4); 191 | }, 192 | ), 193 | ListTile( 194 | title: Text('高等数学'), 195 | onTap: () { 196 | to(5); 197 | }, 198 | ), 199 | ListTile( 200 | title: Text('色彩'), 201 | onTap: () { 202 | to(6); 203 | }, 204 | ), 205 | ListTile( 206 | title: Text('化学方程式'), 207 | onTap: () { 208 | to(7); 209 | }, 210 | ), 211 | ListTile( 212 | title: Text('Github Repository'), 213 | onTap: () { 214 | to(8); 215 | }, 216 | ), 217 | ListTile( 218 | title: Text('知乎日报'), 219 | onTap: () { 220 | to(9); 221 | }, 222 | ), 223 | ListTile( 224 | title: Text('历史上的今天'), 225 | onTap: () { 226 | to(10); 227 | }, 228 | ), 229 | ListTile( 230 | title: Text('文章'), 231 | onTap: () { 232 | to(11); 233 | }, 234 | ) 235 | ])), 236 | Container( 237 | padding: const EdgeInsets.fromLTRB(10, 5, 0, 0), 238 | decoration: BoxDecoration( 239 | border: Border( 240 | top: BorderSide(color: Colors.black26, width: 0.7))), 241 | child: ListTile( 242 | title: Text('关于'), 243 | onTap: () { 244 | launch('https://github.com/shuiRong/TodayX'); 245 | }, 246 | ), 247 | ) 248 | ], 249 | ), 250 | )); 251 | } 252 | 253 | to(int where) { 254 | Navigator.pop(context); 255 | _tabController.animateTo(where); 256 | } 257 | 258 | _loadPicture() { 259 | API.picture().then((obj) { 260 | setState(() { 261 | picture = {...obj, 'url': 'https://cn.bing.com/' + obj['url']}; 262 | }); 263 | }); 264 | } 265 | 266 | _buildPicture() { 267 | final int backgroundColor = 0xFFFFCDB2; 268 | final int textColor = 0xFF6D6875; 269 | final height = MediaQuery.of(context).size.height; 270 | 271 | return EasyRefresh( 272 | refreshHeader: MaterialHeader( 273 | key: _headerKey1, 274 | ), 275 | child: SingleChildScrollView( 276 | child: Container( 277 | color: Color(backgroundColor), 278 | height: height, 279 | padding: EdgeInsets.fromLTRB(15.0, 0, 15.0, 0), 280 | alignment: Alignment.center, 281 | child: Container( 282 | child: Column( 283 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 284 | children: [ 285 | Padding( 286 | padding: EdgeInsets.only(top: 40), 287 | child: Text( 288 | '图片', 289 | style: TextStyle( 290 | color: Color(textColor), 291 | fontSize: 15, 292 | height: 1.3, 293 | ), 294 | )), 295 | Padding( 296 | padding: EdgeInsets.only(bottom: height * 0.3), 297 | child: Column( 298 | children: [ 299 | Padding( 300 | padding: EdgeInsets.only(bottom: 30), 301 | child: (picture['url'].isNotEmpty 302 | ? Image.network(picture['url']) 303 | : null)), 304 | Text( 305 | picture['copyright'], 306 | style: TextStyle( 307 | color: Color(textColor), 308 | fontSize: 15, 309 | height: 1.3, 310 | ), 311 | ) 312 | ], 313 | ), 314 | ) 315 | ], 316 | )))), 317 | onRefresh: () async { 318 | _loadPicture(); 319 | }, 320 | ); 321 | } 322 | 323 | _loadSentence() { 324 | API.sentence().then((obj) { 325 | setState(() { 326 | sentence = obj; 327 | }); 328 | }); 329 | } 330 | 331 | _buildSentence() { 332 | final int backgroundColor = 0xFF06AED5; 333 | final int textColor = 0xFFFFF1D0; 334 | final height = MediaQuery.of(context).size.height; 335 | 336 | return EasyRefresh( 337 | refreshHeader: MaterialHeader( 338 | key: _headerKey4, 339 | ), 340 | child: SingleChildScrollView( 341 | child: Container( 342 | color: Color(backgroundColor), 343 | height: height, 344 | padding: EdgeInsets.fromLTRB(30.0, 0, 30.0, 0), 345 | alignment: Alignment.center, 346 | child: Container( 347 | child: Column( 348 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 349 | children: [ 350 | Padding( 351 | padding: EdgeInsets.only(top: 40), 352 | child: Text( 353 | '名言', 354 | style: TextStyle( 355 | color: Color(textColor), 356 | fontSize: 15, 357 | height: 1.3, 358 | ), 359 | )), 360 | Padding( 361 | padding: EdgeInsets.only(bottom: height * 0.42), 362 | child: Column( 363 | children: [ 364 | Padding( 365 | padding: EdgeInsets.only(bottom: 30), 366 | child: Text( 367 | sentence['hitokoto'], 368 | style: TextStyle( 369 | color: Color(textColor), 370 | fontSize: 22.0, 371 | height: 1.3, 372 | ), 373 | )), 374 | Text( 375 | sentence['from'], 376 | style: TextStyle( 377 | color: Color(textColor), 378 | fontSize: 15, 379 | height: 1.3, 380 | ), 381 | ) 382 | ], 383 | ), 384 | ) 385 | ], 386 | )))), 387 | onRefresh: () async { 388 | _loadSentence(); 389 | }, 390 | ); 391 | } 392 | 393 | _buildPoetry() { 394 | final int backgroundColor = 0xFF6FFFE9; 395 | final int textColor = 0xFF292F36; 396 | final height = MediaQuery.of(context).size.height; 397 | 398 | return EasyRefresh( 399 | refreshHeader: MaterialHeader( 400 | key: _headerKey2, 401 | ), 402 | child: SingleChildScrollView( 403 | child: Container( 404 | color: Color(backgroundColor), 405 | height: height, 406 | padding: EdgeInsets.fromLTRB(30.0, 0, 30.0, 0), 407 | alignment: Alignment.center, 408 | child: Container( 409 | child: Column( 410 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 411 | children: [ 412 | Padding( 413 | padding: EdgeInsets.only(top: 40), 414 | child: Text( 415 | '诗歌', 416 | style: TextStyle( 417 | color: Color(textColor), 418 | fontSize: 15, 419 | height: 1.3, 420 | ), 421 | )), 422 | Padding( 423 | padding: EdgeInsets.only(bottom: height * 0.40), 424 | child: Column( 425 | children: [ 426 | Padding( 427 | padding: EdgeInsets.only(bottom: 30), 428 | child: Text( 429 | poetry['content'], 430 | style: TextStyle( 431 | color: Color(textColor), 432 | fontSize: 22.0, 433 | height: 1.3, 434 | ), 435 | )), 436 | Text( 437 | poetry['author'], 438 | style: TextStyle( 439 | color: Color(textColor), 440 | fontSize: 15, 441 | height: 1.3, 442 | ), 443 | ) 444 | ], 445 | ), 446 | ) 447 | ], 448 | )))), 449 | onRefresh: () async { 450 | _loadPoetry(); 451 | }, 452 | ); 453 | } 454 | 455 | _loadPoetry() { 456 | API.poetry().then((obj) { 457 | setState(() { 458 | poetry = {...obj, 'author': '—— ' + obj['author']}; 459 | }); 460 | }); 461 | } 462 | 463 | _loadMusic() { 464 | audioPlayer.onPlayerCompletion.listen((event) { 465 | setState(() { 466 | isPlaying = false; 467 | }); 468 | }); 469 | API.music().then((obj) { 470 | setState(() { 471 | music = obj; 472 | }); 473 | }); 474 | } 475 | 476 | play() async { 477 | int result = await audioPlayer.play(music['url']); 478 | if (result == 1) { 479 | // success 480 | setState(() { 481 | isPlaying = true; 482 | }); 483 | } 484 | } 485 | 486 | pause() async { 487 | int result = await audioPlayer.pause(); 488 | if (result == 1) { 489 | setState(() { 490 | isPlaying = false; 491 | }); 492 | } 493 | } 494 | 495 | _buildMusic() { 496 | final int backgroundColor = 0xFFD13C37; 497 | final int textColor = 0xFF0D2C54; 498 | final height = MediaQuery.of(context).size.height; 499 | 500 | return EasyRefresh( 501 | refreshHeader: MaterialHeader( 502 | key: _headerKey3, 503 | ), 504 | child: SingleChildScrollView( 505 | child: Container( 506 | color: Color(backgroundColor), 507 | height: height, 508 | padding: EdgeInsets.fromLTRB(15.0, 0, 15.0, 0), 509 | alignment: Alignment.center, 510 | child: Container( 511 | child: Column( 512 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 513 | children: [ 514 | Padding( 515 | padding: EdgeInsets.only(top: 40), 516 | child: Text( 517 | '音乐', 518 | style: TextStyle( 519 | color: Color(textColor), 520 | fontSize: 15, 521 | height: 1.3, 522 | ), 523 | )), 524 | Padding( 525 | padding: EdgeInsets.only(bottom: height * 0.2), 526 | child: Column( 527 | children: [ 528 | Padding( 529 | padding: EdgeInsets.fromLTRB(50, 0, 50, 20), 530 | child: music['picUrl'].isNotEmpty 531 | ? Image.network(music['picUrl']) 532 | : null), 533 | (isPlaying 534 | ? IconButton( 535 | onPressed: pause, 536 | icon: 537 | Icon(Icons.pause, color: Color(textColor))) 538 | : IconButton( 539 | onPressed: play, 540 | icon: Icon(Icons.play_arrow, 541 | color: Color(textColor)))), 542 | Padding( 543 | padding: EdgeInsets.fromLTRB(0, 10, 0, 10), 544 | child: Text( 545 | music['name'], 546 | style: TextStyle( 547 | color: Color(textColor), 548 | fontSize: 20, 549 | height: 1.3, 550 | fontWeight: FontWeight.bold), 551 | )), 552 | Text( 553 | music['author'], 554 | style: TextStyle( 555 | color: Color(textColor), 556 | fontSize: 13, 557 | height: 1.3, 558 | ), 559 | ) 560 | ], 561 | ), 562 | ) 563 | ], 564 | )))), 565 | onRefresh: () async { 566 | _loadMusic(); 567 | }, 568 | ); 569 | } 570 | 571 | // 网易云评论 572 | _buildMusicComment() { 573 | final int backgroundColor = 0xFF003049; 574 | final int textColor = 0xFFEAE2B7; 575 | final height = MediaQuery.of(context).size.height; 576 | 577 | return EasyRefresh( 578 | refreshHeader: MaterialHeader( 579 | key: _headerKey5, 580 | ), 581 | child: SingleChildScrollView( 582 | child: Container( 583 | color: Color(backgroundColor), 584 | height: height, 585 | padding: EdgeInsets.fromLTRB(30.0, 0, 30.0, 0), 586 | alignment: Alignment.center, 587 | child: Container( 588 | child: Column( 589 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 590 | children: [ 591 | Padding( 592 | padding: EdgeInsets.only(top: 40), 593 | child: Text( 594 | '乐评', 595 | style: TextStyle( 596 | color: Color(textColor), 597 | fontSize: 15, 598 | height: 1.3, 599 | ), 600 | )), 601 | Padding( 602 | padding: EdgeInsets.only(bottom: height * 0.32), 603 | child: Column( 604 | children: [ 605 | Padding( 606 | padding: EdgeInsets.only(bottom: 50), 607 | child: AutoSizeText( 608 | musicComment['comment'], 609 | style: TextStyle( 610 | color: Color(textColor), 611 | fontSize: 20.0, 612 | height: 1.3, 613 | ), 614 | maxLines: 5, 615 | )), 616 | Text( 617 | musicComment['nickname'], 618 | style: TextStyle( 619 | color: Color(textColor), 620 | fontSize: 15, 621 | height: 1.3, 622 | ), 623 | ), 624 | Text( 625 | musicComment['author'], 626 | style: TextStyle( 627 | color: Color(textColor), 628 | fontSize: 15, 629 | height: 1.3, 630 | ), 631 | ), 632 | ], 633 | ), 634 | ) 635 | ], 636 | )))), 637 | onRefresh: () async { 638 | _loadMusicComment(); 639 | }, 640 | ); 641 | } 642 | 643 | _loadMusicComment() { 644 | API.musicComment().then((obj) { 645 | setState(() { 646 | musicComment = { 647 | ...obj, 648 | 'author': '《' + obj['title'] + '》 —— ' + obj['author'], 649 | 'nickname': '@' + obj['nickname'] 650 | }; 651 | }); 652 | }); 653 | } 654 | 655 | _loadMath() { 656 | DefaultAssetBundle.of(context) 657 | .loadString("./lib/assets/math.json") 658 | .then((data) { 659 | final result = json.decode(data); 660 | String index = Random().nextInt(8).toString(); 661 | setState(() { 662 | math = result[index]; 663 | }); 664 | }); 665 | } 666 | 667 | _buildMath() { 668 | final int backgroundColor = 0xFFFFCDB2; 669 | final int textColor = 0xFF6D6875; 670 | final height = MediaQuery.of(context).size.height; 671 | 672 | return EasyRefresh( 673 | refreshHeader: MaterialHeader( 674 | key: _headerKey6, 675 | ), 676 | child: SingleChildScrollView( 677 | child: Container( 678 | color: Color(backgroundColor), 679 | height: height, 680 | padding: EdgeInsets.fromLTRB(15.0, 0, 15.0, 0), 681 | alignment: Alignment.center, 682 | child: Container( 683 | child: Column( 684 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 685 | children: [ 686 | Padding( 687 | padding: EdgeInsets.only(top: 40), 688 | child: Text( 689 | '高等数学', 690 | style: TextStyle( 691 | color: Color(textColor), 692 | fontSize: 15, 693 | height: 1.3, 694 | ), 695 | )), 696 | Padding( 697 | padding: EdgeInsets.only(bottom: height * 0.4), 698 | child: Column( 699 | children: [ 700 | Padding( 701 | padding: EdgeInsets.only(bottom: 50), 702 | child: math == null 703 | ? null 704 | : Image.memory(Base64Decoder().convert(math))), 705 | ], 706 | ), 707 | ) 708 | ], 709 | )))), 710 | onRefresh: () async { 711 | _loadMath(); 712 | }, 713 | ); 714 | } 715 | 716 | _loadRandomColor() { 717 | API.randomColor().then((obj) { 718 | setState(() { 719 | randomColor = obj; 720 | }); 721 | }); 722 | } 723 | 724 | _buildRandomColor() { 725 | final height = MediaQuery.of(context).size.height; 726 | 727 | return EasyRefresh( 728 | refreshHeader: MaterialHeader( 729 | key: _headerKey7, 730 | ), 731 | child: SingleChildScrollView( 732 | child: Container( 733 | color: Color(int.parse(randomColor['color_one'])), 734 | height: height, 735 | alignment: Alignment.center, 736 | child: Container( 737 | child: Column( 738 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 739 | children: [ 740 | Padding( 741 | padding: EdgeInsets.only(top: 40), 742 | child: Text( 743 | '色彩', 744 | style: TextStyle( 745 | color: Color(int.parse(randomColor['color_two'])), 746 | fontSize: 15, 747 | height: 1.3, 748 | ), 749 | )), 750 | Padding( 751 | padding: EdgeInsets.only(bottom: height * 0.45), 752 | child: 753 | Row(mainAxisSize: MainAxisSize.min, children: [ 754 | Container( 755 | height: 70, 756 | width: 155, 757 | child: Text(randomColor['color_two_origin'], 758 | textAlign: TextAlign.center, 759 | style: TextStyle( 760 | color: 761 | Color(int.parse(randomColor['color_two'])), 762 | fontSize: 35, 763 | height: 1.45, 764 | fontWeight: FontWeight.bold, 765 | ))), 766 | Container( 767 | color: Color(int.parse(randomColor['color_two'])), 768 | height: 70, 769 | width: 155, 770 | child: Text(randomColor['color_one_origin'], 771 | textAlign: TextAlign.center, 772 | style: TextStyle( 773 | color: 774 | Color(int.parse(randomColor['color_one'])), 775 | fontSize: 35, 776 | height: 1.45, 777 | fontWeight: FontWeight.bold, 778 | ))) 779 | ]), 780 | ) 781 | ], 782 | )))), 783 | onRefresh: () async { 784 | _loadRandomColor(); 785 | }, 786 | ); 787 | } 788 | 789 | _loadChemical() { 790 | DefaultAssetBundle.of(context) 791 | .loadString("./lib/assets/chemical.json") 792 | .then((data) { 793 | final result = json.decode(data); 794 | String index = Random().nextInt(14).toString(); 795 | setState(() { 796 | chemical = result[index]; 797 | }); 798 | }); 799 | } 800 | 801 | _buildChemical() { 802 | final int backgroundColor = 0xFFB2FF9E; 803 | final int textColor = 0xFF3C1642; 804 | final size = MediaQuery.of(context).size; 805 | final height = size.height; 806 | final width = size.width; 807 | 808 | return EasyRefresh( 809 | refreshHeader: MaterialHeader( 810 | key: _headerKey8, 811 | ), 812 | child: SingleChildScrollView( 813 | child: Container( 814 | color: Color(backgroundColor), 815 | height: height, 816 | padding: EdgeInsets.fromLTRB(15.0, 0, 15.0, 0), 817 | alignment: Alignment.center, 818 | child: Container( 819 | child: Column( 820 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 821 | children: [ 822 | Padding( 823 | padding: EdgeInsets.only(top: 40), 824 | child: Text( 825 | '化学方程式', 826 | style: TextStyle( 827 | color: Color(textColor), 828 | fontSize: 15, 829 | height: 1.3, 830 | ), 831 | )), 832 | Padding( 833 | padding: EdgeInsets.only(bottom: height * 0.4), 834 | child: Column( 835 | children: [ 836 | Padding( 837 | padding: EdgeInsets.only(bottom: 50), 838 | child: chemical == null 839 | ? null 840 | : Image.memory( 841 | Base64Decoder().convert(chemical), 842 | width: width * 0.6)), 843 | ], 844 | ), 845 | ) 846 | ], 847 | )))), 848 | onRefresh: () async { 849 | _loadChemical(); 850 | }, 851 | ); 852 | } 853 | 854 | _buildRepo() { 855 | final int backgroundColor = 0xFF2541B2; 856 | final int textColor = 0xFFFFFFFF; 857 | final height = MediaQuery.of(context).size.height; 858 | 859 | return EasyRefresh( 860 | refreshHeader: MaterialHeader( 861 | key: _headerKey9, 862 | ), 863 | child: SingleChildScrollView( 864 | child: Container( 865 | color: Color(backgroundColor), 866 | height: height, 867 | padding: EdgeInsets.fromLTRB(30.0, 0, 30.0, 0), 868 | alignment: Alignment.center, 869 | child: Container( 870 | child: Column( 871 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 872 | children: [ 873 | Padding( 874 | padding: EdgeInsets.only(top: 40), 875 | child: Text( 876 | 'Github Repository', 877 | style: TextStyle( 878 | color: Color(textColor), 879 | fontSize: 15, 880 | height: 1.3, 881 | ), 882 | )), 883 | Padding( 884 | padding: EdgeInsets.only(bottom: height * 0.42), 885 | child: Column( 886 | children: [ 887 | InkWell( 888 | child: Text( 889 | repo['name'], 890 | style: TextStyle( 891 | color: Color(textColor), 892 | fontSize: 20, 893 | height: 1.3, 894 | ), 895 | ), 896 | onTap: () => launch(repo['url'])), 897 | Padding( 898 | padding: EdgeInsets.fromLTRB(0, 10, 0, 30), 899 | child: AutoSizeText( 900 | repo['description'], 901 | style: TextStyle( 902 | color: Color(textColor), 903 | fontSize: 15, 904 | height: 1.3, 905 | ), 906 | maxLines: 5, 907 | )), 908 | Row( 909 | mainAxisAlignment: MainAxisAlignment.center, 910 | children: [ 911 | Icon(Icons.star, color: Color(textColor)), 912 | Text( 913 | repo['stars'], 914 | style: TextStyle( 915 | color: Color(textColor), 916 | fontSize: 17, 917 | height: 1.2, 918 | ), 919 | ), 920 | Padding( 921 | padding: EdgeInsets.only(left: 20), 922 | child: Icon(AntDesign.getIconData("fork"), 923 | color: Color(textColor), size: 17)), 924 | Text( 925 | repo['forks'], 926 | style: TextStyle( 927 | color: Color(textColor), 928 | fontSize: 17, 929 | height: 1.2, 930 | ), 931 | ), 932 | ], 933 | ) 934 | ], 935 | ), 936 | ) 937 | ], 938 | )))), 939 | onRefresh: () async { 940 | _loadRepo(); 941 | }, 942 | ); 943 | } 944 | 945 | _loadRepo() { 946 | API.repo().then((obj) { 947 | setState(() { 948 | repo = obj; 949 | }); 950 | }); 951 | } 952 | 953 | _buildZhihuDaily() { 954 | final int backgroundColor = 0xFF944BBB; 955 | final int textColor = 0xFFE6C79C; 956 | final height = MediaQuery.of(context).size.height; 957 | 958 | return EasyRefresh( 959 | refreshHeader: MaterialHeader( 960 | key: _headerKey10, 961 | ), 962 | child: SingleChildScrollView( 963 | child: Container( 964 | color: Color(backgroundColor), 965 | height: height, 966 | padding: EdgeInsets.fromLTRB(30.0, 0, 30.0, 0), 967 | alignment: Alignment.center, 968 | child: Container( 969 | child: Column( 970 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 971 | children: [ 972 | Padding( 973 | padding: EdgeInsets.only(top: 40), 974 | child: Text( 975 | '知乎日报', 976 | style: TextStyle( 977 | color: Color(textColor), 978 | fontSize: 15, 979 | height: 1.3, 980 | ), 981 | )), 982 | Padding( 983 | padding: EdgeInsets.only(bottom: height * 0.5), 984 | child: InkWell( 985 | child: Text( 986 | zhihuDaily['title'], 987 | style: TextStyle( 988 | color: Color(textColor), 989 | fontSize: 20, 990 | height: 1.3, 991 | ), 992 | ), 993 | onTap: () => launch('https://daily.zhihu.com/story/' + 994 | zhihuDaily["id"].toString()))) 995 | ], 996 | )))), 997 | onRefresh: () async { 998 | _loadZhihuDaily(); 999 | }, 1000 | ); 1001 | } 1002 | 1003 | _loadZhihuDaily() { 1004 | API.zhihuDaily().then((obj) { 1005 | setState(() { 1006 | zhihuDaily = obj; 1007 | }); 1008 | }); 1009 | } 1010 | 1011 | _loadTodayInHistory() { 1012 | API.todayInHistory().then((obj) { 1013 | setState(() { 1014 | today = obj; 1015 | }); 1016 | }); 1017 | } 1018 | 1019 | _buildTodayInHistory() { 1020 | final int backgroundColor = 0xFF06AED5; 1021 | final int textColor = 0xFFFFF1D0; 1022 | final height = MediaQuery.of(context).size.height; 1023 | 1024 | return EasyRefresh( 1025 | refreshHeader: MaterialHeader( 1026 | key: _headerKey11, 1027 | ), 1028 | child: SingleChildScrollView( 1029 | child: Container( 1030 | color: Color(backgroundColor), 1031 | height: height, 1032 | padding: EdgeInsets.fromLTRB(30.0, 0, 30.0, 0), 1033 | alignment: Alignment.center, 1034 | child: Container( 1035 | child: Column( 1036 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 1037 | children: [ 1038 | Padding( 1039 | padding: EdgeInsets.only(top: 40), 1040 | child: Text( 1041 | '历史上的今天', 1042 | style: TextStyle( 1043 | color: Color(textColor), 1044 | fontSize: 15, 1045 | height: 1.3, 1046 | ), 1047 | )), 1048 | Padding( 1049 | padding: EdgeInsets.only(bottom: height * 0.42), 1050 | child: Column( 1051 | children: [ 1052 | Padding( 1053 | padding: EdgeInsets.only(bottom: 30), 1054 | child: Text( 1055 | today['content'], 1056 | style: TextStyle( 1057 | color: Color(textColor), 1058 | fontSize: 22.0, 1059 | height: 1.3, 1060 | ), 1061 | )), 1062 | Text( 1063 | today['day'], 1064 | style: TextStyle( 1065 | color: Color(textColor), 1066 | fontSize: 15, 1067 | height: 1.3, 1068 | ), 1069 | ) 1070 | ], 1071 | ), 1072 | ) 1073 | ], 1074 | )))), 1075 | onRefresh: () async { 1076 | _loadTodayInHistory(); 1077 | }, 1078 | ); 1079 | } 1080 | 1081 | _loadOneArticle() { 1082 | API.oneArticle().then((result) { 1083 | setState(() { 1084 | oneArticle = result; 1085 | }); 1086 | }); 1087 | } 1088 | 1089 | _buildOneArticle() { 1090 | final int textColor = 0xFFFFF1D0; 1091 | final height = MediaQuery.of(context).size.height; 1092 | 1093 | return EasyRefresh( 1094 | refreshHeader: MaterialHeader( 1095 | key: _headerKey12, 1096 | ), 1097 | child: Container( 1098 | color: Colors.blueGrey, 1099 | height: height, 1100 | alignment: Alignment.center, 1101 | child: Container( 1102 | padding: EdgeInsets.fromLTRB(20, 30, 20, 0), 1103 | child: Column( 1104 | mainAxisAlignment: MainAxisAlignment.start, 1105 | children: [ 1106 | //标题 1107 | Text( 1108 | oneArticle['title'], 1109 | style: TextStyle( 1110 | color: Color(textColor), 1111 | fontSize: 23, 1112 | ), 1113 | ), 1114 | //作者 1115 | Padding( 1116 | padding: EdgeInsets.fromLTRB(0, 10, 0, 10), 1117 | child: Text( 1118 | oneArticle['author'], 1119 | style: TextStyle( 1120 | color: Color(textColor), 1121 | ), 1122 | ), 1123 | ), 1124 | //正文 1125 | Expanded( 1126 | child: SingleChildScrollView( 1127 | padding: EdgeInsets.only(bottom: 30), 1128 | child: Text( 1129 | oneArticle['content'], 1130 | style: TextStyle( 1131 | fontSize: 16, 1132 | color: Color(textColor), 1133 | ), 1134 | ), 1135 | ), 1136 | ), 1137 | ], 1138 | ), 1139 | ), 1140 | ), 1141 | onRefresh: () async { 1142 | _loadOneArticle(); 1143 | }, 1144 | ); 1145 | } 1146 | } 1147 | --------------------------------------------------------------------------------