├── .gitignore ├── .metadata ├── .vscode └── launch.json ├── CHANGELOG.md ├── README-CN.md ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── AiRi │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── settings_aar.gradle ├── api.json ├── apk └── airi.apk ├── assets ├── fonts │ └── iconfont.ttf └── images │ ├── confirm_order │ ├── 2x │ │ ├── dingdanchenggong.png │ │ └── edit.png │ └── 3x │ │ ├── dingdanchenggong.png │ │ └── edit.png │ ├── detail │ ├── 2x │ │ ├── dowm.png │ │ ├── down.png │ │ └── up.png │ └── 3x │ │ ├── dowm.png │ │ ├── down.png │ │ └── up.png │ ├── home │ ├── 2x │ │ ├── fenxiang.png │ │ ├── gengduofenlei.png │ │ ├── gouwuche.png │ │ ├── jiazaizhong.png │ │ ├── lianxi.png │ │ ├── shop.png │ │ └── sousuo.png │ └── 3x │ │ ├── fenxiang.png │ │ ├── gengduofenlei.png │ │ ├── gouwuche.png │ │ ├── jiazaizhong.png │ │ ├── lianxi.png │ │ ├── shop.png │ │ └── sousuo.png │ ├── login │ ├── 2x │ │ ├── password.png │ │ └── phone.png │ └── 3x │ │ ├── password.png │ │ └── phone.png │ ├── logo.png │ ├── nav │ ├── 2x │ │ └── nav_back.png │ └── 3x │ │ └── nav_back.png │ ├── order │ ├── 2x │ │ ├── empty.png │ │ ├── jiazaizhong.png │ │ └── querendingdan.png │ └── 3x │ │ ├── empty.png │ │ ├── jiazaizhong.png │ │ └── querendingdan.png │ ├── pay │ ├── 2x │ │ ├── check.png │ │ └── uncheck.png │ └── 3x │ │ ├── check.png │ │ └── uncheck.png │ ├── shopping_cart │ ├── 2x │ │ ├── bottom_check.png │ │ ├── check.png │ │ ├── check_un.png │ │ ├── down.png │ │ ├── down1.png │ │ ├── empty.png │ │ ├── icon-sj-26.png │ │ ├── jiazaizhong.png │ │ └── up.png │ └── 3x │ │ ├── bottom_check.png │ │ ├── check.png │ │ ├── check_un.png │ │ ├── down.png │ │ ├── down1.png │ │ ├── empty.png │ │ ├── icon-sj-26.png │ │ ├── jiazaizhong.png │ │ └── up.png │ ├── supplier │ ├── 2x │ │ ├── lianxiren.png │ │ ├── shijian.png │ │ └── weizi.png │ └── 3x │ │ ├── beijing.png │ │ ├── fenxiang.png │ │ ├── lianxiren.png │ │ ├── shijian.png │ │ └── weizi.png │ └── tabbar │ ├── 2x │ ├── diangdan_ON.png │ ├── dingdan_off.png │ ├── fenlei_ON.png │ ├── fenlei_off.png │ ├── guanli_ON.png │ ├── guanli_off.png │ ├── zhuye_ON.png │ └── zhuye_off.png │ └── 3x │ ├── diangdan_ON.png │ ├── dingdan_off.png │ ├── fenlei_ON.png │ ├── fenlei_off.png │ ├── guanli_ON.png │ ├── guanli_off.png │ ├── zhuye_ON.png │ └── zhuye_off.png ├── ios ├── .gitignore ├── Flutter │ ├── .last_build_id │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── 100.png │ │ ├── 1024.png │ │ ├── 114.png │ │ ├── 120.png │ │ ├── 128.png │ │ ├── 144.png │ │ ├── 152.png │ │ ├── 16.png │ │ ├── 167.png │ │ ├── 172.png │ │ ├── 180.png │ │ ├── 196.png │ │ ├── 20.png │ │ ├── 216.png │ │ ├── 256.png │ │ ├── 29.png │ │ ├── 32.png │ │ ├── 40.png │ │ ├── 48.png │ │ ├── 50.png │ │ ├── 512.png │ │ ├── 55.png │ │ ├── 57.png │ │ ├── 58.png │ │ ├── 60.png │ │ ├── 64.png │ │ ├── 72.png │ │ ├── 76.png │ │ ├── 80.png │ │ ├── 87.png │ │ ├── 88.png │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── components │ ├── appbar_shopcart_button.dart │ ├── base_scaffold.dart │ ├── bottom_button.dart │ ├── commdity_item.dart │ ├── commdity_item_home.dart │ ├── components.dart │ ├── custom_dialog.dart │ ├── empty.dart │ ├── goods_list.dart │ ├── left_title.dart │ ├── my_app_bar.dart │ ├── my_cahenetwork_image.dart │ ├── my_custom_footer.dart │ ├── my_dialog.dart │ ├── my_divider.dart │ ├── my_loading.dart │ ├── my_toast.dart │ └── search_bar.dart ├── config │ └── config.dart ├── env.dart ├── json │ ├── category.json │ ├── detil.json │ ├── home.json │ ├── search.json │ └── supplier.json ├── main.dart ├── model │ ├── category.dart │ ├── detail.dart │ ├── goods.dart │ ├── home.dart │ ├── search.dart │ └── supplier.dart ├── pages │ ├── category │ │ ├── category_page.dart │ │ ├── components │ │ │ ├── list_view_item.dart │ │ │ ├── menue.dart │ │ │ └── right_list_view.dart │ │ └── store │ │ │ └── category_page_provider.dart │ ├── choose_address │ │ └── choose_address.dart │ ├── confirm_order │ │ ├── components │ │ │ ├── bottom.dart │ │ │ ├── order_item.dart │ │ │ ├── remark.dart │ │ │ └── top.dart │ │ └── confirm_order.dart │ ├── detail │ │ ├── components │ │ │ ├── Introduction_configuration.dart │ │ │ ├── bottom.dart │ │ │ ├── head_swiper.dart │ │ │ ├── info.dart │ │ │ └── specifications.dart │ │ ├── detail_page.dart │ │ └── store │ │ │ └── detail_page_provider.dart │ ├── home │ │ ├── components │ │ │ ├── brand_swiper.dart │ │ │ ├── commodity_category.dart │ │ │ └── head_swiper.dart │ │ ├── home_page.dart │ │ └── store │ │ │ └── home_page_provider.dart │ ├── login │ │ └── login_page.dart │ ├── logup │ │ └── logup_page.dart │ ├── main │ │ ├── components │ │ │ ├── my_bottom_navigation_bar.dart │ │ │ └── preload_images.dart │ │ ├── main_page.dart │ │ └── store │ │ │ └── main_provider.dart │ ├── manage │ │ ├── manage_page.dart │ │ └── store │ │ │ └── manage_page_provider.dart │ ├── order │ │ ├── components │ │ │ └── order_item.dart │ │ ├── order_page.dart │ │ └── store │ │ │ └── oder_provider.dart │ ├── order_detail │ │ ├── components │ │ │ ├── address.dart │ │ │ ├── delivery.dart │ │ │ ├── info.dart │ │ │ └── item.dart │ │ └── order_detail_page.dart │ ├── pay │ │ ├── components │ │ │ ├── middle.dart │ │ │ └── top.dart │ │ └── pay_page.dart │ ├── search │ │ ├── search_page.dart │ │ └── store │ │ │ └── search_provider.dart │ ├── shopping_cart │ │ ├── cart_page.dart │ │ ├── components │ │ │ ├── cart_bottom.dart │ │ │ └── cart_item.dart │ │ └── store │ │ │ ├── shopping_cart_global_provider.dart │ │ │ └── shopping_cart_provider.dart │ └── supplier │ │ ├── components │ │ └── search_bar.dart │ │ ├── store │ │ └── supplier_provider.dart │ │ └── supplier_page.dart ├── services │ ├── category.dart │ ├── detail.dart │ ├── home.dart │ ├── search.dart │ ├── services.dart │ └── supplier.dart ├── styles │ ├── colors.dart │ ├── iconfont.dart │ └── styles.dart └── utils │ ├── key_value_store.dart │ ├── my_navigator.dart │ ├── request.dart │ ├── screen.dart │ └── utils.dart ├── pubspec.lock ├── pubspec.yaml ├── screenshot ├── Screenshot_1.png ├── Screenshot_10.png ├── Screenshot_11.png ├── Screenshot_12.png ├── Screenshot_13.png ├── Screenshot_14.png ├── Screenshot_15.png ├── Screenshot_16.png ├── Screenshot_17.png ├── Screenshot_18.png ├── Screenshot_19.png ├── Screenshot_2.png ├── Screenshot_20.png ├── Screenshot_3.png ├── Screenshot_4.png ├── Screenshot_5.png ├── Screenshot_6.png ├── Screenshot_7.png ├── Screenshot_8.png └── Screenshot_9.png └── test └── widget_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Symbolication related 37 | app.*.symbols 38 | 39 | # Obfuscation related 40 | app.*.map.json 41 | 42 | # Exceptions to above rules. 43 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 44 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f7a6a7906be96d2288f5d63a5a54c515a6e987fe 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Flutter", 9 | "request": "launch", 10 | "type": "dart" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.0.5] - [2021-05-25] 2 | 3 | - 迁移到空安全版本- flutter v2.2.0-stable 4 | 5 | 6 | ## [0.0.4] - [2020-08-17] 7 | 8 | - 新增管理中心页面 9 | - 引入阿里字体图标库代码优化 10 | - 代码及其体验优化 11 | 12 | 13 | ## [0.0.3] - [2020-08-01] 14 | 15 | - 增加登录逻辑判断 16 | - 整理代码 17 | - 重构部分代码 18 | 19 | ## [0.0.2] - [2020-07-26] 20 | 21 | - 重构部分代码 22 | 23 | 24 | ## [0.0.1] - [2020-07-01] 25 | 26 | - 完整的电商购物流程 27 | - 分类页面左右动画联动 28 | - 使用 provider (4.x 版本)做状态管理 29 | - 基于 dio (3.x 版本)的网络请求封装 30 | - 输入框等部件的处理封装 31 | - 下拉刷新 + 上拉加载更多 32 | - 自定义 Dialog 33 | -------------------------------------------------------------------------------- /README-CN.md: -------------------------------------------------------------------------------- 1 | # AiRi 2 | 3 | 已迁移至空安全版本 4 | 5 | Language: 中文简体 | [English](https://github.com/xieyezi/flutter-shopping-ArRi) 6 | 7 | 下载`apk`文件请点击[这里](https://github.com/xieyezi/flutter-shopping-AiRi/blob/master/apk/airi.apk?raw=trueg) 8 | 9 | ### 更新记录 10 | 11 | - ~~增加安卓 APP 图标~~ 12 | - ~~已迁移至空安全版本~~ 13 | - ~~添加 apk 文件~~ 14 | - ~~项目采用了 mock 接口,目前 mock 接口已挂,正在修复中...~~(已修复) 15 | 16 | 已有的功能有: 17 | 18 | - [x] 完整的电商购物流程 19 | - [x] 分类页面左右动画联动 20 | - [x] 使用 provider (5.x 版本)做状态管理 21 | - [x] 基于 dio (4.x 版本)的网络请求封装 22 | - [x] 输入框等部件的处理封装 23 | - [x] 下拉刷新 + 上拉加载更多 24 | - [x] 自定义 Dialog 25 | 26 | 通过设置、修改、组合自带部件以及自定义来实现具体的设计效果,满足日常开发的需求。 27 | **这个项目还在持续迭代中,喜欢就给个小 🌟🌟 吧** 28 | 29 | ## 项目运行环境 30 | 31 | ``` 32 | Flutter 2.2.0 • channel stable • https://github.com/flutter/flutter.git 33 | Framework • revision b22742018b (10 days ago) • 2021-05-14 19:12:57 -0700 34 | Engine • revision a9d88a4d18 35 | Tools • Dart 2.13.0 36 | ``` 37 | 38 | ## 后续计划 39 | 40 | - [ ] 从 provider 迁移到 getx 41 | - [x] 整理项目文件夹,优化代码 42 | - [x] 完成登录页面 43 | - [x] 完成个人中心页 44 | 45 | ## 回馈和建议 46 | 47 | 如果你有更好的想法或者你想参与到这个项目中来,欢迎提交 PR!! 48 | 49 | ## 预览 50 | 51 | 部分页面效果如下: 52 | 53 | | ![](./screenshot/Screenshot_1.png) | ![](./screenshot/Screenshot_2.png) | ![](./screenshot/Screenshot_3.png) | ![](./screenshot/Screenshot_4.png) | 54 | | :---------------------------------: | :---------------------------------: | :---------------------------------: | :---------------------------------: | 55 | | ![](./screenshot/Screenshot_5.png) | ![](./screenshot/Screenshot_6.png) | ![](./screenshot/Screenshot_7.png) | ![](./screenshot/Screenshot_8.png) | 56 | | ![](./screenshot/Screenshot_9.png) | ![](./screenshot/Screenshot_10.png) | ![](./screenshot/Screenshot_11.png) | ![](./screenshot/Screenshot_12.png) | 57 | | ![](./screenshot/Screenshot_13.png) | ![](./screenshot/Screenshot_14.png) | ![](./screenshot/Screenshot_17.png) | ![](./screenshot/Screenshot_18.png) | 58 | | ![](./screenshot/Screenshot_15.png) | ![](./screenshot/Screenshot_19.png) | ![](./screenshot/Screenshot_20.png) | ![](./screenshot/Screenshot_21.png) | 59 | | ![](./screenshot/Screenshot_22.jpg) | ![](./screenshot/Screenshot_23.jpg) | ![](./screenshot/Screenshot_24.jpg) | ![](./screenshot/Screenshot_25.jpg) | 60 | | ![](./screenshot/Screenshot_26.jpg) | ![](./screenshot/Screenshot_27.jpg) | | | 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AiRi 2 | 3 | Language: English | [中文简体](README-CN.md) 4 | 5 | ### have been migrate to null-safety version 6 | 7 | Supported features: 8 | 9 | - [x] Complete e-commerce shopping process 10 | - [x] Animation linkage between category pages 11 | - [x] Use provider (version 4.x) for state management 12 | - [x] Network request encapsulation based on dio (version 3.x) 13 | - [x] Processing and packaging of input boxes and other components 14 | - [x] Pull down to refresh + pull up to load more 15 | - [x] Custom Dialog 16 | 17 | Realize specific design effects by setting, modifying, combining self-contained parts and customizing to meet the needs of daily development. 18 | 19 | This project is still in continuous iteration, just give 🌟🌟 if you like it ! 20 | 21 | ## Operating environment 22 | 23 | ``` 24 | Flutter 2.2.0 • channel stable • https://github.com/flutter/flutter.git 25 | Framework • revision b22742018b (10 days ago) • 2021-05-14 19:12:57 -0700 26 | Engine • revision a9d88a4d18 27 | Tools • Dart 2.13.0 28 | ``` 29 | 30 | ## Next Plan 31 | 32 | - [x] Organize project folders and optimize code 33 | - [x] Complete the login page 34 | - [ ] Complete product multi-spec selection function 35 | - [ ] Support night mode 36 | 37 | ## Feedback and Suggestions 38 | 39 | If you have a better idea or you want to participate in this project ,Welcome to PR! 40 | 41 | ## Preview 42 | 43 | The effect of some pages is as follows: 44 | 45 | | ![](./screenshot/Screenshot_1.png) | ![](./screenshot/Screenshot_2.png) | ![](./screenshot/Screenshot_3.png) | ![](./screenshot/Screenshot_4.png) | 46 | | :---------------------------------: | :---------------------------------: | :---------------------------------: | :---------------------------------: | 47 | | ![](./screenshot/Screenshot_5.png) | ![](./screenshot/Screenshot_6.png) | ![](./screenshot/Screenshot_7.png) | ![](./screenshot/Screenshot_8.png) | 48 | | ![](./screenshot/Screenshot_9.png) | ![](./screenshot/Screenshot_10.png) | ![](./screenshot/Screenshot_11.png) | ![](./screenshot/Screenshot_12.png) | 49 | | ![](./screenshot/Screenshot_13.png) | ![](./screenshot/Screenshot_14.png) | ![](./screenshot/Screenshot_17.png) | ![](./screenshot/Screenshot_18.png) | 50 | | ![](./screenshot/Screenshot_15.png) | ![](./screenshot/Screenshot_19.png) | ![](./screenshot/Screenshot_20.png) | ![](./screenshot/Screenshot_21.png) | 51 | | ![](./screenshot/Screenshot_22.jpg) | ![](./screenshot/Screenshot_23.jpg) | ![](./screenshot/Screenshot_24.jpg) | ![](./screenshot/Screenshot_25.jpg) | 52 | | ![](./screenshot/Screenshot_26.jpg) | ![](./screenshot/Screenshot_27.jpg) | | | 53 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.AiRi" 42 | minSdkVersion 21 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 23 | 27 | 32 | 36 | 37 | 38 | 39 | 40 | 41 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/AiRi/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.AiRi 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | maven { url 'https://maven.aliyun.com/repository/google' } 5 | maven { url 'https://maven.aliyun.com/repository/jcenter' } 6 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 7 | mavenCentral() 8 | google() 9 | jcenter() 10 | } 11 | 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:3.5.0' 14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | maven { url 'https://maven.aliyun.com/repository/google' } 21 | maven { url 'https://maven.aliyun.com/repository/jcenter' } 22 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 23 | mavenCentral() 24 | google() 25 | jcenter() 26 | } 27 | } 28 | 29 | rootProject.buildDir = '../build' 30 | subprojects { 31 | project.buildDir = "${rootProject.buildDir}/${project.name}" 32 | } 33 | subprojects { 34 | project.evaluationDependsOn(':app') 35 | } 36 | 37 | task clean(type: Delete) { 38 | delete rootProject.buildDir 39 | } 40 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /android/settings_aar.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /apk/airi.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/apk/airi.apk -------------------------------------------------------------------------------- /assets/fonts/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/fonts/iconfont.ttf -------------------------------------------------------------------------------- /assets/images/confirm_order/2x/dingdanchenggong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/confirm_order/2x/dingdanchenggong.png -------------------------------------------------------------------------------- /assets/images/confirm_order/2x/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/confirm_order/2x/edit.png -------------------------------------------------------------------------------- /assets/images/confirm_order/3x/dingdanchenggong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/confirm_order/3x/dingdanchenggong.png -------------------------------------------------------------------------------- /assets/images/confirm_order/3x/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/confirm_order/3x/edit.png -------------------------------------------------------------------------------- /assets/images/detail/2x/dowm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/detail/2x/dowm.png -------------------------------------------------------------------------------- /assets/images/detail/2x/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/detail/2x/down.png -------------------------------------------------------------------------------- /assets/images/detail/2x/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/detail/2x/up.png -------------------------------------------------------------------------------- /assets/images/detail/3x/dowm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/detail/3x/dowm.png -------------------------------------------------------------------------------- /assets/images/detail/3x/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/detail/3x/down.png -------------------------------------------------------------------------------- /assets/images/detail/3x/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/detail/3x/up.png -------------------------------------------------------------------------------- /assets/images/home/2x/fenxiang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/2x/fenxiang.png -------------------------------------------------------------------------------- /assets/images/home/2x/gengduofenlei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/2x/gengduofenlei.png -------------------------------------------------------------------------------- /assets/images/home/2x/gouwuche.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/2x/gouwuche.png -------------------------------------------------------------------------------- /assets/images/home/2x/jiazaizhong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/2x/jiazaizhong.png -------------------------------------------------------------------------------- /assets/images/home/2x/lianxi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/2x/lianxi.png -------------------------------------------------------------------------------- /assets/images/home/2x/shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/2x/shop.png -------------------------------------------------------------------------------- /assets/images/home/2x/sousuo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/2x/sousuo.png -------------------------------------------------------------------------------- /assets/images/home/3x/fenxiang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/3x/fenxiang.png -------------------------------------------------------------------------------- /assets/images/home/3x/gengduofenlei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/3x/gengduofenlei.png -------------------------------------------------------------------------------- /assets/images/home/3x/gouwuche.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/3x/gouwuche.png -------------------------------------------------------------------------------- /assets/images/home/3x/jiazaizhong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/3x/jiazaizhong.png -------------------------------------------------------------------------------- /assets/images/home/3x/lianxi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/3x/lianxi.png -------------------------------------------------------------------------------- /assets/images/home/3x/shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/3x/shop.png -------------------------------------------------------------------------------- /assets/images/home/3x/sousuo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/home/3x/sousuo.png -------------------------------------------------------------------------------- /assets/images/login/2x/password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/login/2x/password.png -------------------------------------------------------------------------------- /assets/images/login/2x/phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/login/2x/phone.png -------------------------------------------------------------------------------- /assets/images/login/3x/password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/login/3x/password.png -------------------------------------------------------------------------------- /assets/images/login/3x/phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/login/3x/phone.png -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/nav/2x/nav_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/nav/2x/nav_back.png -------------------------------------------------------------------------------- /assets/images/nav/3x/nav_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/nav/3x/nav_back.png -------------------------------------------------------------------------------- /assets/images/order/2x/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/order/2x/empty.png -------------------------------------------------------------------------------- /assets/images/order/2x/jiazaizhong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/order/2x/jiazaizhong.png -------------------------------------------------------------------------------- /assets/images/order/2x/querendingdan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/order/2x/querendingdan.png -------------------------------------------------------------------------------- /assets/images/order/3x/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/order/3x/empty.png -------------------------------------------------------------------------------- /assets/images/order/3x/jiazaizhong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/order/3x/jiazaizhong.png -------------------------------------------------------------------------------- /assets/images/order/3x/querendingdan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/order/3x/querendingdan.png -------------------------------------------------------------------------------- /assets/images/pay/2x/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/pay/2x/check.png -------------------------------------------------------------------------------- /assets/images/pay/2x/uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/pay/2x/uncheck.png -------------------------------------------------------------------------------- /assets/images/pay/3x/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/pay/3x/check.png -------------------------------------------------------------------------------- /assets/images/pay/3x/uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/pay/3x/uncheck.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/bottom_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/bottom_check.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/check.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/check_un.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/check_un.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/down.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/down1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/down1.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/empty.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/icon-sj-26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/icon-sj-26.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/jiazaizhong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/jiazaizhong.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/2x/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/2x/up.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/bottom_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/bottom_check.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/check.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/check_un.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/check_un.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/down.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/down1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/down1.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/empty.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/icon-sj-26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/icon-sj-26.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/jiazaizhong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/jiazaizhong.png -------------------------------------------------------------------------------- /assets/images/shopping_cart/3x/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/shopping_cart/3x/up.png -------------------------------------------------------------------------------- /assets/images/supplier/2x/lianxiren.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/2x/lianxiren.png -------------------------------------------------------------------------------- /assets/images/supplier/2x/shijian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/2x/shijian.png -------------------------------------------------------------------------------- /assets/images/supplier/2x/weizi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/2x/weizi.png -------------------------------------------------------------------------------- /assets/images/supplier/3x/beijing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/3x/beijing.png -------------------------------------------------------------------------------- /assets/images/supplier/3x/fenxiang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/3x/fenxiang.png -------------------------------------------------------------------------------- /assets/images/supplier/3x/lianxiren.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/3x/lianxiren.png -------------------------------------------------------------------------------- /assets/images/supplier/3x/shijian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/3x/shijian.png -------------------------------------------------------------------------------- /assets/images/supplier/3x/weizi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/supplier/3x/weizi.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/diangdan_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/diangdan_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/dingdan_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/dingdan_off.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/fenlei_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/fenlei_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/fenlei_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/fenlei_off.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/guanli_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/guanli_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/guanli_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/guanli_off.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/zhuye_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/zhuye_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/2x/zhuye_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/2x/zhuye_off.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/diangdan_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/diangdan_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/dingdan_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/dingdan_off.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/fenlei_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/fenlei_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/fenlei_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/fenlei_off.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/guanli_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/guanli_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/guanli_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/guanli_off.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/zhuye_ON.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/zhuye_ON.png -------------------------------------------------------------------------------- /assets/images/tabbar/3x/zhuye_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/assets/images/tabbar/3x/zhuye_off.png -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/.last_build_id: -------------------------------------------------------------------------------- 1 | c3b1a80aa67b220c8f4357cf88cfd493 -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - FMDB (2.7.5): 4 | - FMDB/standard (= 2.7.5) 5 | - FMDB/standard (2.7.5) 6 | - path_provider (0.0.1): 7 | - Flutter 8 | - "permission_handler (5.1.0+2)": 9 | - Flutter 10 | - shared_preferences (0.0.1): 11 | - Flutter 12 | - sqflite (0.0.2): 13 | - Flutter 14 | - FMDB (>= 2.7.5) 15 | - url_launcher (0.0.1): 16 | - Flutter 17 | - webview_flutter (0.0.1): 18 | - Flutter 19 | 20 | DEPENDENCIES: 21 | - Flutter (from `Flutter`) 22 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 23 | - permission_handler (from `.symlinks/plugins/permission_handler/ios`) 24 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) 25 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 26 | - url_launcher (from `.symlinks/plugins/url_launcher/ios`) 27 | - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) 28 | 29 | SPEC REPOS: 30 | trunk: 31 | - FMDB 32 | 33 | EXTERNAL SOURCES: 34 | Flutter: 35 | :path: Flutter 36 | path_provider: 37 | :path: ".symlinks/plugins/path_provider/ios" 38 | permission_handler: 39 | :path: ".symlinks/plugins/permission_handler/ios" 40 | shared_preferences: 41 | :path: ".symlinks/plugins/shared_preferences/ios" 42 | sqflite: 43 | :path: ".symlinks/plugins/sqflite/ios" 44 | url_launcher: 45 | :path: ".symlinks/plugins/url_launcher/ios" 46 | webview_flutter: 47 | :path: ".symlinks/plugins/webview_flutter/ios" 48 | 49 | SPEC CHECKSUMS: 50 | Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c 51 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 52 | path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c 53 | permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 54 | shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d 55 | sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 56 | url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef 57 | webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b 58 | 59 | PODFILE CHECKSUM: a75497545d4391e2d394c3668e20cfb1c2bbd4aa 60 | 61 | COCOAPODS: 1.10.0 62 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | AiRi 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/components/appbar_shopcart_button.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:AiRi/pages/shopping_cart/cart_page.dart'; 5 | import 'package:AiRi/pages/shopping_cart/store/shopping_cart_global_provider.dart'; 6 | import 'package:AiRi/utils/my_navigator.dart'; 7 | 8 | class AppBarShopCartIconButton extends StatelessWidget { 9 | const AppBarShopCartIconButton({ 10 | Key? key, 11 | }) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return IconButton( 16 | padding: const EdgeInsets.fromLTRB(6, 6, 8, 6), 17 | icon: Container( 18 | child: Stack( 19 | children: [ 20 | Center( 21 | child: Image.asset('assets/images/home/gouwuche.png', 22 | width: 22, height: 22), 23 | ), 24 | Positioned( 25 | right: 0, 26 | top: 0, 27 | child: Selector( 28 | builder: (_, count, __) { 29 | return Visibility( 30 | visible: count != "0", 31 | child: _badgeWidget(count), 32 | ); 33 | }, 34 | selector: (context, model) => model.goodsCountString), 35 | ) 36 | ], 37 | ), 38 | ), 39 | onPressed: () => MyNavigator.push(CartPage()), 40 | ); 41 | } 42 | 43 | Container _badgeWidget(String count) { 44 | return Container( 45 | decoration: BoxDecoration( 46 | borderRadius: BorderRadius.circular(12), 47 | border: Border.all(width: 1.5, color: Colors.white), 48 | ), 49 | child: ConstrainedBox( 50 | constraints: BoxConstraints(minWidth: 14), 51 | child: Container( 52 | height: 14, 53 | padding: EdgeInsets.only( 54 | left: 4, right: 4, bottom: Platform.isIOS ? 1 : 0), 55 | decoration: BoxDecoration( 56 | color: Color(0xFFB80821), 57 | borderRadius: BorderRadius.circular(12), 58 | ), 59 | child: Center( 60 | child: Text( 61 | count, 62 | style: TextStyle(color: Colors.white, fontSize: 9), 63 | ), 64 | ), 65 | ), 66 | ), 67 | ); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/components/base_scaffold.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:AiRi/components/my_app_bar.dart'; 4 | 5 | class BaseScaffold extends Scaffold { 6 | BaseScaffold( 7 | {String? title, 8 | PreferredSizeWidget? appBar, 9 | Widget? body, 10 | List? actions, 11 | AppBarBackType leadType = AppBarBackType.Back, 12 | WillPopCallback? onWillPop, 13 | Brightness brightness = Brightness.light, 14 | Widget? floatingActionButton, 15 | Color appBarBackgroundColor = Colors.white, 16 | Color? titleColor, 17 | bool centerTitle = true, 18 | FloatingActionButtonLocation? floatingActionButtonLocation}) 19 | : super( 20 | appBar: appBar ?? 21 | MyAppBar( 22 | brightness: Brightness.light, 23 | leadingType: leadType, 24 | onWillPop: onWillPop, 25 | actions: actions ?? [], 26 | centerTitle: centerTitle, 27 | title: MyTitle(title ?? '', color: titleColor ?? Colors.grey[800]), 28 | backgroundColor: appBarBackgroundColor, 29 | ), 30 | backgroundColor: Colors.white, 31 | body: body, 32 | floatingActionButton: floatingActionButton, 33 | floatingActionButtonLocation: floatingActionButtonLocation, 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /lib/components/bottom_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/styles/styles.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class BottomButton extends StatelessWidget { 5 | final String? text; 6 | final Function? handleOk; 7 | const BottomButton({Key ?key, this.handleOk, this.text}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return GestureDetector( 12 | onTap: () => handleOk!(), 13 | child: Container( 14 | margin: EdgeInsets.only( 15 | bottom: MediaQuery.of(context).padding.bottom, 16 | left: 10, 17 | right: 10, 18 | ), 19 | height: 60, 20 | decoration: BoxDecoration( 21 | gradient: LinearGradient( 22 | //背景径向渐变 23 | colors: [AppColors.buttonLine1, AppColors.buttonLine2], 24 | ), 25 | borderRadius: BorderRadius.circular(20.0), 26 | ), 27 | child: Center( 28 | child: Text( 29 | text!, 30 | style: TextStyle( 31 | color: Colors.white, 32 | fontSize: 16, 33 | fontWeight: FontWeight.w500, 34 | ), 35 | ), 36 | ), 37 | ), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/components/commdity_item_home.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/my_cahenetwork_image.dart'; 2 | import 'package:AiRi/styles/styles.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:AiRi/model/goods.dart'; 5 | import 'package:AiRi/pages/detail/detail_page.dart'; 6 | import 'package:AiRi/utils/my_navigator.dart'; 7 | 8 | class CommdityItemHome extends StatelessWidget { 9 | final GoodsList goodData; 10 | const CommdityItemHome({Key? key, required this.goodData}) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return GestureDetector( 15 | behavior: HitTestBehavior.translucent, 16 | onTap: () => MyNavigator.push(DetailPage(goodsId: goodData.goodsId)), 17 | child: Container( 18 | height: 240, 19 | width: (MediaQuery.of(context).size.width - 40) / 2, 20 | padding: EdgeInsets.symmetric(horizontal: 5), 21 | decoration: BoxDecoration( 22 | borderRadius: BorderRadius.circular(5), 23 | color: Colors.white, 24 | ), 25 | child: Column( 26 | crossAxisAlignment: CrossAxisAlignment.start, 27 | children: [ 28 | Container( 29 | height: 182, 30 | child: MyCachedNetworkImage( 31 | imageurl: goodData.goodsPicUrl, 32 | ), 33 | ), 34 | Container( 35 | width: (MediaQuery.of(context).size.width - 40) / 2, 36 | child: Text( 37 | goodData.goodsName, 38 | maxLines: 1, 39 | overflow: TextOverflow.ellipsis, 40 | style: TextStyle( 41 | color: AppColors.primaryText, 42 | fontSize: 14.0, 43 | fontWeight: FontWeight.w500, 44 | ), 45 | ), 46 | ), 47 | Container( 48 | width: (MediaQuery.of(context).size.width - 40) / 2, 49 | child: Text( 50 | '优衣库官方旗舰店', 51 | maxLines: 1, 52 | overflow: TextOverflow.ellipsis, 53 | style: TextStyle( 54 | color: AppColors.primaryGreyText, 55 | fontSize: 12.0, 56 | fontWeight: FontWeight.w500, 57 | ), 58 | ), 59 | ), 60 | Container( 61 | width: (MediaQuery.of(context).size.width - 40) / 2, 62 | child: Text( 63 | '¥${goodData.goodsMiniPrice}', 64 | maxLines: 1, 65 | overflow: TextOverflow.ellipsis, 66 | style: TextStyle( 67 | color: AppColors.priceColor, 68 | fontSize: 12.0, 69 | fontWeight: FontWeight.normal, 70 | ), 71 | ), 72 | ), 73 | ], 74 | ), 75 | ), 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/components/components.dart: -------------------------------------------------------------------------------- 1 | library components; 2 | 3 | export 'empty.dart'; 4 | export 'my_toast.dart'; 5 | export 'my_dialog.dart'; 6 | export 'goods_list.dart'; 7 | export 'left_title.dart'; 8 | export 'search_bar.dart'; 9 | export 'my_app_bar.dart'; 10 | export 'my_divider.dart'; 11 | export 'my_loading.dart'; 12 | export 'base_scaffold.dart'; 13 | export 'bottom_button.dart'; 14 | export 'custom_dialog.dart'; 15 | export 'commdity_item.dart'; 16 | export 'custom_dialog.dart'; 17 | export 'my_custom_footer.dart'; 18 | export 'commdity_item_home.dart'; 19 | export 'my_cahenetwork_image.dart'; 20 | export 'appbar_shopcart_button.dart'; 21 | -------------------------------------------------------------------------------- /lib/components/empty.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/styles/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class Empty extends StatelessWidget { 5 | /// 图片 6 | final String img; 7 | 8 | /// 提示文字 9 | final String tipText; 10 | 11 | /// 按钮文字 12 | final String buttonText; 13 | 14 | /// 按钮事件 15 | final Function buttonTap; 16 | const Empty({ 17 | Key? key, 18 | required this.img, 19 | required this.tipText, 20 | required this.buttonText, 21 | required this.buttonTap, 22 | }) : super(key: key); 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | return Center( 27 | child: Container( 28 | height: 250, 29 | child: Column( 30 | children: [ 31 | Image.asset( 32 | img, 33 | width: 150, 34 | height: 150, 35 | ), 36 | SizedBox( 37 | height: 15, 38 | ), 39 | Text( 40 | tipText, 41 | style: TextStyle( 42 | color: Color(0xFF4A4A4A), 43 | fontSize: 14, 44 | fontWeight: FontWeight.normal, 45 | ), 46 | ), 47 | SizedBox( 48 | height: 15, 49 | ), 50 | Container( 51 | width: 120, 52 | height: 40.5, 53 | child: OutlineButton( 54 | onPressed: () => buttonTap, 55 | borderSide: BorderSide(color: AppColors.primaryColor), 56 | splashColor: AppColors.primaryColor, 57 | child: Center( 58 | child: Text( 59 | buttonText, 60 | style: TextStyle( 61 | color: AppColors.primaryColor, 62 | fontSize: 14, 63 | fontWeight: FontWeight.normal, 64 | ), 65 | ), 66 | ), 67 | ), 68 | ) 69 | ], 70 | ), 71 | ), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/components/goods_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:AiRi/model/goods.dart'; 3 | 4 | import 'commdity_item.dart'; 5 | import 'my_divider.dart'; 6 | 7 | class GoodList extends StatelessWidget { 8 | final List goodsList; 9 | const GoodList({Key? key, required this.goodsList}) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return ListView.separated( 14 | physics: NeverScrollableScrollPhysics(), 15 | shrinkWrap: true, 16 | itemCount: goodsList.length, 17 | itemBuilder: (context, index) { 18 | return CommdityItem(goodData: goodsList[index]); 19 | }, 20 | separatorBuilder: (BuildContext context, int index) { 21 | return MyDivider(); 22 | }, 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/components/left_title.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:AiRi/styles/colors.dart'; 3 | 4 | class LeftTitle extends StatelessWidget { 5 | final Color? tipColor; 6 | final String title; 7 | const LeftTitle({Key? key, this.tipColor, required this.title}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | height: 23, 13 | child: Row( 14 | children: [ 15 | Container( 16 | color: tipColor ?? AppColors.primaryColor, 17 | margin: EdgeInsets.only(right: 15), 18 | width: 3, 19 | height: 14, 20 | ), 21 | Text( 22 | title, 23 | style: TextStyle( 24 | color: AppColors.primaryText, 25 | fontSize: 16, 26 | fontWeight: FontWeight.w500, 27 | ), 28 | ) 29 | ], 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/components/my_app_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/styles/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | /// appbar 返回按钮类型 5 | enum AppBarBackType { Back, Close, None } 6 | 7 | const double kNavigationBarHeight = 44.0; 8 | 9 | // 自定义 AppBar 10 | class MyAppBar extends AppBar implements PreferredSizeWidget { 11 | MyAppBar( 12 | {Key? key, 13 | Widget? title, 14 | AppBarBackType? leadingType, 15 | WillPopCallback? onWillPop, 16 | Widget? leading, 17 | Brightness? brightness, 18 | Color? backgroundColor, 19 | List? actions, 20 | bool centerTitle = true, 21 | double? elevation}) 22 | : super( 23 | key: key, 24 | title: title, 25 | centerTitle: centerTitle, 26 | brightness: brightness ?? Brightness.light, 27 | backgroundColor: backgroundColor ?? Color(0xfffefefe), 28 | leading: leading ?? 29 | (leadingType == AppBarBackType.None 30 | ? Container() 31 | : AppBarBack( 32 | leadingType ?? AppBarBackType.Back, 33 | onWillPop: onWillPop, 34 | )), 35 | actions: actions, 36 | elevation: elevation ?? 0.5, 37 | ); 38 | @override 39 | get preferredSize => Size.fromHeight(44); 40 | } 41 | 42 | // 自定义返回按钮 43 | class AppBarBack extends StatelessWidget { 44 | final AppBarBackType _backType; 45 | final Color? color; 46 | final WillPopCallback? onWillPop; 47 | 48 | AppBarBack(this._backType, {this.onWillPop, this.color}); 49 | 50 | @override 51 | Widget build(BuildContext context) { 52 | return GestureDetector( 53 | onTap: () async { 54 | final willBack = onWillPop == null ? true : await onWillPop!(); 55 | if (!willBack) return; 56 | Navigator.pop(context); 57 | }, 58 | child: _backType == AppBarBackType.Close 59 | ? Container( 60 | child: Icon(Icons.close, color: color ?? Color(0xFF222222), size: 24.0), 61 | ) 62 | : Container( 63 | padding: EdgeInsets.only(right: 15), 64 | child: Image.asset( 65 | 'assets/images/nav/nav_back.png', 66 | color: color, 67 | ), 68 | ), 69 | ); 70 | } 71 | } 72 | 73 | class MyTitle extends StatelessWidget { 74 | final String _title; 75 | final Color? color; 76 | 77 | MyTitle(this._title, {this.color}); 78 | 79 | @override 80 | Widget build(BuildContext context) { 81 | return Text(_title, 82 | style: TextStyle(color: color ?? AppColors.primaryText, fontSize: 16, fontWeight: FontWeight.w500)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/components/my_cahenetwork_image.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class MyCachedNetworkImage extends StatelessWidget { 5 | final String imageurl; 6 | const MyCachedNetworkImage({Key? key, required this.imageurl}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return CachedNetworkImage( 11 | imageUrl: imageurl, 12 | placeholder: (_, __) => Image.asset('assets/images/home/jiazaizhong.png'), 13 | fit: BoxFit.cover, 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/components/my_custom_footer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | import 'package:pull_to_refresh/pull_to_refresh.dart'; 5 | 6 | class MyCustomFooter extends StatelessWidget { 7 | const MyCustomFooter({ 8 | Key? key, 9 | }) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Theme( 14 | data: ThemeData(textTheme: TextTheme(headline4: TextStyle(color: Colors.grey, fontSize: 12))), 15 | child: CustomFooter( 16 | builder: (context, mode) { 17 | Widget body; 18 | if (mode == LoadStatus.idle) { 19 | body = CupertinoActivityIndicator(); 20 | } else if (mode == LoadStatus.loading) { 21 | body = CupertinoActivityIndicator(); 22 | } else if (mode == LoadStatus.failed) { 23 | body = Text("加载失败", style: Theme.of(context).textTheme.headline4); 24 | } else if (mode == LoadStatus.canLoading) { 25 | body = Text("松手,加载更多!", style: Theme.of(context).textTheme.headline4); 26 | } else { 27 | body = Text("我是有底线的~", style: Theme.of(context).textTheme.headline4); 28 | } 29 | return Container( 30 | height: 55.0, 31 | child: Center(child: body), 32 | ); 33 | }, 34 | ), 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/components/my_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | import 'package:flutter/material.dart'; 3 | import '../utils/my_navigator.dart'; 4 | 5 | class MyDialog { 6 | MyDialog._(); 7 | 8 | static OverlayEntry? _entry; 9 | 10 | static showLoading(String msg, {BuildContext? context, bool barrier = false}) { 11 | hideLoading(); 12 | 13 | _entry = OverlayEntry(builder: (BuildContext context) { 14 | return barrier 15 | ? Container( 16 | color: Color(0x66000000), 17 | child: _loadingContainer(msg), 18 | ) 19 | : _loadingContainer(msg); 20 | }); 21 | 22 | Overlay.of(context ?? MyNavigator.ctx)?.insert(_entry!); 23 | } 24 | 25 | static Center _loadingContainer(String msg) { 26 | return Center( 27 | child: Container( 28 | padding: EdgeInsets.only(bottom: 30), 29 | child: ClipRect( 30 | child: BackdropFilter( 31 | filter: ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0), 32 | child: Container( 33 | padding: EdgeInsets.only(left: 12, right: 14, top: 10, bottom: 10), 34 | decoration: BoxDecoration( 35 | color: Color(0xbb000000), 36 | borderRadius: (BorderRadius.circular(4)), 37 | border: Border.all(width: 0.5, color: Colors.black45)), 38 | child: Row( 39 | mainAxisSize: MainAxisSize.min, 40 | children: [ 41 | Padding( 42 | padding: EdgeInsets.only(left: 0), 43 | child: SizedBox( 44 | width: 22, 45 | height: 22, 46 | child: CircularProgressIndicator( 47 | strokeWidth: 2, 48 | valueColor: AlwaysStoppedAnimation(Colors.lightBlueAccent), 49 | )), 50 | ), 51 | Padding( 52 | padding: const EdgeInsets.only(left: 10.0), 53 | child: Text( 54 | msg, 55 | style: TextStyle( 56 | fontSize: 15, 57 | fontWeight: FontWeight.normal, 58 | color: Color(0xfff1f1f1), 59 | decoration: TextDecoration.none), 60 | ), 61 | ), 62 | ], 63 | ), 64 | ), 65 | ), 66 | ))); 67 | } 68 | 69 | static hideLoading() { 70 | _entry?.remove(); 71 | _entry = null; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /lib/components/my_divider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class MyDivider extends StatelessWidget { 4 | const MyDivider({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Divider( 9 | color: Color(0xffdfdfdf), 10 | height: 0.5, 11 | indent: 20, 12 | endIndent:20 13 | ); 14 | } 15 | } 16 | 17 | class MyVerticalDivider extends StatelessWidget { 18 | const MyVerticalDivider({Key? key}) : super(key: key); 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return VerticalDivider( 23 | color: Color(0xffdfdfdf), 24 | width: 1, 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/components/my_loading.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/styles/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class MyLoadingWidget extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return Center( 8 | child: CircularProgressIndicator( 9 | backgroundColor: AppColors.primaryColor, 10 | )); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/components/my_toast.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:oktoast/oktoast.dart'; 3 | 4 | class MyToast { 5 | static show(String msg, {int duration = 1500}) { 6 | showToast(msg, 7 | duration: Duration(milliseconds: duration), 8 | textPadding: EdgeInsets.fromLTRB(12, 8, 12, 8), 9 | radius: 6); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/components/search_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:AiRi/styles/colors.dart'; 3 | 4 | class SearchBar extends StatefulWidget { 5 | final String keyword; 6 | final Function myOntap; 7 | const SearchBar({Key? key, required this.myOntap, this.keyword = ''}) : super(key: key); 8 | 9 | @override 10 | _SearchBarState createState() => _SearchBarState(); 11 | } 12 | 13 | class _SearchBarState extends State { 14 | final _textEditController = TextEditingController(); 15 | @override 16 | Widget build(BuildContext context) { 17 | // 从其他页面传入的搜索关键词,将当前输入框的值绑定为传入的值 18 | _textEditController.text = widget.keyword; 19 | // 控制输入框光标位置为最后一个字 20 | _textEditController.selection = TextSelection.fromPosition( 21 | TextPosition( 22 | affinity: TextAffinity.downstream, offset: widget.keyword.length), 23 | ); 24 | return Container( 25 | color: Colors.white, 26 | height: 49, 27 | padding: EdgeInsets.only(top: 7, right: 15, bottom: 7, left: 15), 28 | child: Row( 29 | children: [ 30 | Expanded( 31 | child: Container( 32 | decoration: BoxDecoration( 33 | color: Color(0xFFF5F7F7), 34 | borderRadius: BorderRadius.circular(49 * 0.5), 35 | ), 36 | child: Container( 37 | child: TextField( 38 | controller: _textEditController, 39 | cursorColor: AppColors.primaryColor, 40 | decoration: InputDecoration( 41 | prefixIcon: Image.asset( 42 | 'assets/images/home/sousuo.png', 43 | width: 15, 44 | height: 15, 45 | ), 46 | isDense: true, 47 | hintText: "最高可降8000", 48 | border: InputBorder.none, 49 | ), 50 | ), 51 | ), 52 | ), 53 | ), 54 | GestureDetector( 55 | /// 将输入值回调传至点击函数 56 | onTap: () => widget.myOntap(_textEditController.text), 57 | child: Container( 58 | padding: EdgeInsets.only(left: 12), 59 | child: Text( 60 | '搜索', 61 | style: TextStyle( 62 | color: Color(0xFF17191A), 63 | fontSize: 16, 64 | fontWeight: FontWeight.normal, 65 | ), 66 | ), 67 | ), 68 | ) 69 | ], 70 | ), 71 | ); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /lib/config/config.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/env.dart'; 2 | 3 | // 开发环境 4 | const SERVER_HOST_DEV = 'http://xieyezi.com:9003/mock/11/airi'; 5 | 6 | // 生产环境 7 | const SERVER_HOST_PROD = 'http://xieyezi.com:9003/mock/11/airi'; 8 | 9 | const SERVER_API_URL = ENV == "DEV" ? SERVER_HOST_DEV : SERVER_HOST_PROD; 10 | -------------------------------------------------------------------------------- /lib/env.dart: -------------------------------------------------------------------------------- 1 | const ENV = 'DEV'; 2 | -------------------------------------------------------------------------------- /lib/json/detil.json: -------------------------------------------------------------------------------- 1 | { 2 | "bannerList": [ 3 | "https://yanxuan.nosdn.127.net/5efcbeecb663e629c1bb309c7b356f60.png", 4 | "https://yanxuan.nosdn.127.net/f968b48c45f29fc1a15b6cff7f92368d.png", 5 | "https://yanxuan.nosdn.127.net/17cbeab4e5e47ef2b5fa0f2adce6cbc2.png", 6 | "https://yanxuan.nosdn.127.net/cf035e09fe2fae909e5d378ccd396e56.png", 7 | "https://yanxuan.nosdn.127.net/53dd392169abf4984ee5daec84510826.png", 8 | "https://yanxuan.nosdn.127.net/1f22276749f73010ae94ae6b8960d201.png" 9 | ], 10 | "specificationList": [ 11 | { 12 | "name": "规格名称1", 13 | "specification": [ 14 | "规格值1", 15 | "规格值2", 16 | "规格值3", 17 | "规格值4", 18 | "规格值5", 19 | "规格值6", 20 | "规格值7" 21 | ] 22 | }, 23 | { 24 | "name": "规格名称2", 25 | "specification": [ 26 | "规格值8", 27 | "规格值9", 28 | "规格值10", 29 | "特别特别特别特别长的规格" 30 | ] 31 | } 32 | ], 33 | "contact": "17783887443", 34 | "goodsName": "蔻驰 COACH 奢侈品 女士深棕色PVC手提单肩包 F57842 IMAA8", 35 | "brandName": "蔻驰", 36 | "goodsSeries": "春夏上新", 37 | "price": "5000.0", 38 | "supplierId": "12313", 39 | "supplierName": "蔻驰", 40 | "supplierCode": "zs11WBD66666", 41 | "platformCode": "zs11WBD66666", 42 | "produceTime": "999天", 43 | 44 | "guidePrice": "6599.0", 45 | "miniBuyNum": "999", 46 | "goodsImgUrl": "https://yanxuan.nosdn.127.net/1f22276749f73010ae94ae6b8960d201.png" 47 | } 48 | -------------------------------------------------------------------------------- /lib/json/search.json: -------------------------------------------------------------------------------- 1 | { 2 | "result": [ 3 | { 4 | "goodsId": "3469", 5 | "goodsMiniPrice": "2800", 6 | "goodsName": "懒人沙发", 7 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/65a7ae2867d891a241dd8291a9037c84.png" 8 | }, 9 | { 10 | "goodsId": "3465", 11 | "goodsMiniPrice": "3800", 12 | "goodsName": "懒人沙发", 13 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/cc507ff0ce7cafc1012885a01fb1942a.png" 14 | }, 15 | { 16 | "goodsId": "3455", 17 | "goodsMiniPrice": "4800", 18 | "goodsName": "懒人沙发", 19 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/4628932649a190c464d138c9236591fa.png" 20 | }, 21 | { 22 | "goodsId": "3469", 23 | "goodsMiniPrice": "2800", 24 | "goodsName": "懒人沙发", 25 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/d04070745e3e6b7588aba519d48ad9d6.png" 26 | }, 27 | { 28 | "goodsId": "3465", 29 | "goodsMiniPrice": "3800", 30 | "goodsName": "懒人沙发", 31 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/dd9cd8d2dae44d4319ab21919021435b.png" 32 | }, 33 | { 34 | "goodsId": "3455", 35 | "goodsMiniPrice": "4800", 36 | "goodsName": "优迪 ZS125T-64", 37 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/567f5588c5c86eeca8c94413d7c45e47.png" 38 | }, 39 | { 40 | "goodsId": "3469", 41 | "goodsMiniPrice": "2800", 42 | "goodsName": "懒人沙发", 43 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/c8af5398744d2ed87d2459ec3d29d83e.png" 44 | }, 45 | { 46 | "goodsId": "3465", 47 | "goodsMiniPrice": "3800", 48 | "goodsName": "懒人沙发", 49 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/09f2f2e348111984dd2c65dd8bcbf5d8.png" 50 | }, 51 | { 52 | "goodsId": "3455", 53 | "goodsMiniPrice": "4800", 54 | "goodsName": "懒人沙发", 55 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/0001332cb0db9939076f56c1dddbad26.png" 56 | }, 57 | { 58 | "goodsId": "3455", 59 | "goodsMiniPrice": "4800", 60 | "goodsName": "懒人沙发", 61 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/0001332cb0db9939076f56c1dddbad26.png" 62 | } 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /lib/json/supplier.json: -------------------------------------------------------------------------------- 1 | { 2 | "supplierName": "优衣库官方旗舰店", 3 | "contact": "觉非", 4 | "phoneNum": "17783887443", 5 | "workTime": "上午10:00 - 下午20:00", 6 | "address": "重庆市巴南区花溪街道", 7 | "supplierImgUrl": "https://yanxuan.nosdn.127.net/38b49a2863971efec7ec9b6ad3c0f96a.png", 8 | "introDuceText": "品牌也远不是强调名称,标志,符号或者商标。它融合了一系列定义其形象的独特价值,并作为一份不成文的合同,通过在消费者每一次购买,使用,体验是提供始终如一的产品和服务。", 9 | 10 | "supplierList": [ 11 | { 12 | "goodsId": "3469", 13 | "goodsMiniPrice": "2800", 14 | "goodsName": "顾家家居 布艺懒人沙发 ", 15 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/65a7ae2867d891a241dd8291a9037c84.png" 16 | }, 17 | { 18 | "goodsId": "3465", 19 | "goodsMiniPrice": "3800", 20 | "goodsName": "顾家家居 布艺懒人沙发 ", 21 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/cc507ff0ce7cafc1012885a01fb1942a.png" 22 | }, 23 | { 24 | "goodsId": "3455", 25 | "goodsMiniPrice": "4800", 26 | "goodsName": "顾家家居 布艺懒人沙发 ", 27 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/4628932649a190c464d138c9236591fa.png" 28 | }, 29 | { 30 | "goodsId": "3469", 31 | "goodsMiniPrice": "2800", 32 | "goodsName": "顾家家居 布艺懒人沙发 ", 33 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/d04070745e3e6b7588aba519d48ad9d6.png" 34 | }, 35 | { 36 | "goodsId": "3465", 37 | "goodsMiniPrice": "3800", 38 | "goodsName": "顾家家居 布艺懒人沙发 ", 39 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/dd9cd8d2dae44d4319ab21919021435b.png" 40 | }, 41 | { 42 | "goodsId": "3455", 43 | "goodsMiniPrice": "4800", 44 | "goodsName": "顾家家居 布艺懒人沙发 ", 45 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/567f5588c5c86eeca8c94413d7c45e47.png" 46 | }, 47 | { 48 | "goodsId": "3469", 49 | "goodsMiniPrice": "2800", 50 | "goodsName": "顾家家居 布艺懒人沙发 ", 51 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/c8af5398744d2ed87d2459ec3d29d83e.png" 52 | }, 53 | { 54 | "goodsId": "3465", 55 | "goodsMiniPrice": "3800", 56 | "goodsName": "顾家家居 布艺懒人沙发 ", 57 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/09f2f2e348111984dd2c65dd8bcbf5d8.png" 58 | }, 59 | { 60 | "goodsId": "3455", 61 | "goodsMiniPrice": "4800", 62 | "goodsName": "顾家家居 布艺懒人沙发 ", 63 | "goodsPicUrl": "https://yanxuan.nosdn.127.net/0001332cb0db9939076f56c1dddbad26.png" 64 | } 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:AiRi/pages/login/login_page.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:oktoast/oktoast.dart'; 6 | import 'package:provider/provider.dart'; 7 | import 'package:pull_to_refresh/pull_to_refresh.dart'; 8 | import 'package:flutter_localizations/flutter_localizations.dart'; 9 | import 'package:AiRi/styles/colors.dart'; 10 | import 'package:shared_preferences/shared_preferences.dart'; 11 | import 'pages/main/main_page.dart'; 12 | import 'pages/main/store/main_provider.dart'; 13 | import 'pages/shopping_cart/store/shopping_cart_global_provider.dart'; 14 | 15 | Future main() async { 16 | // 判断是否已经登录 17 | WidgetsFlutterBinding.ensureInitialized(); 18 | SharedPreferences prefs = await SharedPreferences.getInstance(); 19 | bool isLogin = prefs.getBool('isLogin') ?? false; 20 | print('是否已经登录---' + isLogin.toString()); 21 | runApp( 22 | MultiProvider( 23 | providers: [ 24 | ChangeNotifierProvider(create: (_) => MainProvider()), 25 | ChangeNotifierProvider(create: (_) => ShopingCartGlobalProvider()), 26 | ], 27 | child: MyApp( 28 | isLogin: isLogin, 29 | ), 30 | ), 31 | ); 32 | // 透明状态栏 33 | if (Platform.isAndroid) { 34 | SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(statusBarColor: Colors.transparent); 35 | SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); 36 | } 37 | } 38 | 39 | class MyApp extends StatelessWidget { 40 | final isLogin; 41 | const MyApp({Key? key, this.isLogin}) : super(key: key); 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return OKToast( 46 | child: RefreshConfiguration( 47 | hideFooterWhenNotFull: true, // Viewport不满一屏时,禁用上拉加载更多功能 48 | enableBallisticLoad: true, // 可以通过惯性滑动触发加载更多 49 | child: MaterialApp( 50 | title: 'AiRi', 51 | localizationsDelegates: [ 52 | RefreshLocalizations.delegate, 53 | GlobalMaterialLocalizations.delegate, 54 | GlobalWidgetsLocalizations.delegate, 55 | ], 56 | supportedLocales: [ 57 | const Locale('en'), 58 | const Locale('zh'), 59 | ], 60 | localeResolutionCallback: (Locale? locale, Iterable supportedLocales) { 61 | return locale; 62 | }, 63 | theme: ThemeData( 64 | primarySwatch: Colors.purple, 65 | primaryColor: AppColors.primaryColor, 66 | accentColor: AppColors.primaryColorAccent, 67 | ), 68 | debugShowCheckedModeBanner: false, 69 | home: isLogin ? MainPage() : LoginPage(), 70 | ), 71 | ), 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/model/category.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | CateGoryModel cateGoryModelFromJson(String str) => 4 | CateGoryModel.fromJson(json.decode(str)); 5 | 6 | String cateGoryModelToJson(CateGoryModel data) => json.encode(data.toJson()); 7 | 8 | class CateGoryModel { 9 | List categoryData; 10 | 11 | CateGoryModel({ 12 | required this.categoryData, 13 | }); 14 | 15 | factory CateGoryModel.fromJson(Map json) => CateGoryModel( 16 | categoryData: List.from( 17 | json["categoryData"].map((x) => CategoryDatum.fromJson(x))), 18 | ); 19 | 20 | Map toJson() => { 21 | "categoryData": List.from(categoryData.map((x) => x.toJson())), 22 | }; 23 | } 24 | 25 | class CategoryDatum { 26 | String name; 27 | String banner; 28 | List list; 29 | 30 | CategoryDatum({ 31 | required this.name, 32 | required this.banner, 33 | required this.list, 34 | }); 35 | 36 | factory CategoryDatum.fromJson(Map json) => CategoryDatum( 37 | name: json["name"], 38 | banner: json["banner"], 39 | list: List.from( 40 | json["list"].map((x) => ListElement.fromJson(x))), 41 | ); 42 | 43 | Map toJson() => { 44 | "name": name, 45 | "banner": banner, 46 | "list": List.from(list.map((x) => x.toJson())), 47 | }; 48 | } 49 | 50 | class ListElement { 51 | String name; 52 | String icon; 53 | 54 | ListElement({ 55 | required this.name, 56 | required this.icon, 57 | }); 58 | 59 | factory ListElement.fromJson(Map json) => ListElement( 60 | name: json["name"], 61 | icon: json["icon"], 62 | ); 63 | 64 | Map toJson() => { 65 | "name": name, 66 | "icon": icon, 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /lib/model/detail.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | DetailModel detailModelFromJson(String str) => DetailModel.fromJson(json.decode(str)); 4 | 5 | String detailModelToJson(DetailModel data) => json.encode(data.toJson()); 6 | 7 | class DetailModel { 8 | List bannerList; 9 | List specificationList; 10 | String contact; 11 | String goodsName; 12 | String brandName; 13 | String goodsSeries; 14 | String price; 15 | String supplierId; 16 | String supplierName; 17 | String supplierCode; 18 | String platformCode; 19 | String produceTime; 20 | String guidePrice; 21 | String miniBuyNum; 22 | String goodsImgUrl; 23 | 24 | DetailModel({ 25 | required this.bannerList, 26 | required this.specificationList, 27 | required this.contact, 28 | required this.goodsName, 29 | required this.brandName, 30 | required this.goodsSeries, 31 | required this.price, 32 | required this.supplierId, 33 | required this.supplierName, 34 | required this.supplierCode, 35 | required this.platformCode, 36 | required this.produceTime, 37 | required this.guidePrice, 38 | required this.miniBuyNum, 39 | required this.goodsImgUrl, 40 | }); 41 | 42 | factory DetailModel.fromJson(Map json) => DetailModel( 43 | bannerList: List.from(json["bannerList"].map((x) => x)), 44 | specificationList: 45 | List.from(json["specificationList"].map((x) => SpecificationList.fromJson(x))), 46 | contact: json["contact"], 47 | goodsName: json["goodsName"], 48 | brandName: json["brandName"], 49 | goodsSeries: json["goodsSeries"], 50 | price: json["price"], 51 | supplierId: json["supplierId"], 52 | supplierName: json["supplierName"], 53 | supplierCode: json["supplierCode"], 54 | platformCode: json["platformCode"], 55 | produceTime: json["produceTime"], 56 | guidePrice: json["guidePrice"], 57 | miniBuyNum: json["miniBuyNum"], 58 | goodsImgUrl: json["goodsImgUrl"], 59 | ); 60 | 61 | Map toJson() => { 62 | "bannerList": List.from(bannerList.map((x) => x)), 63 | "specificationList": List.from(specificationList.map((x) => x.toJson())), 64 | "contact": contact, 65 | "goodsName": goodsName, 66 | "brandName": brandName, 67 | "goodsSeries": goodsSeries, 68 | "price": price, 69 | "supplierId": supplierId, 70 | "supplierName": supplierName, 71 | "supplierCode": supplierCode, 72 | "platformCode": platformCode, 73 | "produceTime": produceTime, 74 | "guidePrice": guidePrice, 75 | "miniBuyNum": miniBuyNum, 76 | "goodsImgUrl": goodsImgUrl, 77 | }; 78 | } 79 | 80 | class SpecificationList { 81 | String name; 82 | List specification; 83 | 84 | SpecificationList({ 85 | required this.name, 86 | required this.specification, 87 | }); 88 | 89 | factory SpecificationList.fromJson(Map json) => SpecificationList( 90 | name: json["name"], 91 | specification: List.from(json["specification"].map((x) => x)), 92 | ); 93 | 94 | Map toJson() => { 95 | "name": name, 96 | "specification": List.from(specification.map((x) => x)), 97 | }; 98 | } 99 | -------------------------------------------------------------------------------- /lib/model/goods.dart: -------------------------------------------------------------------------------- 1 | /// 商品列表Model 2 | class GoodsList { 3 | String goodsId; 4 | String goodsMiniPrice; 5 | String goodsName; 6 | String goodsPicUrl; 7 | 8 | GoodsList({ 9 | required this.goodsId, 10 | required this.goodsMiniPrice, 11 | required this.goodsName, 12 | required this.goodsPicUrl, 13 | }); 14 | 15 | factory GoodsList.fromJson(Map json) => GoodsList( 16 | goodsId: json["goodsId"], 17 | goodsMiniPrice: json["goodsMiniPrice"], 18 | goodsName: json["goodsName"], 19 | goodsPicUrl: json["goodsPicUrl"], 20 | ); 21 | 22 | Map toJson() => { 23 | "goodsId": goodsId, 24 | "goodsMiniPrice": goodsMiniPrice, 25 | "goodsName": goodsName, 26 | "goodsPicUrl": goodsPicUrl, 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /lib/model/home.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'goods.dart'; 4 | 5 | HomeModel homeModelFromJson(String str) => HomeModel.fromJson(json.decode(str)); 6 | 7 | String homeModelToJson(HomeModel data) => json.encode(data.toJson()); 8 | 9 | class HomeModel { 10 | List banerList; 11 | List cateGoryList; 12 | List brandList; 13 | List hotList; 14 | 15 | HomeModel({ 16 | required this.banerList, 17 | required this.cateGoryList, 18 | required this.brandList, 19 | required this.hotList, 20 | }); 21 | 22 | factory HomeModel.fromJson(Map json) => HomeModel( 23 | banerList: List.from(json["banerList"].map((x) => x)), 24 | cateGoryList: List.from(json["cateGoryList"].map((x) => BrandListElement.fromJson(x))), 25 | brandList: List.from(json["brandList"].map((x) => BrandListElement.fromJson(x))), 26 | hotList: List.from(json["hotList"].map((x) => GoodsList.fromJson(x))), 27 | ); 28 | 29 | Map toJson() => { 30 | "banerList": List.from(banerList.map((x) => x)), 31 | "cateGoryList": List.from(cateGoryList.map((x) => x.toJson())), 32 | "brandList": List.from(brandList.map((x) => x.toJson())), 33 | "hotList": List.from(hotList.map((x) => x.toJson())), 34 | }; 35 | } 36 | 37 | class BrandListElement { 38 | String name; 39 | String icon; 40 | 41 | BrandListElement({ 42 | required this.name, 43 | required this.icon, 44 | }); 45 | 46 | factory BrandListElement.fromJson(Map json) => BrandListElement( 47 | name: json["name"], 48 | icon: json["icon"], 49 | ); 50 | 51 | Map toJson() => { 52 | "name": name, 53 | "icon": icon, 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /lib/model/search.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'goods.dart'; 3 | 4 | SearchModel searchModelFromJson(String str) => SearchModel.fromJson(json.decode(str)); 5 | 6 | String searchModelToJson(SearchModel data) => json.encode(data.toJson()); 7 | 8 | class SearchModel { 9 | List result; 10 | 11 | SearchModel({ 12 | required this.result, 13 | }); 14 | 15 | factory SearchModel.fromJson(Map json) => SearchModel( 16 | result: List.from(json["result"].map((x) => GoodsList.fromJson(x))), 17 | ); 18 | 19 | Map toJson() => { 20 | "result": List.from(result.map((x) => x.toJson())), 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /lib/model/supplier.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:AiRi/model/goods.dart'; 4 | 5 | SupplierModel supplierModelFromJson(String str) => SupplierModel.fromJson(json.decode(str)); 6 | 7 | String supplierModelToJson(SupplierModel data) => json.encode(data.toJson()); 8 | 9 | class SupplierModel { 10 | String supplierName; 11 | String contact; 12 | String phoneNum; 13 | String workTime; 14 | String supplierImgUrl; 15 | String introDuceText; 16 | List supplierList; 17 | 18 | SupplierModel({ 19 | required this.supplierName, 20 | required this.contact, 21 | required this.phoneNum, 22 | required this.workTime, 23 | required this.supplierImgUrl, 24 | required this.introDuceText, 25 | required this.supplierList, 26 | }); 27 | 28 | factory SupplierModel.fromJson(Map json) => SupplierModel( 29 | supplierName: json["supplierName"], 30 | contact: json["contact"], 31 | phoneNum: json["phoneNum"], 32 | workTime: json["workTime"], 33 | supplierImgUrl: json["supplierImgUrl"], 34 | introDuceText: json["introDuceText"], 35 | supplierList: List.from(json["supplierList"].map((x) => GoodsList.fromJson(x))), 36 | ); 37 | 38 | Map toJson() => { 39 | "supplierName": supplierName, 40 | "contact": contact, 41 | "phoneNum": phoneNum, 42 | "workTime": workTime, 43 | "supplierImgUrl": supplierImgUrl, 44 | "introDuceText": introDuceText, 45 | "supplierList": List.from(supplierList.map((x) => x.toJson())), 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /lib/pages/category/category_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:AiRi/pages/category/store/category_page_provider.dart'; 5 | import 'package:AiRi/pages/search/search_page.dart'; 6 | import 'package:AiRi/utils/my_navigator.dart'; 7 | import 'components/menue.dart'; 8 | import 'components/right_list_view.dart'; 9 | 10 | class CategoryPage extends StatelessWidget { 11 | const CategoryPage({Key? key}) : super(key: key); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return ChangeNotifierProvider( 16 | create: (_) => CateGoryPageProvider(), 17 | child: BaseScaffold( 18 | leadType: AppBarBackType.None, 19 | actions: [AppBarShopCartIconButton()], 20 | title: '分类', 21 | body: Category(), 22 | ), 23 | ); 24 | } 25 | } 26 | 27 | class Category extends StatefulWidget { 28 | Category({Key? key}) : super(key: key); 29 | @override 30 | State createState() => CategoryState(); 31 | } 32 | 33 | class CategoryState extends State with AutomaticKeepAliveClientMixin { 34 | int currentPage = 0; 35 | GlobalKey rightListviewKey = new GlobalKey(); 36 | GlobalKey categoryMenueKey = new GlobalKey(); 37 | 38 | bool isAnimating = false; 39 | int itemCount = 0; 40 | late double menueWidth; 41 | late double itemHeight; 42 | late double height; 43 | @override 44 | Widget build(BuildContext context) { 45 | super.build(context); 46 | final double statusBarHeight = MediaQuery.of(context).padding.top; // 顶部状态栏高度 47 | final double bottomBarHeight = MediaQuery.of(context).padding.bottom; // 底部状态栏高度 48 | final double scafoldHeight = 44; // Scafold高度 49 | final double searchBarHeight = 49; // 搜索框的高度 50 | final double bottomTabbarHeight = 49; // 底部tabBar的高度 51 | final double rightListViewHeight = MediaQuery.of(context).size.height - 52 | statusBarHeight - 53 | bottomBarHeight - 54 | scafoldHeight - 55 | searchBarHeight - 56 | bottomTabbarHeight; 57 | // final double rightListViewHeight = 600; 58 | final state = Provider.of(context); 59 | // List listViewData = []; 60 | return state.loading 61 | ? MyLoadingWidget() 62 | : Container( 63 | color: Color(0xFFFFFFFF), 64 | child: Column( 65 | children: [ 66 | SearchBar( 67 | myOntap: (value) => MyNavigator.push(SearchPage(title: '搜索', keyword: value)), 68 | ), 69 | Expanded( 70 | child: Row( 71 | children: [ 72 | SingleChildScrollView( 73 | child: Container( 74 | color: Color(0xFFf7f7f7), 75 | width: 100, 76 | child: CategoryMenue( 77 | key: categoryMenueKey, 78 | items: state.categoryData.map((i) { 79 | return i.name; 80 | }).toList(), 81 | itemHeight: 60, 82 | itemWidth: 80, 83 | menueTaped: menueItemTap), 84 | ), 85 | ), 86 | RightListView( 87 | key: rightListviewKey, 88 | height: rightListViewHeight, 89 | dataItems: state.categoryData, 90 | listViewChanged: listViewChanged) 91 | ], 92 | ), 93 | ) 94 | ], 95 | )); 96 | } 97 | 98 | menueItemTap(int i) { 99 | rightListviewKey.currentState!.jumpTopage(i); 100 | } 101 | 102 | listViewChanged(i) { 103 | this.categoryMenueKey.currentState!.moveToTap(i); 104 | } 105 | 106 | @override 107 | bool get wantKeepAlive => true; 108 | } 109 | -------------------------------------------------------------------------------- /lib/pages/category/components/list_view_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:AiRi/model/category.dart'; 4 | import 'package:AiRi/pages/search/search_page.dart'; 5 | import 'package:AiRi/utils/my_navigator.dart'; 6 | 7 | class SubCategoryList extends StatefulWidget { 8 | final double height; 9 | final CategoryDatum? data; 10 | final void Function(String) goPage; 11 | SubCategoryList({Key? key, required this.height, required this.goPage, this.data}) : super(key: key); 12 | @override 13 | State createState() => SubCategoryListState(); 14 | } 15 | 16 | class SubCategoryListState extends State { 17 | ScrollController controller = ScrollController(); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Listener( 22 | onPointerUp: this.dragend, 23 | child: Container( 24 | height: widget.height, 25 | child: SingleChildScrollView( 26 | physics: BouncingScrollPhysics(), 27 | padding: EdgeInsets.only(top: 13, bottom: 40), 28 | controller: controller, 29 | // physics: NeverScrollableScrollPhysics(), 30 | child: Container( 31 | child: widget.data != null 32 | ? SecondryCategory(data: widget.data ?? CategoryDatum(name: '', banner: '', list: [])) 33 | : Center( 34 | child: CircularProgressIndicator(), 35 | ), 36 | constraints: BoxConstraints(minHeight: widget.height + 5), 37 | )), 38 | ), 39 | ); 40 | } 41 | 42 | dragend(e) { 43 | double offset = controller.offset; 44 | double maxExtentLenght = controller.position.maxScrollExtent; 45 | if (offset < -50) { 46 | widget.goPage('pre'); 47 | } 48 | if (offset - maxExtentLenght > 50) { 49 | widget.goPage('next'); 50 | } 51 | } 52 | 53 | @override 54 | void dispose() { 55 | controller.dispose(); 56 | super.dispose(); 57 | } 58 | } 59 | 60 | class SecondryCategory extends StatelessWidget { 61 | final CategoryDatum data; 62 | SecondryCategory({Key? key, required this.data}) : super(key: key); 63 | @override 64 | Widget build(BuildContext context) { 65 | List items = data.list; 66 | 67 | final _deviceWidth = MediaQuery.of(context).size.width; 68 | final _crossAxisCount = (_deviceWidth - 100) ~/ 80; 69 | final _childAspectRatio = (_deviceWidth - 100) / _crossAxisCount / 100; 70 | 71 | return Column( 72 | children: [ 73 | Container( 74 | height: 92, 75 | margin: EdgeInsets.only(left: 15, right: 15), 76 | child: MyCachedNetworkImage( 77 | imageurl: data.banner, 78 | ), 79 | ), 80 | GridView.count( 81 | childAspectRatio: _childAspectRatio, 82 | crossAxisCount: _crossAxisCount, 83 | shrinkWrap: true, 84 | physics: NeverScrollableScrollPhysics(), 85 | children: items.map((i) { 86 | return GestureDetector( 87 | onTap: () => MyNavigator.push(SearchPage(title: i.name, keyword: i.name)), 88 | child: Container( 89 | margin: EdgeInsets.only(top: 10), 90 | child: Column( 91 | children: [ 92 | Container( 93 | margin: EdgeInsets.only(bottom: 7), 94 | height: 50, 95 | width: 50, 96 | child: MyCachedNetworkImage( 97 | imageurl: i.icon, 98 | ), 99 | ), 100 | Text( 101 | i.name, 102 | overflow: TextOverflow.ellipsis, 103 | maxLines: 1, 104 | style: TextStyle(fontSize: 12), 105 | ) 106 | ], 107 | )), 108 | ); 109 | }).toList(), 110 | ), 111 | ], 112 | ); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /lib/pages/category/components/menue.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/styles/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/animation.dart'; 4 | 5 | class CategoryMenue extends StatefulWidget { 6 | final List items; 7 | final double itemHeight; 8 | final double itemWidth; 9 | final ValueChanged menueTaped; 10 | CategoryMenue( 11 | {Key? key, required this.items, required this.itemHeight, required this.itemWidth, required this.menueTaped}) 12 | : super(key: key); 13 | @override 14 | State createState() => CategoryMenueState(); 15 | } 16 | 17 | class CategoryMenueState extends State with SingleTickerProviderStateMixin { 18 | late Animation animation; 19 | late AnimationController controller; 20 | int currentItemIndex = 0; 21 | @override 22 | Widget build(BuildContext context) { 23 | int len = widget.items.length; 24 | List widgets = List.generate(len, (i) { 25 | return InkWell( 26 | onTap: () => _menueTaped(i), 27 | child: Container( 28 | height: widget.itemHeight, 29 | alignment: Alignment.center, 30 | child: currentItemIndex == i 31 | ? Container( 32 | padding: EdgeInsets.only(top: 5, bottom: 5, left: 12, right: 12), 33 | decoration: BoxDecoration( 34 | gradient: LinearGradient( 35 | //背景径向渐变 36 | colors: [AppColors.buttonLine1, AppColors.buttonLine2], 37 | ), 38 | borderRadius: BorderRadius.circular(20.0), 39 | ), 40 | child: Text( 41 | widget.items[i], 42 | style: TextStyle( 43 | fontSize: 14, 44 | color: Colors.white, 45 | ), 46 | ), 47 | ) 48 | : Container( 49 | child: Text( 50 | widget.items[i], 51 | style: TextStyle( 52 | fontSize: 14, 53 | color: Color(0xFF4A4A4A), 54 | ), 55 | ), 56 | ), 57 | ), 58 | ); 59 | }); 60 | 61 | return Column(children: widgets); 62 | } 63 | 64 | _menueTaped(int i) { 65 | widget.menueTaped(i); 66 | moveToTap(i); 67 | } 68 | 69 | moveToTap(int i) { 70 | double begin = currentItemIndex * widget.itemHeight; 71 | double end = i * widget.itemHeight; 72 | // print('begin' + begin.toString() + "-----" + end.toString()); 73 | animation = Tween(begin: begin, end: end).animate(new CurvedAnimation(parent: controller, curve: Curves.linear)); 74 | controller.addStatusListener((status) { 75 | if (AnimationStatus.completed == status) { 76 | // print(currentItemIndex); 77 | currentItemIndex = i; 78 | } 79 | }); 80 | 81 | controller.forward(from: 0); 82 | } 83 | 84 | initState() { 85 | controller = AnimationController(duration: Duration(milliseconds: 150), vsync: this); 86 | animation = Tween(begin: 0.0, end: 0.0).animate(controller); 87 | controller.addListener(() { 88 | if (mounted) { 89 | setState(() {}); 90 | } 91 | }); 92 | controller.forward(); 93 | super.initState(); 94 | } 95 | 96 | @override 97 | void dispose() { 98 | controller.dispose(); 99 | super.dispose(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /lib/pages/category/components/right_list_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:AiRi/model/category.dart'; 3 | import 'list_view_item.dart'; 4 | 5 | class RightListView extends StatefulWidget { 6 | final double height; 7 | final List dataItems; 8 | final ValueChanged listViewChanged; 9 | RightListView({Key? key, required this.height, required this.dataItems, required this.listViewChanged}) 10 | : super(key: key); 11 | @override 12 | State createState() => RightListViewState(); 13 | } 14 | 15 | class RightListViewState extends State { 16 | int currentPage = 0; 17 | bool isAnimating = false; 18 | int itemCount = 0; 19 | ScrollController controller = ScrollController(); 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | itemCount = widget.dataItems.length; 24 | return Expanded( 25 | // child: NotificationListener( 26 | // onNotification: (a){ 27 | // if(a.depth==0){ 28 | // //判断一下是否是滑动的整块,纠正一下 29 | // } 30 | // }, 31 | child: ListView.builder( 32 | physics: NeverScrollableScrollPhysics(), //禁用手动滑动,于是有了上面的注释 33 | padding: EdgeInsets.all(0), 34 | controller: controller, 35 | itemBuilder: _itembuilder, 36 | itemCount: itemCount, 37 | itemExtent: widget.height, 38 | ), 39 | // ), 40 | ); 41 | } 42 | 43 | Widget _itembuilder(BuildContext context, int index) { 44 | var data = widget.dataItems[index]; 45 | return SubCategoryList(data: data, height: widget.height, goPage: goPage); 46 | } 47 | 48 | void goPage(String tag) { 49 | if (this.isAnimating) return; 50 | if (tag == 'pre') { 51 | if (currentPage == 0) { 52 | return; 53 | } else { 54 | currentPage--; 55 | } 56 | } else { 57 | if (currentPage == itemCount - 1) { 58 | return; 59 | } else { 60 | currentPage++; 61 | } 62 | } 63 | widget.listViewChanged(currentPage); 64 | animateTopage(currentPage); 65 | } 66 | 67 | jumpTopage(int i) { 68 | currentPage = i; 69 | double offset = widget.height * i; 70 | this.controller.jumpTo(offset); 71 | } 72 | 73 | animateTopage(int i) { 74 | if (this.isAnimating) return; 75 | currentPage = i; 76 | this.isAnimating = true; 77 | double offset = widget.height * i; 78 | this 79 | .controller 80 | .animateTo(offset, 81 | duration: Duration(milliseconds: 300), curve: Curves.easeOut) 82 | .then((onValue) => this.isAnimating = false); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/pages/category/store/category_page_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:AiRi/model/category.dart'; 3 | import 'package:AiRi/services/services.dart'; 4 | 5 | class CateGoryPageProvider with ChangeNotifier { 6 | bool loading = true; 7 | late List categoryData; 8 | 9 | CateGoryPageProvider() { 10 | /// 数据加载 11 | initData(); 12 | } 13 | 14 | Future initData() async { 15 | CateGoryModel res = await CateGoryAPI.getData(); 16 | 17 | /// 加载数据 18 | categoryData = res.categoryData; 19 | loading = false; 20 | notifyListeners(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/pages/choose_address/choose_address.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:AiRi/utils/my_navigator.dart'; 4 | 5 | class ChooseAddress extends StatelessWidget { 6 | const ChooseAddress({Key? key}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return BaseScaffold( 11 | leadType: AppBarBackType.Back, 12 | title: '选择地址', 13 | body: ChooseAddressContainer(), 14 | ); 15 | } 16 | } 17 | 18 | class ChooseAddressContainer extends StatelessWidget { 19 | const ChooseAddressContainer({Key? key}) : super(key: key); 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | final List addAressList = [1, 2, 3]; 24 | return Container( 25 | color: Color(0xFFF7F7F7), 26 | margin: EdgeInsets.only(top: 10), 27 | child: ListView.builder( 28 | itemCount: addAressList.length, 29 | itemBuilder: (context, index) { 30 | return GestureDetector( 31 | onTap: () { 32 | MyNavigator.pop(data: addAressList[index]); 33 | }, 34 | child: _buildItem(context)); 35 | }), 36 | ); 37 | } 38 | 39 | /// 每一项 40 | Widget _buildItem(BuildContext context) { 41 | TextStyle nameText = TextStyle( 42 | color: Color(0xFF121212), 43 | fontSize: 16, 44 | fontWeight: FontWeight.w500, 45 | ); 46 | TextStyle addressText = TextStyle( 47 | color: Color(0xFF4A4A4A), 48 | fontSize: 12, 49 | fontWeight: FontWeight.w400, 50 | ); 51 | return Column( 52 | children: [ 53 | Container( 54 | color: Colors.white, 55 | padding: EdgeInsets.only(top: 10, bottom: 15, left: 15, right: 15), 56 | child: Column( 57 | children: [ 58 | Row( 59 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 60 | children: [ 61 | Text('张晓峰', style: nameText), 62 | Text('18888888888', style: nameText), 63 | ], 64 | ), 65 | Container( 66 | padding: EdgeInsets.only(top: 10), 67 | width: MediaQuery.of(context).size.width - 30, 68 | child: Text( 69 | '重庆 重庆市 渝北区 新天地中心21-6号地重庆 重庆市 渝北区地址重庆 重庆市', 70 | maxLines: 2, 71 | overflow: TextOverflow.ellipsis, 72 | style: addressText, 73 | ), 74 | ), 75 | ], 76 | ), 77 | ), 78 | MyDivider() 79 | ], 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/pages/confirm_order/components/bottom.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:AiRi/styles/styles.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:AiRi/pages/order_detail/order_detail_page.dart'; 5 | import 'package:AiRi/utils/my_navigator.dart'; 6 | 7 | class Bottom extends StatelessWidget { 8 | const Bottom({Key? key}) : super(key: key); 9 | 10 | // 弹出对话框 11 | void _showCancelDialog(BuildContext context) async { 12 | MyDialog.showLoading('提交中...', barrier: true); 13 | await Future.delayed(Duration(seconds: 3), () {}); 14 | MyDialog.hideLoading(); 15 | 16 | showDialog( 17 | context: context, 18 | barrierDismissible: false, 19 | builder: (_) { 20 | return CustomDialog( 21 | content: Center( 22 | child: Column( 23 | children: [ 24 | Image.asset('assets/images/confirm_order/dingdanchenggong.png'), 25 | Container( 26 | padding: EdgeInsets.only(bottom: 0.0, top: 10), 27 | child: Text( 28 | '订单提交成功', 29 | style: TextStyle(color: Color(0xFF4A4A4A), fontSize: 14.0), 30 | ), 31 | ), 32 | ], 33 | ), 34 | ), 35 | confirmContent: '查看订单', 36 | confirmTextColor: AppColors.buyNow1, 37 | cancelContent: '继续采购', 38 | isCancel: true, 39 | confirmCallback: () { 40 | /// 查看订单 41 | MyNavigator.pushAndRemove(OrderDetailPage(orderId: "dd")); 42 | }, 43 | dismissCallback: () { 44 | /// 继续采购 45 | MyNavigator.popToHome(); 46 | }, 47 | ); 48 | }); 49 | } 50 | 51 | @override 52 | Widget build(BuildContext context) { 53 | TextStyle bottomPriceText = TextStyle( 54 | color: AppColors.priceColor, 55 | fontSize: 20, 56 | fontWeight: FontWeight.w600, 57 | ); 58 | TextStyle bottomRightText = TextStyle( 59 | color: Colors.white, 60 | fontSize: 16, 61 | fontWeight: FontWeight.w500, 62 | ); 63 | return Container( 64 | height: 60 + MediaQuery.of(context).padding.bottom, 65 | padding: EdgeInsets.only(bottom: MediaQuery.of(context).padding.bottom, top: 0), 66 | width: MediaQuery.of(context).size.width, 67 | decoration: BoxDecoration( 68 | color: Colors.white, 69 | border: Border( 70 | top: BorderSide( 71 | width: 0.5, 72 | color: Color(0xffdfdfdf), 73 | ), 74 | ), 75 | ), 76 | child: Row( 77 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 78 | children: [ 79 | Container( 80 | width: MediaQuery.of(context).size.width - 128, 81 | padding: EdgeInsets.symmetric(horizontal: 15), 82 | color: Colors.white, 83 | child: Text('¥15900', style: bottomPriceText), 84 | ), 85 | GestureDetector( 86 | onTap: () => _showCancelDialog(context), 87 | child: Container( 88 | width: 128, 89 | decoration: BoxDecoration( 90 | gradient: LinearGradient( 91 | //背景径向渐变 92 | colors: [AppColors.buttonLine1, AppColors.buttonLine2], 93 | ), 94 | borderRadius: BorderRadius.circular(1.0), 95 | ), 96 | child: Center(child: Text('提交订单', style: bottomRightText)), 97 | ), 98 | ), 99 | ], 100 | ), 101 | ); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /lib/pages/confirm_order/components/remark.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:AiRi/styles/styles.dart'; 3 | 4 | class Remark extends StatefulWidget { 5 | const Remark({Key? key}) : super(key: key); 6 | 7 | @override 8 | _RemarkState createState() => _RemarkState(); 9 | } 10 | 11 | class _RemarkState extends State { 12 | final _textEditController = TextEditingController(); 13 | @override 14 | Widget build(BuildContext context) { 15 | return Container( 16 | height: 86, 17 | padding: EdgeInsets.only(left: 10, right: 10, bottom: 5), 18 | decoration: BoxDecoration( 19 | color: Colors.white, 20 | borderRadius: BorderRadius.circular(6), 21 | border: Border.all(color: Color(0xFFD9D9D9)), 22 | ), 23 | child: Column( 24 | children: [ 25 | Container( 26 | child: TextField( 27 | controller: _textEditController, 28 | cursorColor: AppColors.primaryColor, 29 | maxLines: 2, 30 | maxLength: 200, 31 | style: TextStyle( 32 | color: Color(0xFFBEBEBE), 33 | fontSize: 12, 34 | fontWeight: FontWeight.normal, 35 | ), 36 | decoration: InputDecoration( 37 | isDense: true, 38 | labelText: "订单备注", 39 | labelStyle: TextStyle( 40 | color: Color(0xFF121212), 41 | fontSize: 12, 42 | fontWeight: FontWeight.normal, 43 | ), 44 | hintText: "请输入备注信息", 45 | hintStyle: TextStyle( 46 | color: Color(0xFFBEBEBE), 47 | fontSize: 12, 48 | fontWeight: FontWeight.normal, 49 | ), 50 | border: InputBorder.none, 51 | ), 52 | ), 53 | ), 54 | ], 55 | ), 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/pages/confirm_order/confirm_order.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:AiRi/pages/shopping_cart/store/shopping_cart_provider.dart'; 5 | import 'components/bottom.dart'; 6 | import 'components/order_item.dart'; 7 | import 'components/top.dart'; 8 | 9 | class ConfirmOrderPage extends StatelessWidget { 10 | const ConfirmOrderPage({Key? key}) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | return MultiProvider( 15 | providers: [ 16 | ChangeNotifierProvider(create: (_) => ShopingCartProvider()), 17 | ], 18 | child: BaseScaffold( 19 | leadType: AppBarBackType.Back, 20 | title: '确认订单', 21 | body: GestureDetector( 22 | behavior: HitTestBehavior.translucent, 23 | onTap: () => FocusScope.of(context).requestFocus(FocusNode()), 24 | child: ConfirmOrderPageContainer(), 25 | ), 26 | ), 27 | ); 28 | } 29 | } 30 | 31 | class ConfirmOrderPageContainer extends StatelessWidget { 32 | const ConfirmOrderPageContainer({Key? key}) : super(key: key); 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | final List orderList = [1, 1]; // 订单列表 37 | return Container( 38 | color: Color(0xFFF7F7F7), 39 | child: Stack( 40 | children: [ 41 | Container( 42 | width: double.infinity, 43 | height: double.infinity, 44 | margin: EdgeInsets.only( 45 | bottom: 70 + MediaQuery.of(context).padding.bottom), 46 | child: SingleChildScrollView( 47 | physics: AlwaysScrollableScrollPhysics(), 48 | child: Column( 49 | children: [ 50 | Top(), 51 | _buildOrderList(context, orderList: orderList), 52 | ], 53 | ), 54 | ), 55 | ), 56 | Positioned( 57 | left: 0, 58 | right: 0, 59 | bottom: 0, 60 | child: Bottom(), 61 | ), 62 | ], 63 | ), 64 | ); 65 | } 66 | 67 | /// 订单列表 68 | Widget _buildOrderList(BuildContext context, {required List orderList}) { 69 | // final brandList = Provider.of(context).getBrandList; 70 | // print(brandList); 71 | return Container( 72 | margin: EdgeInsets.symmetric(vertical: 14), 73 | child: Column( 74 | children: orderList.map((item) { 75 | return OrderItem(); 76 | }).toList(), 77 | ), 78 | ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/pages/detail/components/head_swiper.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart'; 4 | 5 | class DetailHeadSwiper extends StatelessWidget { 6 | final List bannerList; 7 | const DetailHeadSwiper({Key? key, required this.bannerList}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Container( 12 | height: 375, 13 | color: Colors.white, 14 | child: Swiper( 15 | loop: false, 16 | autoplay: false, 17 | duration: 600, 18 | itemBuilder: (BuildContext context, int index) { 19 | return Center( 20 | child: CachedNetworkImage( 21 | imageUrl: bannerList[index], 22 | fit: BoxFit.cover, 23 | ), 24 | ); 25 | }, 26 | itemCount: bannerList.length, 27 | pagination: MyCustomPagination(), 28 | ), 29 | ); 30 | } 31 | } 32 | 33 | // 自定义分页效果 34 | class MyCustomPagination extends SwiperPlugin { 35 | @override 36 | Widget build(BuildContext context, SwiperPluginConfig config) { 37 | return Container( 38 | child: Positioned( 39 | bottom: 10, 40 | right: 10, 41 | child: Container( 42 | height: 25, 43 | width: 35, 44 | decoration: BoxDecoration( 45 | color: Color.fromRGBO(39, 39, 39, 0.7), 46 | borderRadius: BorderRadius.circular(25), 47 | ), 48 | child: Center( 49 | child: Row( 50 | mainAxisAlignment: MainAxisAlignment.center, 51 | children: [ 52 | Text( 53 | (config.activeIndex + 1).toString(), 54 | style: TextStyle(color: Colors.white), 55 | ), 56 | Text( 57 | '/', 58 | style: TextStyle(color: Colors.white), 59 | ), 60 | Text( 61 | config.itemCount.toString(), 62 | style: TextStyle(color: Colors.white), 63 | ) 64 | ], 65 | ), 66 | ), 67 | ), 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lib/pages/detail/detail_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:AiRi/pages/detail/components/Introduction_configuration.dart'; 5 | import 'package:AiRi/pages/detail/store/detail_page_provider.dart'; 6 | import 'package:AiRi/styles/colors.dart'; 7 | import 'package:AiRi/utils/screen.dart'; 8 | import 'components/bottom.dart'; 9 | import 'components/head_swiper.dart'; 10 | import 'components/info.dart'; 11 | import 'components/specifications.dart'; 12 | 13 | class DetailPage extends StatelessWidget { 14 | final String goodsId; 15 | const DetailPage({Key? key, required this.goodsId}) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return ChangeNotifierProvider( 20 | create: (_) => DetailPageProvider(), 21 | child: BaseScaffold( 22 | leadType: AppBarBackType.Back, 23 | actions: [ 24 | IconButton( 25 | icon: Image.asset( 26 | 'assets/images/home/fenxiang.png', 27 | width: duSetWidth(25), 28 | height: duSetHeight(23.5), 29 | ), 30 | onPressed: () {}, 31 | ), 32 | ], 33 | title: '商品详情', 34 | body: DetailContainer(), 35 | ), 36 | ); 37 | } 38 | } 39 | 40 | class DetailContainer extends StatelessWidget { 41 | const DetailContainer({Key? key}) : super(key: key); 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | final state = Provider.of(context); 46 | ////// 47 | return state.loading 48 | ? MyLoadingWidget() 49 | : Container( 50 | color: AppColors.primaryBackground, 51 | child: Stack( 52 | children: [ 53 | Container( 54 | width: double.infinity, 55 | height: double.infinity, 56 | margin: EdgeInsets.only( 57 | bottom: 70 + MediaQuery.of(context).padding.bottom), 58 | child: SingleChildScrollView( 59 | physics: AlwaysScrollableScrollPhysics(), 60 | child: Column( 61 | children: [ 62 | DetailHeadSwiper( 63 | bannerList: state.bannerList, 64 | ), 65 | MyDivider(), 66 | Info( 67 | goodsName: state.goodsName, 68 | brandName: state.brandName, 69 | goodsSeries: state.goodsSeries, 70 | price: state.price, 71 | ), 72 | MyDivider(), 73 | Specifications( 74 | price: state.price, 75 | goodsImgUrl: state.goodsImgUrl, 76 | guidePrice: state.guidePrice, 77 | miniBuyNum: state.miniBuyNum, 78 | specificationList: state.specificationList), 79 | IntroductionAndConfiguration() 80 | ], 81 | ), 82 | ), 83 | ), 84 | Positioned( 85 | left: 0, 86 | right: 0, 87 | bottom: 0, 88 | child: DetailBottom(contact: state.contact), 89 | ), 90 | ], 91 | ), 92 | ); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/pages/detail/store/detail_page_provider.dart: -------------------------------------------------------------------------------- 1 | /// detail provider 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:AiRi/model/detail.dart'; 4 | import 'package:AiRi/services/services.dart'; 5 | 6 | class DetailPageProvider with ChangeNotifier { 7 | bool loading = true; 8 | List bannerList = []; 9 | String contact = ''; 10 | String goodsName = ''; 11 | String brandName = ''; 12 | String goodsSeries = ''; 13 | String price = ''; 14 | String supplierId = ''; 15 | String supplierName = ''; 16 | String supplierCode = ''; 17 | String platformCode = ''; 18 | String produceTime = ''; 19 | String guidePrice = ''; 20 | String miniBuyNum = ''; 21 | String goodsImgUrl = ''; 22 | List specificationList = []; 23 | 24 | DetailPageProvider() { 25 | /// 数据加载 26 | initData(); 27 | } 28 | 29 | Future initData() async { 30 | DetailModel res = await DetailAPI.getData(); 31 | // print(res.specificationList); 32 | bannerList = res.bannerList; 33 | contact = res.contact; 34 | goodsName = res.goodsName; 35 | brandName = res.brandName; 36 | goodsSeries = res.goodsSeries; 37 | price = res.price; 38 | supplierId = res.supplierId; 39 | supplierName = res.supplierName; 40 | supplierCode = res.supplierCode; 41 | platformCode = res.platformCode; 42 | produceTime = res.produceTime; 43 | guidePrice = res.guidePrice; 44 | miniBuyNum = res.miniBuyNum; 45 | goodsImgUrl = res.goodsImgUrl; 46 | specificationList = res.specificationList; 47 | loading = false; 48 | notifyListeners(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/pages/home/components/brand_swiper.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:AiRi/styles/styles.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:AiRi/components/left_title.dart'; 5 | import 'package:AiRi/model/home.dart'; 6 | import 'package:AiRi/pages/supplier/supplier_page.dart'; 7 | import 'package:AiRi/utils/my_navigator.dart'; 8 | 9 | 10 | class BrandSwiper extends StatelessWidget { 11 | final List brandList; 12 | const BrandSwiper({Key? key, required this.brandList}) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Container( 17 | padding: EdgeInsets.all(15), 18 | margin: EdgeInsets.only(top: 7.5, right: 15, bottom: 7.5, left: 15), 19 | decoration: BoxDecoration( 20 | color: Colors.white, 21 | borderRadius: BorderRadius.circular(5), 22 | ), 23 | child: Column( 24 | children: [ 25 | LeftTitle( 26 | tipColor: AppColors.primaryColor, 27 | title: '品牌专场', 28 | ), 29 | Container( 30 | height: 90, 31 | padding: EdgeInsets.only(top: 15), 32 | child: ListView.builder( 33 | scrollDirection: Axis.horizontal, 34 | itemCount: brandList.length, 35 | itemBuilder: (context, index) { 36 | return _buildBrandItem(context, index); 37 | }, 38 | ), 39 | ) 40 | ], 41 | ), 42 | ); 43 | } 44 | 45 | /////////////////////////////// 46 | /// 每个品牌Item 47 | Widget _buildBrandItem(BuildContext context, int index) { 48 | return GestureDetector( 49 | behavior: HitTestBehavior.translucent, 50 | onTap: () => 51 | MyNavigator.push(SupplierPage(supplierId: brandList[index].name)), 52 | child: Container( 53 | padding: EdgeInsets.only(right: 25), 54 | child: Column( 55 | crossAxisAlignment: CrossAxisAlignment.center, 56 | children: [ 57 | Container( 58 | height: 50.0, 59 | width: 50.0, 60 | padding: EdgeInsets.only(bottom: 12), 61 | child: MyCachedNetworkImage( 62 | imageurl: brandList[index].icon, 63 | ), 64 | ), 65 | Text( 66 | brandList[index].name, 67 | style: TextStyle( 68 | color: AppColors.primaryText, 69 | fontSize: 12, 70 | fontWeight: FontWeight.normal, 71 | ), 72 | ), 73 | ], 74 | ), 75 | ), 76 | ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/pages/home/components/commodity_category.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/my_cahenetwork_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:AiRi/model/home.dart'; 5 | import 'package:AiRi/pages/main/store/main_provider.dart'; 6 | import 'package:AiRi/pages/search/search_page.dart'; 7 | import 'package:AiRi/utils/my_navigator.dart'; 8 | import '../../../styles/colors.dart'; 9 | 10 | class CommodityCateGory extends StatelessWidget { 11 | final List cateGoryList; 12 | const CommodityCateGory({Key? key, required this.cateGoryList}) : super(key: key); 13 | 14 | /////////////////////////////// 15 | List _buildGridItem(BuildContext context) { 16 | final mainProvder = Provider.of(context, listen: false); 17 | 18 | List gridItemList = []; 19 | for (int i = 0; i <= cateGoryList.length; i++) { 20 | gridItemList.add( 21 | GestureDetector( 22 | onTap: i == cateGoryList.length 23 | ? () => {mainProvder.setTabBarSelectedIndex = 1} 24 | : () => MyNavigator.push(SearchPage(title: cateGoryList[i].name, keyword: cateGoryList[i].name)), 25 | child: Container( 26 | child: Column( 27 | crossAxisAlignment: CrossAxisAlignment.center, 28 | children: [ 29 | Container( 30 | height: 60.0, 31 | width: 60.0, 32 | padding: EdgeInsets.only(bottom: 12), 33 | child: i == cateGoryList.length 34 | ? Image.asset( 35 | 'assets/images/home/gengduofenlei.png', 36 | fit: BoxFit.contain, 37 | ) 38 | : MyCachedNetworkImage( 39 | imageurl: cateGoryList[i].icon, 40 | ), 41 | ), 42 | Text( 43 | i == cateGoryList.length ? '更多分类' : cateGoryList[i].name, 44 | style: TextStyle( 45 | color: AppColors.primaryText, 46 | fontSize: 12, 47 | fontWeight: FontWeight.normal, 48 | ), 49 | ), 50 | ], 51 | ), 52 | ), 53 | ), 54 | ); 55 | } 56 | return gridItemList; 57 | } 58 | 59 | @override 60 | Widget build(BuildContext context) { 61 | final _screenWidth = MediaQuery.of(context).size.width; 62 | return Container( 63 | height: 350, 64 | width: _screenWidth - 30, 65 | padding: EdgeInsets.all(15), 66 | margin: EdgeInsets.only(top: 10, right: 15, bottom: 10, left: 15), 67 | decoration: BoxDecoration( 68 | color: Colors.white, 69 | borderRadius: BorderRadius.circular(5), 70 | ), 71 | child: GridView.count( 72 | shrinkWrap: true, 73 | physics: NeverScrollableScrollPhysics(), 74 | mainAxisSpacing: 0.0, 75 | crossAxisSpacing: 5.0, 76 | crossAxisCount: 3, 77 | childAspectRatio: 1, 78 | children: _buildGridItem(context), 79 | ), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/pages/home/components/head_swiper.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart'; 4 | 5 | class HeadSwiper extends StatefulWidget { 6 | final List bannerList; 7 | const HeadSwiper({Key? key, required this.bannerList}) : super(key: key); 8 | 9 | @override 10 | _HeadSwiperState createState() => _HeadSwiperState(); 11 | } 12 | 13 | class _HeadSwiperState extends State { 14 | @override 15 | void initState() { 16 | super.initState(); 17 | } 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return Container( 22 | height: 135.0 + 30, 23 | margin: EdgeInsets.only(top: 10, left: 15, right: 15), 24 | color: Colors.white, 25 | child: Swiper( 26 | autoplay: true, 27 | autoplayDelay: 4000, 28 | duration: 750, 29 | itemBuilder: (BuildContext context, int index) { 30 | return Container( 31 | height: 135, 32 | child: ClipRRect( 33 | borderRadius: BorderRadius.circular(6), 34 | child: MyCachedNetworkImage( 35 | imageurl: widget.bannerList[index], 36 | ), 37 | ), 38 | ); 39 | }, 40 | itemCount: widget.bannerList.length, 41 | ), 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/pages/home/store/home_page_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:pull_to_refresh/pull_to_refresh.dart'; 3 | import 'package:AiRi/model/goods.dart'; 4 | import 'package:AiRi/model/home.dart'; 5 | import 'package:AiRi/services/services.dart'; 6 | 7 | class HomePageProvider with ChangeNotifier { 8 | RefreshController refreshController = 9 | RefreshController(initialRefresh: false); 10 | bool loading = true; 11 | List banerList = []; 12 | List cateGoryList = []; 13 | List brandList = []; 14 | List hotList = []; 15 | 16 | HomePageProvider() { 17 | /// 首页数据加载 18 | initData(); 19 | } 20 | Future initData({bool refresh = false}) async { 21 | HomeModel res = await HomeAPI.getHomeData(); 22 | 23 | /// 初次加载 24 | banerList = res.banerList; 25 | cateGoryList = res.cateGoryList; 26 | brandList = res.brandList; 27 | hotList = res.hotList; 28 | loading = false; 29 | 30 | /// 下拉刷新 31 | if (refresh) { 32 | banerList = res.banerList; 33 | cateGoryList = res.cateGoryList; 34 | brandList = res.brandList; 35 | hotList = res.hotList; 36 | loading = false; 37 | refreshController.refreshCompleted(); 38 | } 39 | notifyListeners(); 40 | } 41 | 42 | /// 上拉加载 43 | Future loadData({bool refresh = false}) async { 44 | HomeModel res = await HomeAPI.getHomeData(); 45 | hotList += res.hotList; 46 | loading = false; 47 | if (hotList.length < 20) { 48 | refreshController.loadComplete(); 49 | } else { 50 | refreshController.loadNoData(); 51 | } 52 | notifyListeners(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/pages/logup/logup_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class LogupPage extends StatelessWidget { 4 | const LogupPage({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | child: Center( 10 | child: Text('注册页面'), 11 | ), 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/pages/main/components/preload_images.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:transparent_image/transparent_image.dart'; 3 | 4 | /* 预加载图片*/ 5 | class PreloadImages extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | return IndexedStack( 9 | children: [ 10 | Image.memory(kTransparentImage), 11 | Image.asset('assets/images/tabbar/zhuye_off.png'), 12 | Image.asset('assets/images/tabbar/fenlei_ON.png'), 13 | Image.asset('assets/images/tabbar/diangdan_ON.png'), 14 | Image.asset('assets/images/tabbar/guanli_ON.png'), 15 | ], 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/pages/main/main_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/pages/main/components/my_bottom_navigation_bar.dart'; 2 | import 'package:AiRi/pages/manage/manage_page.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 5 | import 'package:provider/provider.dart'; 6 | import 'package:AiRi/pages/category/category_page.dart'; 7 | import 'package:AiRi/pages/order/order_page.dart'; 8 | import 'package:AiRi/utils/my_navigator.dart'; 9 | import '../home/home_page.dart'; 10 | import 'store/main_provider.dart'; 11 | 12 | class MainPage extends StatefulWidget { 13 | @override 14 | _MainPageState createState() => _MainPageState(); 15 | } 16 | 17 | class _MainPageState extends State with AutomaticKeepAliveClientMixin { 18 | @override 19 | void initState() { 20 | super.initState(); 21 | hideScreen(); 22 | } 23 | 24 | ///hide your splash screen 25 | Future hideScreen() async { 26 | Future.delayed(Duration(milliseconds: 750), () {}); 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | super.build(context); 32 | final mainState = Provider.of(context, listen: false); 33 | // 保存 ctx 34 | MyNavigator.ctx = context; 35 | 36 | /// 根据iphone X 高度适配,高度去掉 顶部、底部 37 | return ScreenUtilInit( 38 | designSize: Size(375, 812 - 44 - 34), 39 | builder: () => Scaffold( 40 | backgroundColor: Color(0xfffefefe), 41 | bottomNavigationBar: MyBottomNavigationBar(onTap: (index) { 42 | mainState.tabBarPageController.jumpToPage(index); 43 | setState(() { 44 | mainState.setTabBarSelectedIndex = index; 45 | }); 46 | }), 47 | body: PageView( 48 | controller: mainState.tabBarPageController, 49 | children: [HomePage(), CategoryPage(), OrderPage(), ManagePage()], 50 | physics: NeverScrollableScrollPhysics(), 51 | ), 52 | ), 53 | ); 54 | } 55 | 56 | @override 57 | bool get wantKeepAlive => true; 58 | } 59 | -------------------------------------------------------------------------------- /lib/pages/main/store/main_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const URL = "app/conf"; 4 | 5 | class MainProvider with ChangeNotifier { 6 | // PageController 7 | final PageController tabBarPageController = PageController( 8 | initialPage: 0, 9 | ); 10 | 11 | // tabBar选中索引 12 | int _tabBarSelectedIndex = 0; 13 | int get getTabBarSelectedIndex => _tabBarSelectedIndex; 14 | set setTabBarSelectedIndex(int value) { 15 | tabBarPageController.animateToPage(value, 16 | duration: Duration(milliseconds: 300), curve: Curves.easeInOut); 17 | _tabBarSelectedIndex = value; 18 | notifyListeners(); 19 | } 20 | 21 | int _messageCount = 0; 22 | 23 | // 处理后显示的消息 24 | String get getMessageCount => 25 | _messageCount < 100 ? _messageCount.toString() : "99+"; 26 | // 是否有消息 27 | bool get isMessageCount => _messageCount > 0; 28 | } 29 | -------------------------------------------------------------------------------- /lib/pages/manage/store/manage_page_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:pull_to_refresh/pull_to_refresh.dart'; 3 | import 'package:AiRi/model/goods.dart'; 4 | import 'package:AiRi/model/home.dart'; 5 | import 'package:AiRi/services/services.dart'; 6 | 7 | class ManagePageProvider with ChangeNotifier { 8 | bool loading = true; 9 | List hotList = []; 10 | RefreshController refreshController = 11 | RefreshController(initialRefresh: false); 12 | 13 | ManagePageProvider() { 14 | /// 首页数据加载 15 | initData(); 16 | } 17 | Future initData({bool refresh = false}) async { 18 | HomeModel res = await HomeAPI.getHomeData(); 19 | hotList = res.hotList; 20 | loading = false; 21 | 22 | /// 下拉刷新 23 | if (refresh) { 24 | hotList = res.hotList; 25 | loading = false; 26 | refreshController.refreshCompleted(); 27 | } 28 | notifyListeners(); 29 | } 30 | 31 | /// 上拉加载 32 | Future loadData({bool refresh = false}) async { 33 | HomeModel res = await HomeAPI.getHomeData(); 34 | hotList += res.hotList; 35 | loading = false; 36 | if (hotList.length < 20) { 37 | refreshController.loadComplete(); 38 | } else { 39 | refreshController.loadNoData(); 40 | } 41 | notifyListeners(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/pages/order/order_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:AiRi/styles/colors.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:provider/provider.dart'; 5 | import 'package:AiRi/pages/main/store/main_provider.dart'; 6 | import 'package:AiRi/pages/order/components/order_item.dart'; 7 | 8 | class OrderPage extends StatefulWidget { 9 | OrderPage({Key? key}) : super(key: key); 10 | 11 | @override 12 | _OrderPageState createState() => _OrderPageState(); 13 | } 14 | 15 | class _OrderPageState extends State with SingleTickerProviderStateMixin { 16 | late TabController _tabController; 17 | List tabs = ["全部", "待支付", "待接单", "待发货", "待收货", "已完成"]; 18 | 19 | @override 20 | void initState() { 21 | // 创建Controller 22 | _tabController = TabController(length: tabs.length, vsync: this); 23 | super.initState(); 24 | } 25 | 26 | @override 27 | void dispose() { 28 | _tabController.dispose(); 29 | super.dispose(); 30 | } 31 | 32 | @override 33 | Widget build(BuildContext context) { 34 | return BaseScaffold( 35 | leadType: AppBarBackType.None, 36 | actions: [AppBarShopCartIconButton()], 37 | title: '订单', 38 | body: OrderPageContainer(tabController: _tabController, tabs: tabs), 39 | ); 40 | } 41 | } 42 | 43 | class OrderPageContainer extends StatelessWidget { 44 | const OrderPageContainer({ 45 | Key? key, 46 | required TabController tabController, 47 | required this.tabs, 48 | }) : _tabController = tabController, 49 | super(key: key); 50 | 51 | final TabController _tabController; 52 | final List tabs; 53 | 54 | @override 55 | Widget build(BuildContext context) { 56 | List orderList = [1, 1, 1]; 57 | final mainProvder = Provider.of(context, listen: false); 58 | 59 | return Column( 60 | children: [ 61 | _buildTab(), 62 | Expanded( 63 | child: Container( 64 | color: Color(0xFFF7F7F7), 65 | child: TabBarView( 66 | controller: _tabController, 67 | children: tabs.map((_) { 68 | return orderList.length == 0 69 | ? Empty( 70 | img: 'assets/images/order/empty.png', 71 | tipText: '没有相关订单哦~', 72 | buttonText: '去采购', 73 | buttonTap: () => {mainProvder.setTabBarSelectedIndex = 0}, 74 | ) 75 | : ListView.builder( 76 | itemCount: orderList.length, 77 | itemBuilder: (context, index) { 78 | return OrderItem(orderItemData: orderList[index]); 79 | }); 80 | }).toList(), 81 | ), 82 | ), 83 | ) 84 | ], 85 | ); 86 | } 87 | 88 | Widget _buildTab() { 89 | return Container( 90 | height: 49, 91 | child: TabBar( 92 | controller: _tabController, 93 | // indicator: UnderlineIndicator( 94 | // strokeCap: StrokeCap.round, 95 | // borderSide: BorderSide( 96 | // color: AppColors.tabBarActive, 97 | // width: 2, 98 | // ), 99 | // insets: EdgeInsets.only(left: 20, right: 20), 100 | // ), 101 | isScrollable: true, 102 | labelColor: AppColors.tabBarActive, 103 | unselectedLabelColor: AppColors.primaryGreyText, 104 | tabs: tabs 105 | .map((e) => Container( 106 | child: Tab(text: e), 107 | )) 108 | .toList(), 109 | ), 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /lib/pages/order/store/oder_provider.dart: -------------------------------------------------------------------------------- 1 | // 订单页面proVider 2 | -------------------------------------------------------------------------------- /lib/pages/order_detail/components/address.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Address extends StatelessWidget { 4 | const Address({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | TextStyle addressText = TextStyle( 9 | color: Color(0xFF121212), 10 | fontSize: 15, 11 | fontWeight: FontWeight.w500, 12 | ); 13 | 14 | return Container( 15 | height: 90, 16 | decoration: BoxDecoration( 17 | color: Colors.white, 18 | borderRadius: BorderRadius.circular(5), 19 | ), 20 | margin: EdgeInsets.only(top: 10, bottom: 0, left: 10, right: 10), 21 | padding: EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), 22 | child: Column( 23 | children: [ 24 | Container( 25 | child: Row( 26 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 27 | children: [ 28 | Text('张三', style: addressText), 29 | Text('18888888888', style: addressText), 30 | ], 31 | ), 32 | ), 33 | Container( 34 | padding: EdgeInsets.only(top: 10), 35 | width: MediaQuery.of(context).size.width - 50, 36 | child: Text( 37 | '重庆 重庆市 渝北区 天宫街道华夏宗申店21-6号地址地址地址地址地址地址地址地址地址地址', 38 | maxLines: 2, 39 | overflow: TextOverflow.ellipsis, 40 | style: TextStyle( 41 | color: Color(0xFF4A4A4A), 42 | fontSize: 12.0, 43 | fontWeight: FontWeight.w400, 44 | ), 45 | ), 46 | ) 47 | ], 48 | ), 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/pages/order_detail/components/delivery.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Delivery extends StatelessWidget { 4 | const Delivery({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | TextStyle infoTextTip = TextStyle( 9 | color: Color(0xFF4A4A4A), 10 | fontSize: 14, 11 | fontWeight: FontWeight.w400, 12 | ); 13 | TextStyle infoText = TextStyle( 14 | color: Color(0xFF121212), 15 | fontSize: 14, 16 | fontWeight: FontWeight.w400, 17 | ); 18 | 19 | return Container( 20 | width: MediaQuery.of(context).size.width - 20, 21 | decoration: BoxDecoration( 22 | color: Colors.white, 23 | borderRadius: BorderRadius.circular(5), 24 | ), 25 | margin: EdgeInsets.only(bottom: 10, left: 10, right: 10), 26 | padding: EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), 27 | child: Column( 28 | crossAxisAlignment: CrossAxisAlignment.start, 29 | children: [ 30 | Container( 31 | height: 40, 32 | child: Align( 33 | alignment: Alignment.centerLeft, 34 | child: Text( 35 | '物流信息', 36 | style: TextStyle( 37 | color: Color(0xFF4A4A4A), 38 | fontSize: 14, 39 | fontWeight: FontWeight.w500, 40 | ), 41 | ), 42 | ), 43 | ), 44 | _buildItem( 45 | tip: '物流编号: ', 46 | content: '20200401021516851384', 47 | infoTextTip: infoTextTip, 48 | infoText: infoText, 49 | ), 50 | _buildItem( 51 | tip: '发货时间: ', 52 | content: '2020-04-01 12:30:12', 53 | infoTextTip: infoTextTip, 54 | infoText: infoText, 55 | ), 56 | ], 57 | ), 58 | ); 59 | } 60 | 61 | /// 每一项 62 | Widget _buildItem( 63 | {required String tip, required String content, required TextStyle infoTextTip, required TextStyle infoText}) { 64 | return Container( 65 | height: 40, 66 | child: Align( 67 | alignment: Alignment.centerLeft, 68 | child: RichText( 69 | text: TextSpan(text: tip, style: infoTextTip, children: [ 70 | TextSpan( 71 | text: content, 72 | style: infoText, 73 | ) 74 | ]), 75 | ), 76 | ), 77 | ); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/pages/order_detail/order_detail_page.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:AiRi/components/components.dart'; 3 | import 'package:AiRi/pages/pay/pay_page.dart'; 4 | import 'package:AiRi/styles/colors.dart'; 5 | import 'package:AiRi/utils/my_navigator.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:AiRi/pages/order_detail/components/address.dart'; 8 | import 'package:AiRi/pages/order_detail/components/delivery.dart'; 9 | import 'components/info.dart'; 10 | import 'components/item.dart'; 11 | 12 | class OrderDetailPage extends StatelessWidget { 13 | final String orderId; 14 | 15 | const OrderDetailPage({Key? key, required this.orderId}) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return BaseScaffold( 20 | actions: [ 21 | Container( 22 | padding: EdgeInsets.only(right: 10), 23 | child: GestureDetector( 24 | onTap: () => _showCancelDialog(context), 25 | child: Center( 26 | child: Text( 27 | '取消订单', 28 | style: TextStyle( 29 | color: AppColors.primaryText, 30 | fontSize: 14, 31 | fontWeight: FontWeight.w500, 32 | ), 33 | ), 34 | ), 35 | ), 36 | ) 37 | ], 38 | title: '订单详情', 39 | body: OrderDetailContainer(), 40 | ); 41 | } 42 | 43 | // 弹出对话框 44 | void _showCancelDialog(BuildContext context) { 45 | showDialog( 46 | context: context, 47 | barrierDismissible: false, 48 | builder: (_) { 49 | return CustomDialog( 50 | title: '', 51 | content: Center( 52 | child: Column( 53 | children: [ 54 | Image.asset('assets/images/order/querendingdan.png'), 55 | Container( 56 | padding: EdgeInsets.only(bottom: 0.0, top: 20), 57 | child: Text( 58 | '取消订单', 59 | style: 60 | TextStyle(color: Color(0xFF4A4A4A), fontSize: 14.0), 61 | ), 62 | ), 63 | ], 64 | ), 65 | ), 66 | confirmContent: '确定', 67 | cancelContent: '返回', 68 | isCancel: true, 69 | // confirmColor: Color(0xFFF5A623), 70 | confirmCallback: () { 71 | /// 取消订单操作 72 | }, 73 | dismissCallback: () { 74 | return; 75 | }, 76 | ); 77 | }); 78 | } 79 | } 80 | 81 | class OrderDetailContainer extends StatelessWidget { 82 | const OrderDetailContainer({Key? key}) : super(key: key); 83 | 84 | @override 85 | Widget build(BuildContext context) { 86 | return Container( 87 | color: Color(0xFFF7F7F7), 88 | child: Stack( 89 | children: [ 90 | Container( 91 | width: double.infinity, 92 | height: double.infinity, 93 | margin: EdgeInsets.only( 94 | bottom: 60 + MediaQuery.of(context).padding.bottom), 95 | child: SingleChildScrollView( 96 | physics: AlwaysScrollableScrollPhysics(), 97 | child: Column( 98 | children: [ 99 | Address(), 100 | OrderItem(), 101 | OrderDetailInfo(), 102 | Delivery(), 103 | ], 104 | ), 105 | ), 106 | ), 107 | Positioned( 108 | left: 0, 109 | right: 0, 110 | bottom: 0, 111 | child: BottomButton( 112 | text: '去支付', 113 | handleOk: () => MyNavigator.push(PayPage(orderId: "id")), 114 | ), 115 | ), 116 | ], 117 | ), 118 | ); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /lib/pages/pay/components/middle.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Middle extends StatelessWidget { 4 | const Middle({Key? key}) : super(key: key); 5 | 6 | @override 7 | Widget build(BuildContext context) { 8 | return Container( 9 | color: Colors.white, 10 | margin: EdgeInsets.symmetric(vertical: 10), 11 | padding: EdgeInsets.symmetric(horizontal: 15), 12 | child: Column( 13 | crossAxisAlignment: CrossAxisAlignment.start, 14 | mainAxisAlignment: MainAxisAlignment.center, 15 | children: [ 16 | Container( 17 | height: 32, 18 | child: Text( 19 | '支付渠道', 20 | style: TextStyle( 21 | color: Color(0xFF4A4A4A), 22 | fontSize: 14, 23 | fontWeight: FontWeight.normal, 24 | ), 25 | ), 26 | ), 27 | Divider(color: Color(0xffdfdfdf), height: 0.5), 28 | _buildItem( 29 | title: '微信支付', 30 | tip: '(已开放)', 31 | img: 'assets/images/pay/check.png', 32 | ), 33 | Divider(color: Color(0xffdfdfdf), height: 0.5), 34 | _buildItem( 35 | title: '支付宝', 36 | tip: '(未开放)', 37 | img: 'assets/images/pay/uncheck.png', 38 | ), 39 | Divider(color: Color(0xffdfdfdf), height: 0.5), 40 | _buildItem( 41 | title: '银联', 42 | tip: '(未开放)', 43 | img: 'assets/images/pay/uncheck.png', 44 | ), 45 | Divider(color: Color(0xffdfdfdf), height: 0.5), 46 | _buildItem( 47 | title: '线下转账', 48 | tip: '(需上传支付凭证)', 49 | img: 'assets/images/pay/uncheck.png', 50 | ), 51 | ], 52 | ), 53 | ); 54 | } 55 | 56 | /// 每一项 57 | Widget _buildItem({ 58 | required String title, 59 | required String tip, 60 | required String img, 61 | }) { 62 | TextStyle greyText = TextStyle( 63 | color: Color(0xFFBEBEBE), 64 | fontSize: 12, 65 | fontWeight: FontWeight.normal, 66 | ); 67 | TextStyle blackText = TextStyle( 68 | color: Color(0xFF121212), 69 | fontSize: 12, 70 | fontWeight: FontWeight.w500, 71 | ); 72 | return Container( 73 | height: 50, 74 | child: Row( 75 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 76 | children: [ 77 | Column( 78 | mainAxisAlignment: MainAxisAlignment.center, 79 | crossAxisAlignment: CrossAxisAlignment.start, 80 | children: [ 81 | Text(title, style: title == '微信支付' ? blackText : greyText), 82 | Text(tip, style: greyText), 83 | ], 84 | ), 85 | Image.asset(img, width: 20, height: 20) 86 | ], 87 | ), 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/pages/pay/components/top.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/styles/colors.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class Top extends StatelessWidget { 5 | const Top({Key? key}) : super(key: key); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return Container( 10 | height: 224, 11 | color: Colors.white, 12 | child: Column( 13 | crossAxisAlignment: CrossAxisAlignment.start, 14 | children: [ 15 | Container( 16 | margin: EdgeInsets.only(top: 20, bottom: 10), 17 | child: Center( 18 | child: Text( 19 | '订单金额', 20 | style: TextStyle( 21 | color: Color(0xFF17191A), 22 | fontSize: 18, 23 | fontWeight: FontWeight.normal, 24 | ), 25 | ), 26 | ), 27 | ), 28 | Container( 29 | margin: EdgeInsets.only(top: 0, bottom: 30), 30 | child: Center( 31 | child: Text( 32 | '¥15900', 33 | style: TextStyle( 34 | color: AppColors.priceColor, 35 | fontSize: 27, 36 | fontWeight: FontWeight.w600, 37 | ), 38 | ), 39 | ), 40 | ), 41 | Container( 42 | padding: EdgeInsets.only(left: 15), 43 | child: Text( 44 | '支付方式', 45 | style: TextStyle( 46 | color: Color(0xFF4A4A4A), 47 | fontSize: 14, 48 | fontWeight: FontWeight.normal, 49 | ), 50 | ), 51 | ), 52 | Container( 53 | margin: EdgeInsets.only(left: 15, top: 15), 54 | width: 100, 55 | height: 50, 56 | decoration: BoxDecoration( 57 | color: Color(0xFFFEF6F4), 58 | borderRadius: BorderRadius.circular(6), 59 | border: Border.all(color: AppColors.priceColor), 60 | ), 61 | child: Center( 62 | child: Text( 63 | '全款支付', 64 | style: TextStyle( 65 | color: AppColors.priceColor, 66 | fontSize: 14, 67 | fontWeight: FontWeight.w500, 68 | ), 69 | ), 70 | ), 71 | ), 72 | ], 73 | ), 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/pages/search/search_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:AiRi/utils/my_navigator.dart'; 3 | import 'package:AiRi/utils/utils.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:provider/provider.dart'; 6 | import 'package:pull_to_refresh/pull_to_refresh.dart'; 7 | import 'package:AiRi/model/goods.dart'; 8 | import 'package:AiRi/pages/search/store/search_provider.dart'; 9 | import 'package:AiRi/pages/shopping_cart/cart_page.dart'; 10 | import 'package:AiRi/styles/colors.dart'; 11 | 12 | class SearchPage extends StatelessWidget { 13 | final String title; 14 | final String keyword; 15 | const SearchPage({Key? key, required this.title, required this.keyword}) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return ChangeNotifierProvider( 20 | create: (_) => SearchPageProvider(), 21 | child: BaseScaffold( 22 | leadType: AppBarBackType.Back, 23 | actions: [ 24 | IconButton( 25 | icon: Image.asset( 26 | 'assets/images/home/gouwuche.png', 27 | width: duSetWidth(25), 28 | height: duSetHeight(23.5), 29 | ), 30 | onPressed: () => MyNavigator.push(CartPage()), 31 | ), 32 | ], 33 | title: title, 34 | body: SerachContainer(keyword: keyword), 35 | ), 36 | ); 37 | } 38 | } 39 | 40 | class SerachContainer extends StatefulWidget { 41 | final String keyword; 42 | const SerachContainer({Key? key, required this.keyword}) : super(key: key); 43 | 44 | @override 45 | _SerachContainerState createState() => _SerachContainerState(); 46 | } 47 | 48 | class _SerachContainerState extends State { 49 | String keyWord = ''; 50 | @override 51 | void initState() { 52 | keyWord = widget.keyword; 53 | super.initState(); 54 | } 55 | 56 | /// 下方搜索结果列表 57 | Widget _buildresultList(List resultList) { 58 | return GoodList(goodsList: resultList); 59 | } 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | final state = Provider.of(context); 64 | return Container( 65 | color: AppColors.primaryBackground, 66 | child: Column( 67 | children: [ 68 | SearchBar( 69 | keyword: keyWord, 70 | myOntap: (value) { 71 | setState(() { 72 | keyWord = value; // 重新设置当前搜索框的值 73 | }); 74 | state.searchData(keyword: value); // 跳转到Provider进行搜索请求 75 | }, 76 | ), 77 | Expanded( 78 | child: state.loading 79 | ? MyLoadingWidget() 80 | : Container( 81 | decoration: BoxDecoration( 82 | color: Colors.white, 83 | borderRadius: BorderRadius.circular(5), 84 | ), 85 | padding: EdgeInsets.all(15), 86 | margin: EdgeInsets.all(15), 87 | child: SmartRefresher( 88 | enablePullUp: true, 89 | controller: state.refreshController, 90 | onRefresh: () => state.searchData(refresh: true, keyword: ''), 91 | onLoading: () => state.loadData, 92 | header: WaterDropHeader(), 93 | footer: MyCustomFooter(), 94 | child: _buildresultList(state.result), 95 | ), 96 | ), 97 | ), 98 | ], 99 | ), 100 | ); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /lib/pages/search/store/search_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:pull_to_refresh/pull_to_refresh.dart'; 3 | import 'package:AiRi/model/goods.dart'; 4 | import 'package:AiRi/model/search.dart'; 5 | import 'package:AiRi/services/search.dart'; 6 | 7 | class SearchPageProvider with ChangeNotifier { 8 | RefreshController refreshController = RefreshController(initialRefresh: false); 9 | List result = []; 10 | bool loading = true; 11 | 12 | SearchPageProvider() { 13 | /// 数据加载 14 | searchData(keyword: ''); 15 | notifyListeners(); 16 | } 17 | Future searchData({bool refresh = false, required String keyword}) async { 18 | // print(keyword); 19 | loading = true; 20 | 21 | /// 这里keyword有存在空的情况,后期需要判断 22 | SearchModel res = await SearchAPI.searchData(keyword: keyword); 23 | 24 | /// 初次加载 25 | result = res.result; 26 | loading = false; 27 | 28 | /// 下拉刷新 29 | if (refresh) { 30 | refreshController.refreshCompleted(); 31 | } 32 | notifyListeners(); 33 | } 34 | 35 | /// 上拉加载 36 | Future loadData({bool refresh = false, required String keyword}) async { 37 | SearchModel res = await SearchAPI.searchData(keyword: keyword); 38 | result += res.result; 39 | if (result.length < 20) { 40 | refreshController.loadComplete(); 41 | } else { 42 | refreshController.loadNoData(); 43 | } 44 | notifyListeners(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/pages/shopping_cart/cart_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/components/components.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:tuple/tuple.dart'; 5 | import 'package:AiRi/pages/shopping_cart/store/shopping_cart_provider.dart'; 6 | import 'package:AiRi/styles/colors.dart'; 7 | import 'package:AiRi/utils/my_navigator.dart'; 8 | import 'components/cart_bottom.dart'; 9 | import 'components/cart_item.dart'; 10 | 11 | class CartPage extends StatefulWidget { 12 | @override 13 | _CartPageState createState() => _CartPageState(); 14 | } 15 | 16 | class _CartPageState extends State { 17 | final _provider = ShopingCartProvider(); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return ChangeNotifierProvider( 22 | create: (_) => _provider, 23 | child: BaseScaffold( 24 | title: '购物车', 25 | actions: [ 26 | Selector>( 27 | builder: (_, tuple, __) { 28 | return IconButton( 29 | icon: Text( 30 | tuple.item2 ? '完成' : '编辑', 31 | style: TextStyle(color: AppColors.primaryGreyText, fontSize: 14, fontWeight: FontWeight.w400), 32 | ), 33 | onPressed: () => tuple.item1(), 34 | ); 35 | }, 36 | selector: (_, provider) => Tuple2(provider.changeEditMode, provider.isEditMode), 37 | ), 38 | ], 39 | body: CartContainer(), 40 | ), 41 | ); 42 | } 43 | } 44 | 45 | class CartContainer extends StatelessWidget { 46 | const CartContainer({Key? key}) : super(key: key); 47 | Widget _listItemBuilder(BuildContext context, int index) { 48 | // 取出数据 49 | final brandList = Provider.of(context).getBrandList; 50 | return Container( 51 | color: Color(0xFFF5F7F7), 52 | padding: EdgeInsets.all(10.0), 53 | child: CartItem(brandData: brandList[index], brandIndex: index), 54 | ); 55 | } 56 | 57 | @override 58 | Widget build(BuildContext context) { 59 | // 取出数据 60 | final brandList = Provider.of(context).getBrandList; 61 | return Stack( 62 | children: [ 63 | Container( 64 | padding: EdgeInsets.only(bottom: 80.0), 65 | color: Color(0xFFF5F7F7), 66 | child: brandList.length == 0 67 | ? Empty( 68 | img: 'assets/images/shopping_cart/empty.png', 69 | tipText: '购物车为空,快去采购吧~', 70 | buttonText: '去采购', 71 | buttonTap: () => MyNavigator.popToHome(), 72 | ) 73 | : ListView.builder( 74 | itemCount: brandList.length, 75 | itemBuilder: _listItemBuilder, 76 | ), 77 | ), 78 | CartBottom(), 79 | ], 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/pages/shopping_cart/store/shopping_cart_global_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class ShopingCartGlobalProvider with ChangeNotifier { 4 | int get goodsCount { 5 | return 5; 6 | } 7 | 8 | String get goodsCountString { 9 | return goodsCount > 99 ? "99+" : goodsCount.toString(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/pages/supplier/components/search_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class SearchBar extends StatefulWidget { 4 | final String keyword; 5 | final Function myOntap; 6 | const SearchBar({Key? key, required this.myOntap, this.keyword = ''}) : super(key: key); 7 | 8 | @override 9 | _SearchBarState createState() => _SearchBarState(); 10 | } 11 | 12 | class _SearchBarState extends State { 13 | final _textEditController = TextEditingController(); 14 | @override 15 | Widget build(BuildContext context) { 16 | // 从其他页面传入的搜索关键词,默认为'' 17 | _textEditController.text = widget.keyword; 18 | return Container( 19 | height: 49, 20 | padding: EdgeInsets.only(top: 7, right: 15, bottom: 7, left: 15), 21 | child: Row( 22 | children: [ 23 | Expanded( 24 | child: Opacity( 25 | opacity: 0.1, 26 | child: Container( 27 | decoration: BoxDecoration( 28 | color: Color(0xFFF5F7F7), 29 | borderRadius: BorderRadius.circular(49 * 0.5), 30 | ), 31 | child: Container( 32 | child: TextField( 33 | controller: _textEditController, 34 | cursorColor: Colors.black, 35 | style: TextStyle( 36 | color: Colors.black, 37 | ), 38 | decoration: InputDecoration( 39 | prefixIcon: Image.asset( 40 | 'assets/images/home/sousuo.png', 41 | width: 15, 42 | height: 15, 43 | ), 44 | isDense: true, 45 | hintText: "最高可降8000", 46 | hintStyle: TextStyle( 47 | color: Colors.black, 48 | ), 49 | border: InputBorder.none, 50 | ), 51 | ), 52 | ), 53 | ), 54 | ), 55 | ), 56 | GestureDetector( 57 | /// 将输入值回调传至点击函数 58 | onTap: () => widget.myOntap(_textEditController.text), 59 | child: Container( 60 | padding: EdgeInsets.only(left: 12), 61 | child: Text( 62 | '搜索', 63 | style: TextStyle( 64 | color: Colors.white, 65 | fontSize: 16, 66 | fontWeight: FontWeight.normal, 67 | ), 68 | ), 69 | ), 70 | ) 71 | ], 72 | ), 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/pages/supplier/store/supplier_provider.dart: -------------------------------------------------------------------------------- 1 | /// 供应商provider 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:pull_to_refresh/pull_to_refresh.dart'; 4 | import 'package:AiRi/model/goods.dart'; 5 | import 'package:AiRi/model/supplier.dart'; 6 | import 'package:AiRi/services/services.dart'; 7 | 8 | class SupplierPageProvider with ChangeNotifier { 9 | RefreshController refreshController = 10 | RefreshController(initialRefresh: false); 11 | bool loading = true; 12 | String supplierName = ''; 13 | String contact = ''; 14 | String phoneNum = ''; 15 | String workTime = ''; 16 | 17 | String supplierImgUrl = ""; 18 | String introDuceText = ''; 19 | 20 | List supplierList = []; 21 | 22 | SupplierPageProvider() { 23 | /// 数据加载 24 | initData(); 25 | } 26 | 27 | Future initData({bool refresh = false}) async { 28 | SupplierModel res = await SupplierAPI.getData(); 29 | supplierName = res.supplierName; 30 | contact = res.contact; 31 | phoneNum = res.phoneNum; 32 | workTime = res.workTime; 33 | supplierList = res.supplierList; 34 | supplierImgUrl = res.supplierImgUrl; 35 | introDuceText = res.introDuceText; 36 | loading = false; 37 | notifyListeners(); 38 | } 39 | 40 | /// 上拉加载 41 | Future loadData({bool refresh = false}) async { 42 | SupplierModel res = await SupplierAPI.getData(); 43 | supplierList += res.supplierList; 44 | loading = false; 45 | if (supplierList.length < 20) { 46 | refreshController.loadComplete(); 47 | } else { 48 | refreshController.loadNoData(); 49 | } 50 | notifyListeners(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/services/category.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/model/category.dart'; 2 | import 'package:AiRi/utils/request.dart'; 3 | 4 | /// 分类页面 5 | class CateGoryAPI { 6 | /// 获取分类数据 7 | static Future getData() async { 8 | var response = await RequestUtil().get('/category'); 9 | return CateGoryModel.fromJson(response); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/services/detail.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/model/detail.dart'; 2 | import 'package:AiRi/utils/request.dart'; 3 | 4 | /// 详情页面 5 | class DetailAPI { 6 | /// 获取详情数据 7 | static Future getData() async { 8 | var response = await RequestUtil().get('/detail'); 9 | return DetailModel.fromJson(response); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/services/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/model/home.dart'; 2 | import 'package:AiRi/utils/request.dart'; 3 | 4 | /// 首页 5 | class HomeAPI { 6 | /// 获取首页数据 7 | static Future getHomeData() async { 8 | var response = await RequestUtil().get('/index'); 9 | return HomeModel.fromJson(response); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/services/search.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/model/search.dart'; 2 | import 'package:AiRi/utils/request.dart'; 3 | 4 | /// 搜索页面 5 | class SearchAPI { 6 | /// 搜索数据 7 | static Future searchData({required String keyword}) async { 8 | var response = await RequestUtil().get( 9 | '/search', 10 | params: {"keyword": keyword}, 11 | ); 12 | return SearchModel.fromJson(response); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/services/services.dart: -------------------------------------------------------------------------------- 1 | library apis; 2 | 3 | export 'home.dart'; 4 | export 'category.dart'; 5 | export 'search.dart'; 6 | export 'detail.dart'; 7 | export 'supplier.dart'; 8 | -------------------------------------------------------------------------------- /lib/services/supplier.dart: -------------------------------------------------------------------------------- 1 | import 'package:AiRi/model/supplier.dart'; 2 | import 'package:AiRi/utils/request.dart'; 3 | 4 | /// 详情页面 5 | class SupplierAPI { 6 | /// 获取供应商数据 7 | static Future getData() async { 8 | var response = await RequestUtil().get('/supplier'); 9 | return SupplierModel.fromJson(response); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lib/styles/colors.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class AppColors { 5 | /// 主背景 6 | static const Color primaryBackground = Color(0xFFF4F6FA); 7 | 8 | /// 主文本 9 | static const Color primaryText = Color(0xFF2D3142); 10 | 11 | /// 主文本灰色 12 | static const Color primaryGreyText = Color(0xFF9B9B9B); 13 | 14 | /// 主文本灰色 15 | static const Color primaryGreyText1 = Color(0xFFE0DDF5); 16 | 17 | /// tabBar 默认颜色 灰色 18 | static const Color tabBarElement = Color(0xFFE0DDF5); 19 | 20 | /// tabBar 激活颜色 21 | static const Color tabBarActive = Color(0xFF8B63E6); 22 | 23 | /// 分类tab渐变色 24 | static Color buttonLine1 = Color(0xFFBA68C8); 25 | 26 | /// 分类tab渐变色 27 | static const Color buttonLine2 = Color(0xFF7265E3); 28 | 29 | /// 主题色 30 | static const Color primaryColor = Color(0xFF8B63E6); 31 | 32 | static const Color primaryColorAccent = Color(0xFFE1DDF5); 33 | 34 | /// 价格颜色 35 | static const Color priceColor = Color(0xFFF77777); 36 | 37 | /// 提货方式-自提 38 | static const Color deliveryColor1 = Color(0xFFFE9C5E); 39 | 40 | /// 提货方式-物流 41 | static const Color deliveryColor2 = Color(0xFF6155CC); 42 | 43 | /// 提货方式-自提 44 | static const Color deliveryBackColor1 = Color.fromRGBO(254, 156, 94, 0.15); 45 | 46 | /// 提货方式-物流 47 | static const Color deliveryBackColor2 = Color.fromRGBO(97, 85, 204, 0.15); 48 | 49 | /// 加入购物车 50 | static const Color addToCart2 = Color(0xFFFE9C5E); 51 | static const Color addToCart1 = Color(0xFFfdcb6e); 52 | 53 | /// 立即采购 54 | static const Color buyNow1 = Color(0xFFF77777); 55 | static const Color buyNow2 = Color(0xFFd63031); 56 | 57 | /// splashColor 58 | static const Color splashColor = Color(0xFFE1DDF5); 59 | 60 | /// 店铺背景渐变 61 | static const Color supplierColor1 = Color(0xFF8B63E6); 62 | static const Color supplierColor2 = Color(0xFF7265E3); 63 | } 64 | -------------------------------------------------------------------------------- /lib/styles/iconfont.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Iconfont { 4 | // iconName: redpacket_fil 5 | static const redpacket_fil = IconData( 6 | 0xe7d3, 7 | fontFamily: 'Iconfont', 8 | matchTextDirection: true, 9 | ); 10 | 11 | // iconName: ticket_fill 12 | static const ticket_fill = IconData( 13 | 0xe800, 14 | fontFamily: 'Iconfont', 15 | matchTextDirection: true, 16 | ); 17 | 18 | // iconName: round_like_fill 19 | static const round_like_fill = IconData( 20 | 0xe80a, 21 | fontFamily: 'Iconfont', 22 | matchTextDirection: true, 23 | ); 24 | 25 | // iconName: card_fill 26 | static const card_fill = IconData( 27 | 0xe81f, 28 | fontFamily: 'Iconfont', 29 | matchTextDirection: true, 30 | ); 31 | 32 | // iconName: settings 33 | static const settings = IconData( 34 | 0xe68a, 35 | fontFamily: 'Iconfont', 36 | matchTextDirection: true, 37 | ); 38 | 39 | // iconName: notice 40 | static const notice = IconData( 41 | 0xe70a, 42 | fontFamily: 'Iconfont', 43 | matchTextDirection: true, 44 | ); 45 | /////// 46 | static const discover = IconData( 47 | 0xe67e, 48 | fontFamily: 'Iconfont', 49 | matchTextDirection: true, 50 | ); 51 | static const question = IconData( 52 | 0xe691, 53 | fontFamily: 'Iconfont', 54 | matchTextDirection: true, 55 | ); 56 | static const game = IconData( 57 | 0xe6df, 58 | fontFamily: 'Iconfont', 59 | matchTextDirection: true, 60 | ); 61 | static const tian = IconData( 62 | 0xe748, 63 | fontFamily: 'Iconfont', 64 | matchTextDirection: true, 65 | ); 66 | static const magic = IconData( 67 | 0xe74c, 68 | fontFamily: 'Iconfont', 69 | matchTextDirection: true, 70 | ); 71 | static const haodian = IconData( 72 | 0xe76d, 73 | fontFamily: 'Iconfont', 74 | matchTextDirection: true, 75 | ); 76 | static const qi = IconData( 77 | 0xe76f, 78 | fontFamily: 'Iconfont', 79 | matchTextDirection: true, 80 | ); 81 | static const shuang11 = IconData( 82 | 0xe782, 83 | fontFamily: 'Iconfont', 84 | matchTextDirection: true, 85 | ); 86 | static const shop_light = IconData( 87 | 0xe7b8, 88 | fontFamily: 'Iconfont', 89 | matchTextDirection: true, 90 | ); 91 | static const we_fill_light = IconData( 92 | 0xe7d8, 93 | fontFamily: 'Iconfont', 94 | matchTextDirection: true, 95 | ); 96 | static const news_light = IconData( 97 | 0xe7e6, 98 | fontFamily: 'Iconfont', 99 | matchTextDirection: true, 100 | ); 101 | static const sports = IconData( 102 | 0xe7f1, 103 | fontFamily: 'Iconfont', 104 | matchTextDirection: true, 105 | ); 106 | } 107 | -------------------------------------------------------------------------------- /lib/styles/styles.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * 此文件夹为公共样式 3 | */ 4 | 5 | library styles; 6 | 7 | export 'colors.dart'; 8 | export 'styles.dart'; 9 | export 'iconfont.dart'; 10 | -------------------------------------------------------------------------------- /lib/utils/key_value_store.dart: -------------------------------------------------------------------------------- 1 | // Get a location using getDatabasesPath 2 | import 'dart:convert'; 3 | import 'package:convert/convert.dart'; 4 | import 'package:crypto/crypto.dart' as crypto; 5 | import 'package:path/path.dart'; 6 | import 'package:sqflite/sqflite.dart'; 7 | 8 | const _dbName = "cache.db"; 9 | 10 | class KeyValueStore { 11 | /// 添加 12 | static put(String name, Object object) async { 13 | final database = await _getDB(); 14 | final data = jsonEncode(object); 15 | database.transaction((txn) async { 16 | txn.rawInsert('INSERT OR REPLACE INTO "cache" VALUES (?, ?, ?,?);', [ 17 | generateMd5(name), 18 | DateTime.now().millisecondsSinceEpoch, 19 | data, 20 | generateMd5(data) 21 | ]); 22 | }); 23 | } 24 | 25 | /// 获取 26 | static Future get(String name) async { 27 | final database = await _getDB(); 28 | List list = await database 29 | .rawQuery('SELECT * FROM "cache" WHERE name=?', [generateMd5(name)]); 30 | if (list.isEmpty) { 31 | // return KeyValueStoreItem(); 32 | throw Exception("没有查询到缓存数据"); 33 | } 34 | return KeyValueStoreItem.fromJson(Map.from(list.first)); 35 | } 36 | 37 | /// getDB 38 | static Future _getDB() async { 39 | var databasesPath = await getDatabasesPath(); 40 | String path = join(databasesPath, _dbName); 41 | return openDatabase(path, version: 1, 42 | onCreate: (Database db, int version) async { 43 | print("----初始化数据表:" + databasesPath); 44 | await db.execute("""CREATE TABLE IF NOT EXISTS "cache" ( 45 | "name" char NOT NULL, 46 | "create_time" integer NOT NULL, 47 | "content" text, 48 | "content_hash" char, 49 | PRIMARY KEY ("name")); 50 | """); 51 | }); 52 | } 53 | } 54 | 55 | class KeyValueStoreItem { 56 | final String name; 57 | final int createTime; 58 | final dynamic content; 59 | final String contentHash; 60 | 61 | bool get isEmpty { 62 | return this.createTime < 1; 63 | } 64 | 65 | KeyValueStoreItem( 66 | {required this.name, required this.createTime, this.content, required this.contentHash}); 67 | 68 | factory KeyValueStoreItem.fromJson(Map json) { 69 | return KeyValueStoreItem( 70 | name: json["name"].toString(), 71 | createTime: json["create_time"], 72 | content: jsonDecode(json["content"]), 73 | contentHash: json["content_hash"]); 74 | } 75 | } 76 | 77 | ///Generate MD5 hash 78 | String generateMd5(String data) { 79 | var content = Utf8Encoder().convert(data); 80 | var md5 = crypto.md5; 81 | var digest = md5.convert(content); 82 | return hex.encode(digest.bytes); 83 | } 84 | -------------------------------------------------------------------------------- /lib/utils/my_navigator.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:provider/provider.dart'; 4 | import 'package:AiRi/pages/main/store/main_provider.dart'; 5 | 6 | class MyNavigator { 7 | // 设置一次 context 方便后面 8 | static late BuildContext ctx; 9 | 10 | // push 新页面 11 | static Future? push(Widget page, {BuildContext? context}) { 12 | final _ctx = context ?? ctx; 13 | FocusScope.of(_ctx).requestFocus(FocusNode()); 14 | Navigator.of(_ctx).push( 15 | MaterialPageRoute(builder: (_ctx) => page), 16 | ); 17 | } 18 | 19 | // pop 返回 20 | static pop({BuildContext? context, T? data}) { 21 | final _ctx = context ?? ctx; 22 | return Navigator.pop(_ctx, data); 23 | } 24 | 25 | /// 返回根页面 26 | static void popToRoot({BuildContext? context}) { 27 | final _ctx = context ?? ctx; 28 | Navigator.popUntil(_ctx, (predicate) { 29 | return predicate.isFirst; 30 | }); 31 | } 32 | 33 | /// 返回首页 34 | static void popToHome({BuildContext? context}) { 35 | final _ctx = context ?? ctx; 36 | final mainProvder = Provider.of(_ctx, listen: false); 37 | mainProvder.setTabBarSelectedIndex = 0; 38 | Navigator.popUntil(_ctx, (predicate) { 39 | return predicate.isFirst; 40 | }); 41 | } 42 | 43 | /// 返回并删除页面 44 | static void pushAndRemove(Widget page, {int removeCount = 1, BuildContext? context}) { 45 | var index = 0; 46 | final _ctx = context ?? ctx; 47 | Navigator.of(_ctx).pushAndRemoveUntil( 48 | MaterialPageRoute(builder: (context) => page), 49 | (route) { 50 | index++; 51 | return index > removeCount ? true : false; 52 | }, 53 | ); 54 | } 55 | 56 | // iOS 从底部向上出来的页面 57 | static present(Widget page, {BuildContext? context}) { 58 | final _ctx = context ?? ctx; 59 | Navigator.of(_ctx).push(MaterialPageRoute(fullscreenDialog: true, builder: (context) => page)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/utils/screen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 | /* 3 | ScreenUtil.pixelRatio //设备的像素密度 4 | ScreenUtil.screenWidth //设备宽度 5 | ScreenUtil.screenHeight //设备高度 6 | ScreenUtil.bottomBarHeight //底部安全区距离,适用于全面屏下面有按键的 7 | ScreenUtil.statusBarHeight //状态栏高度 刘海屏会更高 单位px 8 | ScreenUtil.textScaleFactor //系统字体缩放比例 9 | 10 | ScreenUtil().scaleWidth // 实际宽度的dp与设计稿px的比例 11 | ScreenUtil().scaleHeight // 实际高度的dp与设计稿px的比例 12 | */ 13 | 14 | /// 设置宽度 15 | double duSetWidth(double width) { 16 | return ScreenUtil().setWidth(width); 17 | } 18 | 19 | /// 设置宽度 20 | double duSetHeight(double height) { 21 | return ScreenUtil().setHeight(height); 22 | } 23 | 24 | /// 设置字体尺寸 25 | double duSetFontSize(double fontSize) { 26 | return ScreenUtil().setSp(fontSize); 27 | } 28 | -------------------------------------------------------------------------------- /lib/utils/utils.dart: -------------------------------------------------------------------------------- 1 | library utils; 2 | 3 | export 'screen.dart'; 4 | export 'key_value_store.dart'; 5 | export 'request.dart'; 6 | export 'screen.dart'; 7 | -------------------------------------------------------------------------------- /screenshot/Screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_1.png -------------------------------------------------------------------------------- /screenshot/Screenshot_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_10.png -------------------------------------------------------------------------------- /screenshot/Screenshot_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_11.png -------------------------------------------------------------------------------- /screenshot/Screenshot_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_12.png -------------------------------------------------------------------------------- /screenshot/Screenshot_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_13.png -------------------------------------------------------------------------------- /screenshot/Screenshot_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_14.png -------------------------------------------------------------------------------- /screenshot/Screenshot_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_15.png -------------------------------------------------------------------------------- /screenshot/Screenshot_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_16.png -------------------------------------------------------------------------------- /screenshot/Screenshot_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_17.png -------------------------------------------------------------------------------- /screenshot/Screenshot_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_18.png -------------------------------------------------------------------------------- /screenshot/Screenshot_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_19.png -------------------------------------------------------------------------------- /screenshot/Screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_2.png -------------------------------------------------------------------------------- /screenshot/Screenshot_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_20.png -------------------------------------------------------------------------------- /screenshot/Screenshot_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_3.png -------------------------------------------------------------------------------- /screenshot/Screenshot_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_4.png -------------------------------------------------------------------------------- /screenshot/Screenshot_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_5.png -------------------------------------------------------------------------------- /screenshot/Screenshot_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_6.png -------------------------------------------------------------------------------- /screenshot/Screenshot_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_7.png -------------------------------------------------------------------------------- /screenshot/Screenshot_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_8.png -------------------------------------------------------------------------------- /screenshot/Screenshot_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xieyezi/flutter-shopping-AiRi/d82770b1054bf8f99b83acaf8ed56c63562e1a5f/screenshot/Screenshot_9.png -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:AiRi/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | --------------------------------------------------------------------------------