提交 dfd85037 authored 作者: yueweilu's avatar yueweilu

add

上级 a4b68652
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
version:
revision: 84a1e904f44f9b0e9c4510138010edcc653163f8
channel: stable
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8
base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8
- platform: android
create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8
base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8
- platform: ios
create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8
base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
# flutter_book
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace "com.zijin.book.flutter_book"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.zijin.book.flutter_book"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
package com.zijin.book.flutter_book;
import io.flutter.embedding.android.FlutterActivity;
public class MainActivity extends FlutterActivity {
}
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
PODS:
- Flutter (1.0.0)
- flutter_tts (0.0.1):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_tts (from `.symlinks/plugins/flutter_tts/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_tts:
:path: ".symlinks/plugins/flutter_tts/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
PODFILE CHECKSUM: 02caaa843f6501172c0d470d80e72f61175c8b93
COCOAPODS: 1.11.2
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
297D4B521D4A45CEFC018F23 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D9746A3A42B49971E109B58 /* libPods-Runner.a */; };
331C80F4294D02FB00263BE5 /* RunnerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 331C80F3294D02FB00263BE5 /* RunnerTests.m */; };
389E384DCE26FA37EA2BA4FF /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E360DC6E27A1D286B37E030A /* libPods-RunnerTests.a */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C80F5294D02FB00263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1D32EB398235AD2BE8600068 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
331C80F1294D02FB00263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
331C80F3294D02FB00263BE5 /* RunnerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerTests.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3CA9A1798566CFB3C56D42A1 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
42E1283DBA824C1906B1C857 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
7D9746A3A42B49971E109B58 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D9823D2E103E4E3DCED32D6E /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
E360DC6E27A1D286B37E030A /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
EC29B8E2BC54E4C58DEC128C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
F5C7DF67C742AA0A5A6AF22A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
331C80EE294D02FB00263BE5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
389E384DCE26FA37EA2BA4FF /* libPods-RunnerTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
297D4B521D4A45CEFC018F23 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331C80F2294D02FB00263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C80F3294D02FB00263BE5 /* RunnerTests.m */,
);
path = RunnerTests;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
331C80F2294D02FB00263BE5 /* RunnerTests */,
97C146EF1CF9000F007C117D /* Products */,
D89318379B32A72620402A57 /* Pods */,
DEAEA83548321DAC7AAEFA5B /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C80F1294D02FB00263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
);
path = Runner;
sourceTree = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
97C146F21CF9000F007C117D /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
D89318379B32A72620402A57 /* Pods */ = {
isa = PBXGroup;
children = (
1D32EB398235AD2BE8600068 /* Pods-Runner.debug.xcconfig */,
F5C7DF67C742AA0A5A6AF22A /* Pods-Runner.release.xcconfig */,
EC29B8E2BC54E4C58DEC128C /* Pods-Runner.profile.xcconfig */,
D9823D2E103E4E3DCED32D6E /* Pods-RunnerTests.debug.xcconfig */,
42E1283DBA824C1906B1C857 /* Pods-RunnerTests.release.xcconfig */,
3CA9A1798566CFB3C56D42A1 /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
DEAEA83548321DAC7AAEFA5B /* Frameworks */ = {
isa = PBXGroup;
children = (
7D9746A3A42B49971E109B58 /* libPods-Runner.a */,
E360DC6E27A1D286B37E030A /* libPods-RunnerTests.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C80F0294D02FB00263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C80F7294D02FB00263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
B43297EA9857A81E0E7B6100 /* [CP] Check Pods Manifest.lock */,
331C80ED294D02FB00263BE5 /* Sources */,
331C80EE294D02FB00263BE5 /* Frameworks */,
331C80EF294D02FB00263BE5 /* Resources */,
);
buildRules = (
);
dependencies = (
331C80F6294D02FB00263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C80F1294D02FB00263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
385593853978697595401F12 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C80F0294D02FB00263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C80F0294D02FB00263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C80EF294D02FB00263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
385593853978697595401F12 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
B43297EA9857A81E0E7B6100 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
331C80ED294D02FB00263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C80F4294D02FB00263BE5 /* RunnerTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
97C146F31CF9000F007C117D /* main.m in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C80F6294D02FB00263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C80F5294D02FB00263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "紫荆云书";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zijin.book.flutterBook;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C80F8294D02FB00263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = D9823D2E103E4E3DCED32D6E /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.zijin.book.flutterBook.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C80F9294D02FB00263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 42E1283DBA824C1906B1C857 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.zijin.book.flutterBook.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C80FA294D02FB00263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3CA9A1798566CFB3C56D42A1 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.zijin.book.flutterBook.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "紫荆云书";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zijin.book.flutterBook;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "紫荆云书";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.books";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.zijin.book.flutterBook;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C80F7294D02FB00263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C80F8294D02FB00263BE5 /* Debug */,
331C80F9294D02FB00263BE5 /* Release */,
331C80FA294D02FB00263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C80F0294D02FB00263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
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.
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Flutter Book</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_book</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char* argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
@interface RunnerTests : XCTestCase
@end
@implementation RunnerTests
- (void)testExample {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
@end
part of apis;
abstract class AccountAPI {
static Future <UserModel> login({
required String phone,
required String password,
required String type,
}) async {
final result = await HttpService.to.post(
'/v1/members/login/login',
excludeToken: true,
showLoading: true,
params: {
'phone': phone,
'password': password,
'type': type
},
);
if (result.data is! Map) return UserModel();
return UserModel.fromJson(result.data);
}
}
\ No newline at end of file
library apis;
import 'dart:io';
import '../models/user_model.dart';
import '../services/index.dart';
part 'account.dart';
\ No newline at end of file
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter_book/services/index.dart';
import 'package:flutter_book/store/index.dart';
import 'package:get/get.dart';
class Global {
static Future<void> init() async {
// 确保 Flutter 绑定已经初始化
WidgetsFlutterBinding.ensureInitialized();
// 设置应用程序的首选屏幕方向
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
await Future.wait([
// 配置存储
Get.putAsync<StorageService>(() => StorageService().init()),
]).whenComplete(() {
// 网络
Get.put<HttpService>(HttpService());
//配置基本设置
Get.put<ConfigStore>(ConfigStore());
//
Get.put<UserStore>(UserStore());
});
}
}
\ No newline at end of file
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_book/routes/index.dart';
import 'package:flutter_book/store/index.dart';
import 'package:flutter_book/theme.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'global.dart';
void main() {
Global.init().then((_) => runApp(const MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}): super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(428, 926),
builder: (context, child) => RefreshConfiguration(
headerBuilder: () => const ClassicHeader(
refreshingIcon: CupertinoActivityIndicator(),
),
footerBuilder: () => const ClassicFooter(
loadingIcon: CupertinoActivityIndicator(),
),
hideFooterWhenNotFull: true,
child: GetBuilder<ConfigStore>(
builder: (config) => MaterialApp.router(
debugShowCheckedModeBanner: false,
title: '紫荆云书',
theme: AppTheme.light,
darkTheme: AppTheme.dark,
themeMode: AppTheme.mode,
routerConfig: Routes.config,
builder: CustomToast.init(
context: context,
builder: (context, child) {
return ScrollConfiguration(
behavior: _NoShadowScrollBehavior(),
child: child ?? const Material(),
);
},
),
// localizationsDelegates: const [
// GlobalMaterialLocalizations.delegate,
// GlobalWidgetsLocalizations.delegate,
// GlobalCupertinoLocalizations.delegate,
// // S.delegate,
// ],
// locale: config.locale,
// supportedLocales: S.delegate.supportedLocales,
),
),
)
);
}
}
class _NoShadowScrollBehavior extends ScrollBehavior {
@override
Widget buildOverscrollIndicator(
BuildContext context,
Widget child,
ScrollableDetails details,
) {
switch (getPlatform(context)) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return child;
case TargetPlatform.android:
return GlowingOverscrollIndicator(
showLeading: false,
showTrailing: false,
axisDirection: details.direction,
color: Theme.of(context).colorScheme.primary,
child: child,
);
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
return GlowingOverscrollIndicator(
showLeading: false,
showTrailing: false,
axisDirection: details.direction,
color: Theme.of(context).colorScheme.primary,
child: child,
);
}
}
}
library models;
part 'response.dart';
\ No newline at end of file
part of models;
class ResponseModel {
ResponseModel({
this.code,
this.msg,
this.data,
});
ResponseModel.fromJson(dynamic json) {
code = int.tryParse(json['code'].toString());
msg = json['msg']?.toString();
data = json['data'];
}
int? code;
String? msg;
dynamic data;
ResponseModel copyWith({
int? code,
String? msg,
dynamic data,
}) =>
ResponseModel(
code: code ?? this.code,
msg: msg ?? this.msg,
data: data ?? this.data,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['code'] = code;
map['msg'] = msg;
map['data'] = data;
return map;
}
}
/// members_id : 1
/// name : "555555"
/// password : "637641045c830d80190da7b94f69c2cd"
/// head_img : "http://192.168.11.67:9090/static/images/20210820182011.png"
/// sex : 1
/// birthday : "2020-01-01"
/// phone : "13532236565"
/// grade_id : 1
/// badge_id : 1
/// token : "e8410f5092b809a80956b5f01de75035"
/// access_token : "members_access_token:be48312274defc9ee894c088b7a3be74"
/// grade_name : "等级1"
class UserModel {
UserModel({
this.membersId,
this.name,
this.password,
this.headImg,
this.sex,
this.birthday,
this.phone,
this.gradeId,
this.badgeId,
this.token,
this.accessToken,
this.gradeName,});
num? membersId;
String? name;
String? password;
String? headImg;
num? sex;
String? birthday;
String? phone;
num? gradeId;
num? badgeId;
String? token;
String? accessToken;
String? gradeName;
UserModel.fromJson(dynamic json) {
membersId = json['members_id'];
name = json['name'];
password = json['password'];
headImg = json['head_img'];
sex = json['sex'];
birthday = json['birthday'];
phone = json['phone'];
gradeId = json['grade_id'];
badgeId = json['badge_id'];
token = json['token'];
accessToken = json['access_token'];
gradeName = json['grade_name'];
}
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['members_id'] = membersId;
map['name'] = name;
map['password'] = password;
map['head_img'] = headImg;
map['sex'] = sex;
map['birthday'] = birthday;
map['phone'] = phone;
map['grade_id'] = gradeId;
map['badge_id'] = badgeId;
map['token'] = token;
map['access_token'] = accessToken;
map['grade_name'] = gradeName;
return map;
}
}
\ No newline at end of file
part of home;
\ No newline at end of file
library home;
import 'package:flutter/material.dart';
part 'view.dart';
part 'controller.dart';
\ No newline at end of file
part of home;
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.cyan,
),
);
}
}
part of main;
class MainController extends GetxController {
late final PageController pageController;
//默认显示
int currentPage = 0;
@override
void onInit() {
super.onInit();
pageController = PageController(initialPage: currentPage);
}
@override
void onClose() {
pageController.dispose();
super.onClose();
}
void onPageChanged(int page) {
currentPage = page;
update(['navigation']);
}
}
\ No newline at end of file
library main;
import 'package:flutter/material.dart';
import 'package:flutter_book/pages/home/index.dart';
import 'package:flutter_book/theme.dart';
import 'package:get/get.dart';
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
import 'package:ionicons/ionicons.dart';
import '../test_tts.dart';
part 'view.dart';
part 'controller.dart';
\ No newline at end of file
part of main;
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> with WidgetsBindingObserver{
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void didChangePlatformBrightness() {
super.didChangePlatformBrightness();
AppTheme.setSystemStyle();
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
return GetBuilder<MainController>(
init: MainController(),
builder: (controller) => Scaffold(
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: controller.pageController,
onPageChanged: controller.onPageChanged,
children: const [
HomePage(),
TestTTSPage(),
HomePage(),
HomePage(),
],
),
bottomNavigationBar: GetBuilder<MainController>(
id: 'navigation',
builder: (controller) => BottomNavigationBar(
currentIndex:controller.currentPage ,
onTap: (page){
controller.pageController.jumpToPage(page);
},
items: const [
BottomNavigationBarItem(
icon: Icon(Ionicons.home_outline),
activeIcon:Icon(Ionicons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Ionicons.apps_outline),
activeIcon:Icon(Ionicons.apps),
label: '图书馆',
),
BottomNavigationBarItem(
icon: Icon(Ionicons.chatbubbles_outline),
activeIcon:Icon(Ionicons.chatbubbles),
label: '购物车',
),
BottomNavigationBarItem(
icon: Icon(Ionicons.person_outline),
activeIcon:Icon(Ionicons.person),
label: '我的',
)
]
),
),
)
);
}
}
library splash_page;
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_book/apis/index.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:go_router/go_router.dart';
import '../../routes/index.dart';
import '../../utils/index.dart';
part 'view.dart';
\ No newline at end of file
part of splash_page;
class SplashPage extends StatefulWidget {
const SplashPage({Key? key}) : super(key: key);
@override
State<SplashPage> createState() => _SplashPageState();
}
class _SplashPageState extends State<SplashPage> {
@override
void initState() {
super.initState();
Future.wait([
Future.delayed(const Duration(seconds: 1))
]).whenComplete(() async {
// final userModel = await AccountAPI.login(phone: '18337678567', password: '013790d7eb52197bead4c757ebfae7cf', type: '1');
// Console.log('++++++++++++++++');
// Console.log(userModel.name);
context.goNamed(Routes.main);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(),
body: const Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 5,
child: Center(
child: CustomEmpty(
icon: CustomImage.asset(
url: 'assets/images/logo.png',
fit: BoxFit.contain,
),
title: Text('云书'),
),
)
),
Expanded(
flex: 2,
child: Center(child: CupertinoActivityIndicator(),),
)
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:flutter_book/utils/index.dart';
class TestTTSPage extends StatefulWidget {
const TestTTSPage({Key? key}) : super(key: key);
@override
State<TestTTSPage> createState() => _TestTTSPageState();
}
class _TestTTSPageState extends State<TestTTSPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('测试语音'),
centerTitle: true,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Colors.yellow,
height: 150,
width: double.infinity,
// padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: const Text('你好我是小助手',textAlign: TextAlign.start,style: TextStyle(
color: Colors.black,
fontSize: 18
),),
),
GestureDetector(
onTap: (){
Console.log('你好');
},
child: Container(
margin: const EdgeInsets.all(10),
padding: const EdgeInsets.all(20),
color: Colors.red,
child: const Text('播放'),
),
)
],
),
);
}
}
library routes;
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_book/pages/main/index.dart';
import 'package:flutter_book/pages/splash/index.dart';
import 'package:go_router/go_router.dart';
part 'observers.dart';
part 'routes.dart';
\ No newline at end of file
part of routes;
class RouteObservers<R extends Route<dynamic>> extends RouteObserver<R> {
@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPush(route, previousRoute);
final name = route.settings.name ?? '';
if (name.isNotEmpty) Routes.history.add(name);
if (kDebugMode) {
print('didPush');
print(Routes.history);
}
}
@override
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didPop(route, previousRoute);
Routes.history.remove(route.settings.name);
if (kDebugMode) {
print('didPop');
print(Routes.history);
}
}
@override
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
if (newRoute != null) {
final index = Routes.history.indexWhere((element) {
return element == oldRoute?.settings.name;
});
final name = newRoute.settings.name ?? '';
if (name.isNotEmpty) {
if (index > -1) {
Routes.history[index] = name;
} else {
Routes.history.add(name);
}
}
}
if (kDebugMode) {
print('didReplace');
print(Routes.history);
}
}
@override
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
super.didRemove(route, previousRoute);
Routes.history.remove(route.settings.name);
if (kDebugMode) {
print('didRemove');
print(Routes.history);
}
}
}
part of routes;
abstract class Routes {
static final RouteObserver<Route> observer = RouteObservers();
static List<String> history = [];
static const splash = 'splash';
static const main = 'main';
static final GoRouter config = GoRouter(
initialLocation: '/$splash',
observers: [observer],
routes: [
GoRoute(
path: '/$splash',
name: splash,
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: const SplashPage(),
),
),
GoRoute(
path: '/',
name: main,
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: const MainPage()
)
)
]
);
}
\ No newline at end of file
part of services;
class HttpService extends GetxService {
static HttpService get to => Get.find();
late final Dio _dio;
@override
void onInit() {
super.onInit();
final options = BaseOptions(
baseUrl: kServerUrl,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds:10),
headers: {},
contentType: Headers.jsonContentType,
responseType: ResponseType.json
);
_dio = Dio(options);
_dio.interceptors.add(_RequestInterceptor());
}
/// 组织 headers 参数
Map<String,dynamic>? _getHeaders({bool excludeToken = false,Map<String,dynamic>? params,String? url}) {
final headers = <String, dynamic>{};
if (Get.isRegistered<UserStore>() &&
UserStore.to.hasToken && !excludeToken) {
// headers['Token'] = UserStore.to.token;
headers['token'] = UserStore.to.token;
if (params != null) {
params.addAll(headers);
}
headers['Sign'] = SignTool.createSign(params!);
} else{
headers['appId'] = AppConfig.AppID;
headers['appSecret'] = AppConfig.AppSecret;
headers['timestamp'] = (DateTime.now().millisecondsSinceEpoch~/1000).toString();
headers['url'] = kServerUrl + url.toString();
headers['token'] = '';
if (params != null) {
params.addAll(headers);
}
headers['Sign'] = SignTool.createSign(params!);
}
return headers;
}
/// get
Future<ResponseModel> get(
String url,{
Map<String, dynamic>? params,
Options? options,
CancelToken? cancelToken,
bool excludeToken = false,
bool showLoading = false,
}) async {
if (showLoading) CustomToast.loading();
try {
final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url);
final response = await _dio.get(
url,
queryParameters: params,
options: requestOptions,
cancelToken: cancelToken,
);
if (showLoading) CustomToast.dismiss();
return ResponseModel.fromJson(response.data);
} catch (error){
if (error is! DioException) CustomToast.dismiss();
rethrow;
}
}
/// post
Future<ResponseModel> post(
String url,{
Map<String,dynamic>? params,
Options? options,
CancelToken? cancelToken,
bool excludeToken = false,
bool showLoading = false,
}) async{
if (showLoading) CustomToast.loading();
try {
final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,params: params,url: url);
final response = await _dio.post(
url,
data: params,
options: requestOptions,
cancelToken: cancelToken,
);
if (showLoading) CustomToast.dismiss();
return ResponseModel.fromJson(response.data);
} catch (error){
if (error is! DioException) CustomToast.dismiss();
rethrow;
}
}
/// upload
Future<ResponseModel> upload(
String url, {
required String path,
Options? options,
CancelToken? cancelToken,
bool excludeToken = false,
ProgressCallback? onSendProgress,
})async {
final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,url:url);
final name = path.substring(path.lastIndexOf('/') + 1,path.length);
final image = await MultipartFile.fromFile(path, filename: name);
final formData = FormData.fromMap({'file':image});
final response = await _dio.post(
url,
data:formData,
options:requestOptions,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
);
return ResponseModel.fromJson(response.data);
}
/// download
Future<void> download(
String url,{
required String savePath,
Options? options,
CancelToken? cancelToken,
bool excludeToken = false,
ProgressCallback? onReceiveProgress,
}) async {
try{
final requestOptions = options ?? Options();
requestOptions.headers = _getHeaders(excludeToken: excludeToken,url: url);
await _dio.download(
url,
savePath,
options: requestOptions,
cancelToken: cancelToken,
onReceiveProgress: onReceiveProgress
);
Console.log('Download completed:$savePath');
}catch(e){
Console.log(e);
rethrow;
}
}
}
class _RequestInterceptor extends Interceptor {
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
Console.log('--------------------------------');
if (response.data['code'] != 200) {
handler.reject(
DioException(
requestOptions: response.requestOptions,
response: response,
type: DioExceptionType.badResponse,
),
true,
);
} else {
super.onResponse(response, handler);
}
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
Console.log(err.type);
switch (err.type) {
case DioExceptionType.connectionTimeout:
CustomToast.fail('网络连接超时');
break;
case DioExceptionType.sendTimeout:
CustomToast.fail('发送超时');
break;
case DioExceptionType.receiveTimeout:
CustomToast.fail('接收超时');
break;
case DioExceptionType.badCertificate:
CustomToast.fail('证书错误');
break;
case DioExceptionType.badResponse:
final response = err.response;
final statusCode = response?.statusCode;
// Console.log(response?.data);
final code = int.tryParse(response?.data['code']?.toString() ?? '');
var msg = '服务器错误';
switch (statusCode) {
case 401:
msg = '$statusCode - Unauthorized';
break;
case 404:
msg = '$statusCode - Server not found';
break;
case 500:
msg = '$statusCode - Server error';
break;
case 502:
msg = '$statusCode - Bad gateway';
break;
default:
if (code == 901) UserStore.to.logout();
msg = response?.data?['msg']?.toString() ?? msg;
break;
}
CustomToast.fail(msg);
break;
case DioExceptionType.cancel:
Console.log('请求取消');
break;
case DioExceptionType.connectionError:
CustomToast.fail('网络连接失败');
break;
case DioExceptionType.unknown:
CustomToast.fail('请求发生未知错误');
break;
}
super.onError(err, handler);
}
}
library services;
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter_book/store/index.dart';
import 'package:flutter_book/utils/index.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:get/get.dart' hide Response, FormData, MultipartFile;
import 'package:shared_preferences/shared_preferences.dart';
import '../models/index.dart';
export 'package:dio/dio.dart';
part 'storage.dart';
part 'http.dart';
part 'interceptor.dart';
\ No newline at end of file
part of services;
class AuthInterceptor extends Interceptor {
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final token = UserStore.to.token;
super.onRequest(options, handler);
}
}
part of services;
class StorageService extends GetxService {
static StorageService get to => Get.find();
late final SharedPreferences _prefs;
///初始化 StorageService
Future<StorageService> init() async {
_prefs = await SharedPreferences.getInstance();
// 返回 StorageService 实例
return this;
}
///存储字符串
Future<bool> setString(String key, String value) async {
return await _prefs.setString(key, value);
}
///存储bool类型
Future<bool> setBool(String key, bool value) async {
return await _prefs.setBool(key, value);
}
///存储list类型
Future<bool> setList(String key, List<String> value) async{
return await _prefs.setStringList(key, value);
}
///获取字符串
String getString(String key) {
return _prefs.getString(key) ?? '';
}
///获取bool
bool getBool(String key) {
return _prefs.getBool(key) ?? false;
}
///获取list
List<String> getList(String key) {
return _prefs.getStringList(key) ?? [];
}
///移除key
Future<bool> remove(String key) async {
return await _prefs.remove(key);
}
}
\ No newline at end of file
part of store;
class ConfigStore extends GetxController {
static ConfigStore get to => Get.find();
@override
void onInit() {
super.onInit();
_initThemeMode();
}
/// 主题模式
void _initThemeMode() {
final theme = StorageService.to.getString(C.localThemeMode);
switch (theme) {
case C.themeLight:
AppTheme.mode = ThemeMode.light;
break;
case C.themeDark:
AppTheme.mode = ThemeMode.dark;
break;
default:
AppTheme.mode = ThemeMode.system;
break;
}
AppTheme.setSystemStyle();
}
}
\ No newline at end of file
library store;
import 'package:flutter/material.dart';
import 'package:flutter_book/services/index.dart';
import 'package:flutter_book/theme.dart';
import 'package:get/get.dart';
import '../utils/index.dart';
part 'config.dart';
part 'user.dart';
\ No newline at end of file
part of store;
class UserStore extends GetxController {
// 获取 UserStore 实例
static UserStore get to => Get.find();
// 是否登录
bool _isLogin = false;
String _token = '';
String get token => _token;
bool get isLogin=> _isLogin;
bool get hasToken => _token.isNotEmpty;
@override
void onInit() {
super.onInit();
_token = StorageService.to.getString(kLocalToken);
}
Future<void> setToken(String value) async {
await StorageService.to.setString(kLocalToken, value);
_token = value;
}
// 登出
Future<void> logout() async {
await StorageService.to.remove(kLocalToken);
_token = '';
_isLogin = false;
}
}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_book/utils/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
abstract class AppTheme {
// 应用程序默认边距
static const margin = 16.0;
// 主要/主题颜色的常量
static const primary = Color(0xFF2972FE);
// 成功状态的颜色
static const success = Color(0xFF23A757);
// 警告状态的颜色
static const warning = Color(0xFFFF1843);
// 错误状态的颜色
static const error = Color(0xFFDA1414);
// 信息/提示状态的颜色
static const info = Color(0xFF2E5AAC);
static ThemeMode mode = ThemeMode.system;
// 系统主题
static SystemUiOverlayStyle get systemStyle => const SystemUiOverlayStyle(
// 状态栏(位于屏幕顶部的区域)的颜色
statusBarColor: Colors.transparent,
// 设置状态栏中元素(如文字、图标)的亮度
statusBarBrightness: Brightness.light,
statusBarIconBrightness: Brightness.dark,
systemNavigationBarDividerColor: Colors.transparent,
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.dark
);
// 亮色主题
static SystemUiOverlayStyle get systemStyleLight => systemStyle.copyWith(
statusBarBrightness: Brightness.light,
statusBarIconBrightness: Brightness.dark,
systemNavigationBarIconBrightness: Brightness.dark
);
// 暗色主题
static SystemUiOverlayStyle get systemStyleDark => systemStyle.copyWith(
statusBarBrightness: Brightness.dark,
statusBarIconBrightness: Brightness.light,
systemNavigationBarColor: const Color(0xFF0D0D0D),
systemNavigationBarIconBrightness: Brightness.light
);
/// 设置主题
static void setSystemStyle() {
switch (mode) {
case ThemeMode.system:
if (Screen.mediaQuery.platformBrightness == Brightness.dark) {
SystemChrome.setSystemUIOverlayStyle(systemStyleDark);
} else {
SystemChrome.setSystemUIOverlayStyle(systemStyleLight);
}
break;
case ThemeMode.light:
SystemChrome.setSystemUIOverlayStyle(systemStyleLight);
break;
case ThemeMode.dark:
SystemChrome.setSystemUIOverlayStyle(systemStyleDark);
break;
}
}
static ThemeData get light {
var scheme = ColorScheme.light(
background: Colors.white,
onBackground: const Color(0xFF333333),
surface: Colors.white,
onSurface: const Color(0xFF333333),
primary: primary,
onPrimary: Colors.white,
secondary: const Color(0xFFFFB800),
onSecondary: Colors.white,
tertiary: const Color(0xFFF4F6F9),
outline: const Color(0xFFF4F6F9),
shadow: const Color(0xFF5A6CEA).withOpacity(0.08),
error: error,
onError: Colors.white,
);
return _getTheme(scheme);
}
static ThemeData get dark {
var scheme = ColorScheme.dark(
background: const Color(0xFF0D0D0D),
onBackground: Colors.white,
surface: const Color(0xFF252525),
onSurface: Colors.white,
primary: primary,
onPrimary: Colors.white,
secondary: const Color(0xFFFFB800),
onSecondary: Colors.white,
tertiary: const Color(0xFF141414),
outline: const Color(0xFF252525),
shadow: const Color(0xFF777777).withOpacity(0.08),
error: error,
onError: Colors.white,
);
return _getTheme(scheme);
}
static ThemeData _getTheme(ColorScheme scheme) {
return ThemeData(
useMaterial3: false,
colorScheme: scheme,
scaffoldBackgroundColor: scheme.background,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
dialogTheme: DialogTheme(
elevation: 0,
titleTextStyle: TextStyle(
fontSize: 22.w,
fontWeight: FontWeight.w600,
),
contentTextStyle: TextStyle(fontSize: 20.w),
backgroundColor: scheme.brightness == Brightness.light
? scheme.surface
: scheme.tertiary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.w),
),
),
bottomSheetTheme: BottomSheetThemeData(
elevation: 0,
backgroundColor: scheme.brightness == Brightness.light
? scheme.surface
: scheme.tertiary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.w),
topRight: Radius.circular(30.w),
),
),
),
appBarTheme: AppBarTheme(
backgroundColor: scheme.background,
scrolledUnderElevation: 0,
elevation: 0,
centerTitle: true,
toolbarHeight: 56.w,
iconTheme: IconThemeData(
color: scheme.onBackground,
size: 22.w,
),
titleTextStyle: TextStyle(
color: scheme.onBackground,
fontSize: 24.w,
fontWeight: FontWeight.w600,
height: 1.2,
),
toolbarTextStyle: TextStyle(
color: scheme.onBackground,
fontSize: 22.w,
fontWeight: FontWeight.w600,
height: 1.2,
),
),
textTheme: TextTheme(
bodyMedium: TextStyle(
fontSize: 16.w,
color: scheme.onBackground,
),
labelLarge: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.w,
height: 1.2,
color: scheme.onBackground,
),
),
bottomAppBarTheme: BottomAppBarTheme(
elevation: 0,
color: scheme.background,
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
type: BottomNavigationBarType.fixed,
elevation: 0,
backgroundColor: scheme.background,
unselectedItemColor: scheme.onBackground.withOpacity(0.5),
selectedItemColor: scheme.primary,
unselectedLabelStyle: TextStyle(fontSize: 13.w, height: 1.6),
selectedLabelStyle: TextStyle(fontSize: 13.w, height: 1.6),
unselectedIconTheme: IconThemeData(
size: 24.w,
color: scheme.onBackground.withOpacity(0.5),
),
selectedIconTheme: IconThemeData(
size: 24.w,
color: scheme.primary,
),
),
outlinedButtonTheme: OutlinedButtonThemeData(
style: ButtonStyle(
elevation: MaterialStateProperty.all(0),
minimumSize: MaterialStateProperty.all(Size.zero),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
overlayColor: MaterialStateProperty.all(Colors.transparent),
),
),
inputDecorationTheme: InputDecorationTheme(
isCollapsed: true,
isDense: true,
filled: true,
fillColor: scheme.surface,
labelStyle: TextStyle(
fontSize: 16.w,
color: scheme.onBackground,
fontWeight: FontWeight.w600,
),
helperStyle: TextStyle(
fontSize: 14.w,
color: scheme.onBackground.withOpacity(0.7),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 20.w,
vertical: 14.w,
),
border: OutlineInputBorder(
borderSide: BorderSide(color: scheme.outline, width: 2.w),
borderRadius: BorderRadius.all(Radius.circular(25.w)),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: scheme.outline, width: 2.w),
borderRadius: BorderRadius.all(Radius.circular(25.w)),
),
disabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: scheme.outline, width: 2.w),
borderRadius: BorderRadius.all(Radius.circular(25.w)),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: scheme.primary, width: 2.w),
borderRadius: BorderRadius.all(Radius.circular(25.w)),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: error, width: 2.w),
borderRadius: BorderRadius.all(Radius.circular(25.w)),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: error, width: 2.w),
borderRadius: BorderRadius.all(Radius.circular(100.w)),
),
),
tabBarTheme: TabBarTheme(
labelColor: scheme.primary,
unselectedLabelColor: scheme.background,
labelStyle: TextStyle(
color: scheme.onPrimary,
fontSize: 16.w,
fontWeight: FontWeight.w600,
),
unselectedLabelStyle: TextStyle(
color: scheme.primary,
fontSize: 16.w,
fontWeight: FontWeight.w600,
),
labelPadding: EdgeInsets.symmetric(horizontal: 6.w),
),
dividerTheme: DividerThemeData(
thickness: 1.w,
color: scheme.onBackground.withOpacity(0.08),
),
);
}
}
\ No newline at end of file
part of utils;
class AppConfig{
//app在服务端注册的id,由后端直接提供
static const String AppID = 'ZTxGRWl6F6erl330';
//app在服务端的秘钥串,由后端直接提供
static const String AppSecret = '0a6521b67cbd5397ce641f791f284bb7';
//签名时使用的加密串,由后端直接提供
static const String AppEncodeKey = 'J2h8a9zK0z%a-k2z';
}
part of utils;
abstract class Console {
static final _log = Logger(filter: _LogFilter());
static void log(dynamic message) => _log.d(message);
}
class _LogFilter extends LogFilter {
@override
bool shouldLog(LogEvent event) => !kReleaseMode;
}
part of utils;
// 服务器地址
const String kServerUrl = 'https://app.vning.com';
const String kLocalToken = 'local_token';
const String kLocalAccount = 'local_account';
const String kLocalPassword = 'local_password';
abstract class C {
static const String localAccount = 'storage_account';
static const String localThemeMode = 'storage_theme_mode';
static const String localLanguage = 'storage_lang';
/// 自动主题
static const String themeSystem = '0';
/// 亮色主题
static const String themeLight = '1';
/// 暗色主题
static const String themeDark = '2';
}
\ No newline at end of file
part of utils;
class EncryptUtil {
/// md5 加密
static String encodeMd5(String data) {
var content = Utf8Encoder().convert(data);
var digest = md5.convert(content);
return hex.encode(digest.bytes);
}
}
\ No newline at end of file
library utils;
import 'dart:convert';
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';
import 'package:crypto/crypto.dart';
import 'package:convert/convert.dart';
part 'constants.dart';
part 'screen.dart';
part 'console.dart';
part 'app_config.dart';
part 'sign.dart';
part 'encrypt_util.dart';
\ No newline at end of file
part of utils;
class Screen {
static MediaQueryData get mediaQuery => MediaQueryData.fromView(
PlatformDispatcher.instance.views.first,
);
/// 获取屏幕宽度
static double get width => mediaQuery.size.width;
/// 获取屏幕高度
static double get height => mediaQuery.size.height;
/// 获取屏幕dp比例
static double get scale => mediaQuery.devicePixelRatio;
/// 获取顶部安全区域
static double get statusBar => mediaQuery.padding.top;
/// 获取底部安全区域
static double get bottomBar => mediaQuery.padding.bottom;
}
part of utils;
class SignTool {
static String createSign(Map<String, dynamic> params) {
Map<String, dynamic> tempParams = keySort(params);
List<String> tempArr = [];
for (String key in tempParams.keys){
tempArr.add("$key=${tempParams[key]}");
}
String tempStr = tempArr.join("&");
String finalString = tempStr + AppConfig.AppEncodeKey;
String finalEncodeStr = EncryptUtil.encodeMd5(EncryptUtil.encodeMd5(finalString));
return finalEncodeStr;
}
///首字母排序得到排序后新的map
static Map<String,dynamic> keySort(Map<String,dynamic> params) {
Map<String, dynamic> tempParam = <String,dynamic>{};
List<String> oldKeys = params.keys.toList();
if(oldKeys.isEmpty) return tempParam;
oldKeys.sort((a,b){
List<int> al = a.codeUnits;
List<int> bl = b.codeUnits;
for(int i = 0;i< al.length;i++){
if(bl.length <= i) return 1;
if(al[i]>bl[i]){
return 1;
}
else if (al[i] < bl[i]){
return -1;
}
}
return 0;
});
for (int i = 0; i< oldKeys.length;i++){
tempParam[oldKeys[i]]= params[oldKeys[i]];
}
return tempParam;
}
}
\ No newline at end of file
part of widgets;
class CustomEmpty extends StatelessWidget {
final Widget? icon;
final Widget? title;
final Widget? label;
final Color? color;
const CustomEmpty({
Key? key,
this.icon,
this.title,
this.label, this.color,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final color = this.color ?? Theme.of(context).colorScheme.primary;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (icon != null)
IconTheme(
data: IconThemeData(color: Colors.white, size: 50.w),
child: Container(
height: 180.w,
alignment: Alignment.center,
decoration: BoxDecoration(
image: DecorationImage(
colorFilter: ColorFilter.mode(color, BlendMode.srcATop),
image: const AssetImage('assets/images/empty.png'),
fit: BoxFit.contain,
),
),
child: Container(
width: 80.w,
height: 80.w,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(28.w)),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color.alphaBlend(color.withOpacity(0.6), Colors.white),
color,
],
),
),
child: icon,
),
),
),
if (title != null)
Padding(
padding: EdgeInsets.only(top: 20.w),
child: DefaultTextStyle.merge(
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 32.w,
fontWeight: FontWeight.w600,
color: Theme.of(context).colorScheme.primary,
),
child: title!,
),
),
if (label != null)
Padding(
padding: EdgeInsets.only(top: 20.w),
child: DefaultTextStyle.merge(
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18.w),
child: label!,
),
),
],
);
}
}
part of widgets;
enum CustomImageType { asset, network, file }
class CustomImage extends StatelessWidget {
final String url;
final CustomImageType type;
final double? width;
final double? height;
final double? radius;
final BoxFit fit;
final ExtendedImageMode mode;
final bool enableSlideOutPage;
final InitGestureConfigHandler? initGestureConfig;
final Widget Function(
BuildContext context,
ImageProvider provider,
Widget completed,
Size? size,
)? builder;
const CustomImage({
Key? key,
required this.url,
required this.type,
this.width,
this.height,
this.radius,
this.fit = BoxFit.cover,
this.builder,
this.mode = ExtendedImageMode.none,
this.enableSlideOutPage = false,
this.initGestureConfig,
}) : super(key: key);
const CustomImage.network({
Key? key,
required this.url,
this.width,
this.height,
this.radius,
this.fit = BoxFit.cover,
this.builder,
}) : type = CustomImageType.network,
mode = ExtendedImageMode.none,
enableSlideOutPage = false,
initGestureConfig = null,
super(key: key);
const CustomImage.asset({
Key? key,
required this.url,
this.width,
this.height,
this.radius,
this.fit = BoxFit.cover,
this.builder,
}) : type = CustomImageType.asset,
mode = ExtendedImageMode.none,
enableSlideOutPage = false,
initGestureConfig = null,
super(key: key);
const CustomImage.file({
Key? key,
required this.url,
this.width,
this.height,
this.radius,
this.fit = BoxFit.cover,
this.builder,
}) : type = CustomImageType.file,
mode = ExtendedImageMode.none,
enableSlideOutPage = false,
initGestureConfig = null,
super(key: key);
@override
Widget build(BuildContext context) {
final borderRadius = BorderRadius.all(Radius.circular(radius ?? 8.w));
switch (type) {
case CustomImageType.asset:
return ExtendedImage.asset(
url,
width: width,
height: height,
fit: fit,
shape: BoxShape.rectangle,
borderRadius: borderRadius,
mode: mode,
enableSlideOutPage: enableSlideOutPage,
initGestureConfigHandler: initGestureConfig,
loadStateChanged: (state) => _buildLoadState(context, state),
);
case CustomImageType.network:
return ExtendedImage.network(
url,
width: width,
height: height,
fit: fit,
shape: BoxShape.rectangle,
borderRadius: borderRadius,
mode: mode,
enableSlideOutPage: enableSlideOutPage,
initGestureConfigHandler: initGestureConfig,
loadStateChanged: (state) => _buildLoadState(context, state),
);
case CustomImageType.file:
return ExtendedImage.file(
File(url),
width: width,
height: height,
fit: fit,
shape: BoxShape.rectangle,
borderRadius: borderRadius,
mode: mode,
enableSlideOutPage: enableSlideOutPage,
initGestureConfigHandler: initGestureConfig,
loadStateChanged: (state) => _buildLoadState(context, state),
);
}
}
Widget _buildLoadState(BuildContext context, ExtendedImageState state) {
switch (state.extendedImageLoadState) {
case LoadState.loading:
return Center(
child: CustomLoadingIndicator(
size: 30.w,
strokeWidth: 3.w,
),
);
case LoadState.completed:
Size? size;
if (state.extendedImageInfo != null) {
size = Size(
state.extendedImageInfo!.image.width.toDouble(),
state.extendedImageInfo!.image.height.toDouble(),
);
}
final provider = state.imageProvider;
final completed = state.completedWidget;
return builder?.call(context, provider, completed, size) ?? completed;
case LoadState.failed:
return Center(
child: Icon(
Icons.image_not_supported_outlined,
size: 24.w,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
),
);
}
}
}
library widgets;
import 'dart:math';
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:extended_image/extended_image.dart';
part 'toast.dart';
part 'loading.dart';
part 'empty.dart';
part 'image.dart';
\ No newline at end of file
part of widgets;
class CustomLoadingIndicator extends StatefulWidget {
final Color? color;
final double size;
final double strokeWidth;
final Duration duration;
final AnimationController? controller;
const CustomLoadingIndicator({
Key? key,
this.color,
this.strokeWidth = 5.0,
this.size = 50.0,
this.duration = const Duration(milliseconds: 1200),
this.controller,
}) : super(key: key);
@override
State<CustomLoadingIndicator> createState() => _CustomLoadingIndicatorState();
}
class _CustomLoadingIndicatorState extends State<CustomLoadingIndicator>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _animation1;
late Animation<double> _animation2;
late Animation<double> _animation3;
@override
void initState() {
super.initState();
_controller = (widget.controller ??
AnimationController(vsync: this, duration: widget.duration))
..addListener(() => setState(() {}))
..repeat();
_animation1 = Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(
parent: _controller,
curve: const Interval(0.0, 1.0, curve: Curves.linear)));
_animation2 = Tween(begin: -2 / 3, end: 1 / 2).animate(CurvedAnimation(
parent: _controller,
curve: const Interval(0.5, 1.0, curve: Curves.linear)));
_animation3 = Tween(begin: 0.25, end: 5 / 6).animate(CurvedAnimation(
parent: _controller,
curve: const Interval(0.0, 1.0, curve: _RingCurve())));
}
@override
void dispose() {
if (widget.controller == null) {
_controller.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Transform(
transform: Matrix4.identity()
..rotateZ((_animation1.value) * 5 * pi / 6),
alignment: FractionalOffset.center,
child: SizedBox.fromSize(
size: Size.square(widget.size),
child: CustomPaint(
painter: _RingPainter(
paintWidth: widget.strokeWidth,
trackColor: widget.color ?? Theme.of(context).colorScheme.primary,
progressPercent: _animation3.value,
startAngle: pi * _animation2.value,
),
),
),
);
}
}
class _RingPainter extends CustomPainter {
_RingPainter({
required this.paintWidth,
this.progressPercent,
this.startAngle,
required this.trackColor,
}) : trackPaint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = paintWidth
..strokeCap = StrokeCap.round;
final double paintWidth;
final Paint trackPaint;
final Color trackColor;
final double? progressPercent;
final double? startAngle;
@override
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = (min(size.width, size.height) - paintWidth) / 2;
trackPaint.color = trackColor.withOpacity(0.2);
canvas.drawCircle(center, radius, trackPaint);
trackPaint.color = trackColor;
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle!,
2 * pi * progressPercent!,
false,
trackPaint,
);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
class _RingCurve extends Curve {
const _RingCurve();
@override
double transform(double t) => (t <= 0.5) ? 2 * t : 2 * (1 - t);
}
part of widgets;
abstract class CustomToast {
static TransitionBuilder init({
required BuildContext context,
required TransitionBuilder builder,
}) {
EasyLoading.instance
..displayDuration = const Duration(milliseconds: 2000)
..indicatorType = EasyLoadingIndicatorType.ring
..loadingStyle = EasyLoadingStyle.custom
..radius = 20.w
..boxShadow = [
BoxShadow(
color: Theme.of(context).colorScheme.shadow.withOpacity(0.15),
offset: const Offset(0, 0),
blurRadius: 20.w,
),
]
..progressColor = Colors.transparent
..contentPadding = EdgeInsets.all(20.w)
..backgroundColor =
Theme.of(context).brightness == Brightness.light
? Theme.of(context).colorScheme.surface
: Theme.of(context).colorScheme.tertiary
..indicatorColor = Colors.transparent
..textColor = Theme.of(context).colorScheme.onSurface
..textStyle = TextStyle(
fontWeight: FontWeight.w600,
fontSize: 17.w,
color: Theme.of(context).colorScheme.onSurface,
)
..maskType = EasyLoadingMaskType.clear
..maskColor = const Color(0xFF09101D).withOpacity(0.7)
..userInteractions = true
..successWidget = const CustomToastSuccess()
..errorWidget = const CustomToastFail()
..indicatorWidget = CustomLoadingIndicator(size: 60.w)
..dismissOnTap = false;
return EasyLoading.init(builder: builder);
}
static void text(String text) {
EasyLoading.instance
..maskType = EasyLoadingMaskType.clear
..userInteractions = true;
EasyLoading.showToast(text);
}
static void success(String text) {
EasyLoading.instance
..maskType = EasyLoadingMaskType.clear
..userInteractions = true;
EasyLoading.showSuccess(text);
}
static void fail(String text) {
EasyLoading.instance
..maskType = EasyLoadingMaskType.clear
..userInteractions = true;
EasyLoading.showError(text);
}
static void loading() {
EasyLoading.instance
..maskType = EasyLoadingMaskType.custom
..userInteractions = false;
EasyLoading.show();
}
static void dismiss() => EasyLoading.dismiss();
}
class CustomToastFail extends StatelessWidget {
const CustomToastFail({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Icon(
Icons.close_rounded,
color: const Color(0xFFFF1843),
size: 60.w,
);
}
}
class CustomToastSuccess extends StatelessWidget {
const CustomToastSuccess({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Icon(
Icons.check_rounded,
color: Theme.of(context).colorScheme.primary,
size: 60.w,
);
}
}
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.17.1"
convert:
dependency: "direct main"
description:
name: convert
sha256: f08428ad63615f96a27e34221c65e1a451439b5f26030f78d790f461c686d65d
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
crypto:
dependency: "direct main"
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.3"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.6"
dio:
dependency: "direct main"
description:
name: dio
sha256: "417e2a6f9d83ab396ec38ff4ea5da6c254da71e4db765ad737a42af6930140b7"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.3.3"
extended_image:
dependency: "direct main"
description:
name: extended_image
sha256: e77d18f956649ba6e5ecebd0cb68542120886336a75ee673788145bd4c3f0767
url: "https://pub.flutter-io.cn"
source: hosted
version: "8.0.2"
extended_image_library:
dependency: transitive
description:
name: extended_image_library
sha256: bb8d08c504ebc73d476ec1c99451a61f12e95538869e734fc4f55a3a2d5c98ec
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.5.3"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "7.0.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_easyloading:
dependency: "direct main"
description:
name: flutter_easyloading
sha256: ba21a3c883544e582f9cc455a4a0907556714e1e9cf0eababfcb600da191d17c
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.5"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.3"
flutter_localizations:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_screenutil:
dependency: "direct main"
description:
name: flutter_screenutil
sha256: b3e155ee4f2cf5b21a2e15182d1c49c848147ed47f62083fc9a9beccb85f59f9
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.8.2"
flutter_spinkit:
dependency: transitive
description:
name: flutter_spinkit
sha256: b39c753e909d4796906c5696a14daf33639a76e017136c8d82bf3e620ce5bb8e
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.2.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_tts:
dependency: "direct main"
description:
name: flutter_tts
sha256: cbb3fd43b946e62398560235469e6113e4fe26c40eab1b7cb5e7c417503fb3a8
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.8.5"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
get:
dependency: "direct main"
description:
name: get
sha256: "2ba20a47c8f1f233bed775ba2dd0d3ac97b4cf32fc17731b3dfc672b06b0e92a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.6.5"
go_router:
dependency: "direct main"
description:
name: go_router
sha256: "2aa884667eeda3a1c461f31e72af1f77984ab0f29450d8fb12ec1f7bc53eea14"
url: "https://pub.flutter-io.cn"
source: hosted
version: "10.1.0"
http:
dependency: transitive
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.0"
http_client_helper:
dependency: transitive
description:
name: http_client_helper
sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.0"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.2"
intl:
dependency: transitive
description:
name: intl
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.18.0"
ionicons:
dependency: "direct main"
description:
name: ionicons
sha256: "5496bc65a16115ecf05b15b78f494ee4a8869504357668f0a11d689e970523cf"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.2"
js:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.6.7"
lints:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
logger:
dependency: "direct main"
description:
name: logger
sha256: db2ff852ed77090ba9f62d3611e4208a3d11dfa35991a81ae724c113fcb3e3f7
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
logging:
dependency: transitive
description:
name: logging
sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.15"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.0"
meta:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.1"
path:
dependency: transitive
description:
name: path
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.3"
path_provider:
dependency: transitive
description:
name: path_provider
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.1"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
platform:
dependency: transitive
description:
name: platform
sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.3"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.7"
pull_to_refresh_flutter3:
dependency: "direct main"
description:
name: pull_to_refresh_flutter3
sha256: "223a6241067162dc15cf8c46c05af998ce7aa85e0703d8f696101eb1b5629d76"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.1"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.4"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.2"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.2.1"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.3.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.5.1"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
win32:
dependency: transitive
description:
name: win32
sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.9"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.3"
sdks:
dart: ">=3.0.0 <4.0.0"
flutter: ">=3.10.0"
name: flutter_book
description: 紫荆云书
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: '>=3.0.0 <4.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
logger: 1.3.0
get: 4.6.5
go_router: 10.1.0
flutter_easyloading: 3.0.5
shared_preferences: 2.1.1
flutter_screenutil: 5.8.2
pull_to_refresh_flutter3: 2.0.1
extended_image: 8.0.2
ionicons: 0.2.2
dio: 5.3.3
crypto: 3.0.3
convert: 3.0.1
flutter_tts: 3.8.5
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets:
- assets/images/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_book/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();
// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论