├── ios
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── icon_1024.png
│ │ │ ├── icon_20@1x.png
│ │ │ ├── icon_20@2x.png
│ │ │ ├── icon_20@3x.png
│ │ │ ├── icon_29@1x.png
│ │ │ ├── icon_29@2x.png
│ │ │ ├── icon_29@3x.png
│ │ │ ├── icon_40@1x.png
│ │ │ ├── icon_40@2x.png
│ │ │ ├── icon_40@3x.png
│ │ │ ├── icon_60@2x.png
│ │ │ ├── icon_60@3x.png
│ │ │ ├── icon_76@1x.png
│ │ │ ├── icon_76@2x.png
│ │ │ ├── icon_20@2x-1.png
│ │ │ ├── icon_29@2x-1.png
│ │ │ ├── icon_40@2x-1.png
│ │ │ ├── icon_83.5@2x.png
│ │ │ └── Contents.json
│ │ └── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
└── Runner.xcworkspace
│ └── contents.xcworkspacedata
├── 示例图
├── 伙伴.png
├── 启动图.png
├── 商店.png
├── 我的.png
├── 首页.png
└── 首页推上.png
├── android
├── key.properties
├── minic_applicaion.jks
├── gradle.properties
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── values
│ │ │ │ │ └── styles.xml
│ │ │ │ └── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── boohee
│ │ │ │ │ └── one
│ │ │ │ │ └── boohee_flutter
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ ├── proguard-rules.pro
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── settings.gradle
└── build.gradle
├── images
├── ic_arrow_grey.png
├── ic_home_baby.png
├── ic_home_habit.png
├── ic_home_sleep.png
├── ic_home_sport.png
├── ic_home_step.png
├── ic_me_address.png
├── ic_me_order.png
├── ic_me_ticket.png
├── ic_boohee_logo.png
├── ic_home_calorie.png
├── ic_home_weight.png
├── ic_message_grey.png
├── ic_search_grey.png
├── ic_search_white.png
├── ic_dietician_logo.png
├── ic_home_dietician.png
├── ic_home_food_plan.png
├── ic_message_white.png
├── ic_settings_white.png
├── ic_shop_cart_white.png
├── ic_tab_bar_me_grey.png
├── ic_home_menstruation.png
├── ic_home_tabbar_plus.png
├── ic_me_shopping_cart.png
├── ic_tab_bar_home_grey.png
├── ic_tab_bar_me_green.png
├── ic_tab_bar_shop_grey.png
├── ic_arrow_light_yellow.png
├── ic_home_circumference.png
├── ic_tab_bar_home_green.png
├── ic_tab_bar_partner_grey.png
├── ic_tab_bar_shop_green.png
├── ic_tab_bar_partner_green.png
└── ic_home_default_wallpaper.webp
├── fonts
└── Montserrat-Bold.otf
├── lib
├── app
│ └── route
│ │ ├── application.dart
│ │ ├── route_handlers.dart
│ │ ├── routes.dart
│ │ └── fluro_navigator.dart
├── main.dart
├── utils
│ ├── toast_utils.dart
│ ├── utils.dart
│ ├── repository_utils.dart
│ ├── account_utils.dart
│ ├── base64_utils.dart
│ └── browser_url.dart
├── common
│ ├── colors.dart
│ ├── view_factory.dart
│ └── constant.dart
├── widget
│ ├── top_bottom_widget.dart
│ ├── card_view.dart
│ ├── round_button.dart
│ ├── tool_bar.dart
│ ├── home_common_card.dart
│ ├── md2_tab_indicator.dart
│ ├── header
│ │ └── home_wallpaper_header.dart
│ └── common_search_bar.dart
├── model
│ ├── splash_ad.dart
│ ├── splash_ad.g.dart
│ ├── mine_cards.dart
│ ├── home_tools.dart
│ ├── mine_cards.g.dart
│ ├── home_wall_paper.dart
│ ├── home_tools.g.dart
│ ├── login_user.dart
│ ├── home_wall_paper.g.dart
│ ├── login_user.g.dart
│ ├── discover
│ │ ├── sub_discover.dart
│ │ └── sub_discover.g.dart
│ ├── ShopRecommendList.dart
│ ├── ShopRecommendList.g.dart
│ ├── ShopBanner.dart
│ └── ShopBanner.g.dart
├── views
│ ├── route_component.dart
│ ├── common
│ │ ├── wallpaper_page.dart
│ │ └── browser_page.dart
│ ├── discover_page.dart
│ ├── main_page.dart
│ ├── login
│ │ └── login_page.dart
│ ├── discover
│ │ └── discover_child_page.dart
│ ├── mine_page.dart
│ ├── shop_pages
│ │ └── shop_page.dart
│ └── home_page.dart
├── res
│ └── styles.dart
└── splash_page.dart
├── .metadata
├── assets
└── json
│ ├── user
│ └── login_user.json
│ ├── common
│ └── splash_ad.json
│ ├── me
│ └── mine_cards.json
│ ├── home
│ ├── home_health_tools.json
│ └── home_wallpaper.json
│ ├── discover
│ └── discover_sub.json
│ └── shop
│ └── shop_banner.json
├── test
└── widget_test.dart
├── README.md
├── .gitignore
├── pubspec.yaml
└── pubspec.lock
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/示例图/伙伴.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/示例图/伙伴.png
--------------------------------------------------------------------------------
/示例图/启动图.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/示例图/启动图.png
--------------------------------------------------------------------------------
/示例图/商店.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/示例图/商店.png
--------------------------------------------------------------------------------
/示例图/我的.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/示例图/我的.png
--------------------------------------------------------------------------------
/示例图/首页.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/示例图/首页.png
--------------------------------------------------------------------------------
/示例图/首页推上.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/示例图/首页推上.png
--------------------------------------------------------------------------------
/android/key.properties:
--------------------------------------------------------------------------------
1 | storePassword=qq123456
2 | keyPassword=qq123456
3 | keyAlias=chenyy
4 |
--------------------------------------------------------------------------------
/images/ic_arrow_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_arrow_grey.png
--------------------------------------------------------------------------------
/images/ic_home_baby.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_baby.png
--------------------------------------------------------------------------------
/images/ic_home_habit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_habit.png
--------------------------------------------------------------------------------
/images/ic_home_sleep.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_sleep.png
--------------------------------------------------------------------------------
/images/ic_home_sport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_sport.png
--------------------------------------------------------------------------------
/images/ic_home_step.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_step.png
--------------------------------------------------------------------------------
/images/ic_me_address.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_me_address.png
--------------------------------------------------------------------------------
/images/ic_me_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_me_order.png
--------------------------------------------------------------------------------
/images/ic_me_ticket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_me_ticket.png
--------------------------------------------------------------------------------
/fonts/Montserrat-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/fonts/Montserrat-Bold.otf
--------------------------------------------------------------------------------
/images/ic_boohee_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_boohee_logo.png
--------------------------------------------------------------------------------
/images/ic_home_calorie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_calorie.png
--------------------------------------------------------------------------------
/images/ic_home_weight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_weight.png
--------------------------------------------------------------------------------
/images/ic_message_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_message_grey.png
--------------------------------------------------------------------------------
/images/ic_search_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_search_grey.png
--------------------------------------------------------------------------------
/images/ic_search_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_search_white.png
--------------------------------------------------------------------------------
/android/minic_applicaion.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/android/minic_applicaion.jks
--------------------------------------------------------------------------------
/images/ic_dietician_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_dietician_logo.png
--------------------------------------------------------------------------------
/images/ic_home_dietician.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_dietician.png
--------------------------------------------------------------------------------
/images/ic_home_food_plan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_food_plan.png
--------------------------------------------------------------------------------
/images/ic_message_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_message_white.png
--------------------------------------------------------------------------------
/images/ic_settings_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_settings_white.png
--------------------------------------------------------------------------------
/images/ic_shop_cart_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_shop_cart_white.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_me_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_me_grey.png
--------------------------------------------------------------------------------
/images/ic_home_menstruation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_menstruation.png
--------------------------------------------------------------------------------
/images/ic_home_tabbar_plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_tabbar_plus.png
--------------------------------------------------------------------------------
/images/ic_me_shopping_cart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_me_shopping_cart.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_home_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_home_grey.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_me_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_me_green.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_shop_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_shop_grey.png
--------------------------------------------------------------------------------
/images/ic_arrow_light_yellow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_arrow_light_yellow.png
--------------------------------------------------------------------------------
/images/ic_home_circumference.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_circumference.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_home_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_home_green.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_partner_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_partner_grey.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_shop_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_shop_green.png
--------------------------------------------------------------------------------
/images/ic_tab_bar_partner_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_tab_bar_partner_green.png
--------------------------------------------------------------------------------
/images/ic_home_default_wallpaper.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/images/ic_home_default_wallpaper.webp
--------------------------------------------------------------------------------
/lib/app/route/application.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:fluro/fluro.dart';
3 |
4 | class Application {
5 | static Router router;
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_1024.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_20@2x-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_29@2x-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_40@2x-1.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenyy0708/BooheeFlutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:auto_size/auto_size.dart';
2 | import 'package:boohee_flutter/views/route_component.dart';
3 |
4 | void main() {
5 | runAutoSizeApp(RouteComponent(), width: 375, height: 667);
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | #Flutter Wrapper
2 | -keep class io.flutter.app.** { *; }
3 | -keep class io.flutter.plugin.** { *; }
4 | -keep class io.flutter.util.** { *; }
5 | -keep class io.flutter.view.** { *; }
6 | -keep class io.flutter.** { *; }
7 | -keep class io.flutter.plugins.** { *; }
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/lib/utils/toast_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:toast/toast.dart';
3 |
4 | class ToastUtils {
5 | static void showToast(BuildContext context, String msg,
6 | {int duration, int gravity}) {
7 | Toast.show(msg, context, duration: duration, gravity: gravity);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/common/colors.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | Color mainColor = const Color(0xFF31D1AD);
4 | Color color373D52 = const Color(0xFF373D52);
5 | Color colorA8ACBC = const Color(0xFFA8ACBC);
6 | Color colorFF6C65 = const Color(0xFFFF6C65);
7 | Color color00CDA2 = const Color(0xFF00CDA2);
8 | Color colorEEEFF3 = const Color(0xFFEEEFF3);
9 | Color color0EB794 = const Color(0xFF0EB794);
10 | Color colorFEBB07 = const Color(0xFFFEBB07);
11 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/boohee/one/boohee_flutter/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.boohee.one.boohee_flutter
2 |
3 | import android.os.Bundle
4 |
5 | import io.flutter.app.FlutterActivity
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | GeneratedPluginRegistrant.registerWith(this)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/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: [UIApplicationLaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/utils/utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/cupertino.dart';
4 |
5 | class Utils {
6 | static String getImgPath(String name, {String format: 'png'}) {
7 | return 'images/$name.$format';
8 | }
9 |
10 | static Color nameToColor(String name) {
11 | // assert(name.length > 1);
12 | final int hash = name.hashCode & 0xffff;
13 | final double hue = (360.0 * hash / (1 << 15)) % 360.0;
14 | return HSVColor.fromAHSV(1.0, hue, 0.4, 0.90).toColor();
15 | }
16 | }
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/lib/widget/top_bottom_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/res/styles.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class TopBottom extends StatelessWidget {
5 | final Widget top;
6 | final Widget bottom;
7 | final double margin;
8 |
9 | TopBottom({
10 | this.top,
11 | this.bottom,
12 | this.margin,
13 | });
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | return Column(
18 | children: [
19 | top,
20 | SizeBoxFactory.getVerticalSizeBox(margin),
21 | bottom
22 | ],
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/assets/json/user/login_user.json:
--------------------------------------------------------------------------------
1 | {
2 | "user": {
3 | "user_key": "3ad64cc4-ed8e-45b2-9a8a-125577b3e71e",
4 | "user_name": "薄荷测试账号",
5 | "email": null,
6 | "cellphone": "18370622030",
7 | "cellphone_state": true,
8 | "user_type": 0,
9 | "created_at": "2019-02-28T00:10:09.000+08:00",
10 | "nick_name": null,
11 | "gender": null,
12 | "birthday": null,
13 | "height": null,
14 | "avatar_url": "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3607875829,3212684153&fm=26&gp=0.jpg",
15 | "at_coin_balance": 0
16 | },
17 | "token": "hAw338p5x4xsGxK6hqHCN8zb8xMrpW8n"
18 | }
--------------------------------------------------------------------------------
/lib/common/view_factory.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class ViewFactory {
4 | // 创建通用的CardView
5 | static Card createCard(
6 | Widget child,
7 | EdgeInsetsGeometry margin,
8 | double height, {
9 | double elevation: 1,
10 | double radius: 12,
11 | }) {
12 | return Card(
13 | shape: // 圆角
14 | RoundedRectangleBorder(borderRadius: BorderRadius.circular(radius)),
15 | margin: margin,
16 | elevation: elevation,
17 | child: Container(
18 | width: double.infinity,
19 | height: height,
20 | child: child,
21 | ),
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/utils/repository_utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 | import 'dart:math';
3 |
4 | import 'package:flutter/services.dart';
5 |
6 | class Repository {
7 | static Future loadAsset(String fileName,
8 | {String fileDir: 'common'}) async {
9 | return await rootBundle.loadString('assets/json/$fileDir/$fileName.json');
10 | }
11 |
12 | static Map toMap(String json) {
13 | return jsonDecode(json);
14 | }
15 |
16 | /// 获取json集合中随机一个数据
17 | static Map toMapForList(String json) {
18 | List mLists = jsonDecode(json);
19 | return mLists[Random().nextInt(mLists.length)];
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/lib/utils/account_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/common/constant.dart';
2 | import 'package:boohee_flutter/model/login_user.dart';
3 | import 'package:flustars/flustars.dart';
4 |
5 | class AccountUtils {
6 | static User mUser;
7 |
8 | static bool isLogin() {
9 | String token = SpUtil.getString(Constant.token, defValue: "");
10 | return token.isNotEmpty;
11 | }
12 |
13 | static void saveUser(LoginUser user) {
14 | SpUtil.putObject(Constant.login_user, user);
15 | }
16 |
17 | static User getUser() {
18 | if (mUser == null) {
19 | mUser =
20 | SpUtil.getObj(Constant.login_user, (v) => LoginUser.fromJson(v)).user;
21 | }
22 | return mUser;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/model/splash_ad.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'splash_ad.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class SplashAd extends Object {
8 |
9 | @JsonKey(name: 'id')
10 | int id;
11 |
12 | @JsonKey(name: 'start_up_url')
13 | String startUpUrl;
14 |
15 | @JsonKey(name: 'is_ad')
16 | bool isAd;
17 |
18 | @JsonKey(name: 'text')
19 | String text;
20 |
21 | @JsonKey(name: 'link')
22 | String link;
23 |
24 | SplashAd(this.id,this.startUpUrl,this.isAd,this.text,this.link,);
25 |
26 | factory SplashAd.fromJson(Map srcJson) => _$SplashAdFromJson(srcJson);
27 |
28 | Map toJson() => _$SplashAdToJson(this);
29 |
30 | }
31 |
32 |
33 |
--------------------------------------------------------------------------------
/assets/json/common/splash_ad.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 236,
4 | "start_up_url": "http://up.boohee.cn/house/u/shop/ad_page/0812/jrw.jpg",
5 | "is_ad": true,
6 | "text": "低脂鸡胸肉丸新上市!自营满200返200",
7 | "link": "https://one.boohee.com/store/pages/august_week3?page_from=launch_screen",
8 | "pop_ads": []
9 | },
10 | {
11 | "id": 237,
12 | "start_up_url": "http://up.boohee.cn/house/u/shop/ad_page/0812/cc.jpg",
13 | "is_ad": true,
14 | "text": "5/7日体重突击,另返100元代金券",
15 | "link": "https://one.boohee.com/store/pages/august_week3?page_from=launch_screen",
16 | "pop_ads": []
17 | },
18 | {
19 | "id": 3,
20 | "start_up_url": "http://up.boohee.cn/house/u/one/screen/summer_kp.jpg",
21 | "is_ad": false,
22 | "text": "",
23 | "link": "",
24 | "pop_ads": []
25 | }
26 | ]
--------------------------------------------------------------------------------
/lib/model/splash_ad.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'splash_ad.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | SplashAd _$SplashAdFromJson(Map json) {
10 | return SplashAd(
11 | json['id'] as int,
12 | json['start_up_url'] as String,
13 | json['is_ad'] as bool,
14 | json['text'] as String,
15 | json['link'] as String,
16 | );
17 | }
18 |
19 | Map _$SplashAdToJson(SplashAd instance) => {
20 | 'id': instance.id,
21 | 'start_up_url': instance.startUpUrl,
22 | 'is_ad': instance.isAd,
23 | 'text': instance.text,
24 | 'link': instance.link,
25 | };
26 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/widget/card_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | /// 全局Card,统一Card样式便于全局修改
5 | class CardView extends StatelessWidget {
6 | final EdgeInsetsGeometry margin;
7 | final Widget child;
8 | final double elevation;
9 | final double radius;
10 | final Function onPressed;
11 |
12 | CardView(
13 | {Key key,
14 | this.margin,
15 | this.child,
16 | this.onPressed,
17 | this.elevation: 1,
18 | this.radius: 12})
19 | : super(key: key);
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return Card(
24 | shape: // 圆角
25 | RoundedRectangleBorder(borderRadius: BorderRadius.circular(radius)),
26 | margin: margin,
27 | elevation: elevation,
28 | child: InkWell(
29 | onTap: onPressed,
30 | child: child,
31 | ),
32 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/views/route_component.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/app/route/application.dart';
2 | import 'package:boohee_flutter/app/route/routes.dart';
3 | import 'package:fluro/fluro.dart';
4 | import 'package:flutter/cupertino.dart';
5 | import 'package:flutter/material.dart';
6 |
7 | import '../splash_page.dart';
8 |
9 | class RouteComponent extends StatefulWidget {
10 | @override
11 | _RouteComponentState createState() => _RouteComponentState();
12 | }
13 |
14 | class _RouteComponentState extends State {
15 | _RouteComponentState() {
16 | final router = new Router();
17 | Routes.configureRoutes(router);
18 | Application.router = router;
19 | }
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return MaterialApp(
24 | theme: ThemeData(
25 | primarySwatch: Colors.blue, scaffoldBackgroundColor: Colors.white),
26 | home: SplashPage(),
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/utils/base64_utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:crypto/crypto.dart';
4 |
5 | class Base64 {
6 | static const String HMAC_SHA1 = "HmacSHA1";
7 |
8 | /*
9 | * Base64加密
10 | */
11 | static String encodeBase64(String data) {
12 | var content = utf8.encode(data);
13 | var digest = base64Encode(content);
14 | return digest;
15 | }
16 |
17 | /*
18 | * Base64加密
19 | */
20 | static String encodeBase64ForBytes(List data) {
21 | var digest = base64Encode(data);
22 | return digest;
23 | }
24 |
25 | /*
26 | * Base64解密
27 | */
28 | static String decodeBase64(String data) {
29 | return String.fromCharCodes(base64Decode(data));
30 | }
31 |
32 | /*
33 | * HMAC加密
34 | */
35 | static String encryptHMAC(String data, String key) {
36 | var _key = utf8.encode(key);
37 | var bytes = utf8.encode(data);
38 |
39 | var hmacSha256 = new Hmac(sha1, _key); // HMAC-SHA256
40 | var digest = hmacSha256.convert(bytes);
41 | String content = encodeBase64ForBytes(digest.bytes);
42 | return content;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/model/mine_cards.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'mine_cards.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class MineCards extends Object {
8 |
9 | @JsonKey(name: 'success')
10 | bool success;
11 |
12 | @JsonKey(name: 'msg')
13 | String msg;
14 |
15 | @JsonKey(name: 'data')
16 | List data;
17 |
18 | MineCards(this.success,this.msg,this.data,);
19 |
20 | factory MineCards.fromJson(Map srcJson) => _$MineCardsFromJson(srcJson);
21 |
22 | Map toJson() => _$MineCardsToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Data extends Object {
29 |
30 | @JsonKey(name: 'id')
31 | int id;
32 |
33 | @JsonKey(name: 'name')
34 | String name;
35 |
36 | @JsonKey(name: 'icon_url')
37 | String iconUrl;
38 |
39 | @JsonKey(name: 'url')
40 | String url;
41 |
42 | Data(this.id,this.name,this.iconUrl,this.url,);
43 |
44 | factory Data.fromJson(Map srcJson) => _$DataFromJson(srcJson);
45 |
46 | Map toJson() => _$DataToJson(this);
47 |
48 | }
49 |
50 |
51 |
--------------------------------------------------------------------------------
/lib/model/home_tools.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'home_tools.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class HomeTools extends Object {
8 |
9 | @JsonKey(name: 'success')
10 | bool success;
11 |
12 | @JsonKey(name: 'msg')
13 | String msg;
14 |
15 | @JsonKey(name: 'data')
16 | List data;
17 |
18 | HomeTools(this.success,this.msg,this.data,);
19 |
20 | factory HomeTools.fromJson(Map srcJson) => _$HomeToolsFromJson(srcJson);
21 |
22 | Map toJson() => _$HomeToolsToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Data extends Object {
29 |
30 | @JsonKey(name: 'id')
31 | int id;
32 |
33 | @JsonKey(name: 'name')
34 | String name;
35 |
36 | @JsonKey(name: 'code')
37 | String code;
38 |
39 | @JsonKey(name: 'visible')
40 | bool visible;
41 |
42 | @JsonKey(name: 'editable')
43 | bool editable;
44 |
45 | Data(this.id,this.name,this.code,this.visible,this.editable,);
46 |
47 | factory Data.fromJson(Map srcJson) => _$DataFromJson(srcJson);
48 |
49 | Map toJson() => _$DataToJson(this);
50 |
51 | }
52 |
53 |
54 |
--------------------------------------------------------------------------------
/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:boohee_flutter/views/route_component.dart';
9 | import 'package:flutter/material.dart';
10 | import 'package:flutter_test/flutter_test.dart';
11 |
12 | void main() {
13 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
14 | // Build our app and trigger a frame.
15 | await tester.pumpWidget(RouteComponent());
16 |
17 | // Verify that our counter starts at 0.
18 | expect(find.text('0'), findsOneWidget);
19 | expect(find.text('1'), findsNothing);
20 |
21 | // Tap the '+' icon and trigger a frame.
22 | await tester.tap(find.byIcon(Icons.add));
23 | await tester.pump();
24 |
25 | // Verify that our counter has incremented.
26 | expect(find.text('0'), findsNothing);
27 | expect(find.text('1'), findsOneWidget);
28 | });
29 | }
30 |
--------------------------------------------------------------------------------
/lib/common/constant.dart:
--------------------------------------------------------------------------------
1 | class Constant {
2 | static const String login_user = "login_user";
3 | static const String token = "token";
4 | static const String user_key = "user_key";
5 | static const String y_mo_d_v2 = "yyyy/MM/dd";
6 | }
7 |
8 | class HomeCard {
9 | // 减肥环和健康习惯
10 | static const String HEALTH_WEIGHT = "减肥环和健康习惯";
11 |
12 | // 饮食&运动记录
13 | static const String DIET_SPORT_RECORD = "diet_exercise_record";
14 |
15 | // 体重记录
16 | static const String WEIGHT_RECORD = "weight_record";
17 |
18 | // 智慧营养师
19 | static const String WISDOM = "wisdom";
20 |
21 | // 健康习惯
22 | static const String HEALTH_HABITS = "health_habits";
23 |
24 | // 步数统计
25 | static const String STEPS_RECORD = "steps_record";
26 |
27 | // 生理期记录
28 | static const String PERIODS_RECORD = "periods_record";
29 |
30 | // 睡眠记录
31 | static const String SLEEP_RECORD = "sleep_record";
32 |
33 | // 宝宝计划
34 | static const String BABY = "baby";
35 |
36 | // 饮食计划
37 | static const String DIET_PLAN = "diet_plan";
38 |
39 | // 运动训练
40 | static const String EXERCISE = "exercise";
41 |
42 | // 围度记录
43 | static const String MEASURE_RECORD = "measure_record";
44 |
45 | // 底部可定制TAB
46 | static const String SMART_CARD = "SMART_CARD";
47 | }
48 |
--------------------------------------------------------------------------------
/lib/model/mine_cards.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'mine_cards.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | MineCards _$MineCardsFromJson(Map json) {
10 | return MineCards(
11 | json['success'] as bool,
12 | json['msg'] as String,
13 | (json['data'] as List)
14 | ?.map(
15 | (e) => e == null ? null : Data.fromJson(e as Map))
16 | ?.toList(),
17 | );
18 | }
19 |
20 | Map _$MineCardsToJson(MineCards instance) => {
21 | 'success': instance.success,
22 | 'msg': instance.msg,
23 | 'data': instance.data,
24 | };
25 |
26 | Data _$DataFromJson(Map json) {
27 | return Data(
28 | json['id'] as int,
29 | json['name'] as String,
30 | json['icon_url'] as String,
31 | json['url'] as String,
32 | );
33 | }
34 |
35 | Map _$DataToJson(Data instance) => {
36 | 'id': instance.id,
37 | 'name': instance.name,
38 | 'icon_url': instance.iconUrl,
39 | 'url': instance.url,
40 | };
41 |
--------------------------------------------------------------------------------
/lib/model/home_wall_paper.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'home_wall_paper.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class HomeWallPaper extends Object {
8 |
9 | @JsonKey(name: 'welcome_img')
10 | Welcome_img welcomeImg;
11 |
12 | HomeWallPaper(this.welcomeImg,);
13 |
14 | factory HomeWallPaper.fromJson(Map srcJson) => _$HomeWallPaperFromJson(srcJson);
15 |
16 | Map toJson() => _$HomeWallPaperToJson(this);
17 |
18 | }
19 |
20 |
21 | @JsonSerializable()
22 | class Welcome_img extends Object {
23 |
24 | @JsonKey(name: 'hello_text')
25 | String helloText;
26 |
27 | @JsonKey(name: 'back_img')
28 | String backImg;
29 |
30 | @JsonKey(name: 'back_img_small')
31 | String backImgSmall;
32 |
33 | @JsonKey(name: 'back_img_x')
34 | String backImgX;
35 |
36 | @JsonKey(name: 'video_url')
37 | String videoUrl;
38 |
39 | @JsonKey(name: 'link')
40 | String link;
41 |
42 | @JsonKey(name: 'date')
43 | String date;
44 |
45 | Welcome_img(this.helloText,this.backImg,this.backImgSmall,this.backImgX,this.videoUrl,this.link,this.date,);
46 |
47 | factory Welcome_img.fromJson(Map srcJson) => _$Welcome_imgFromJson(srcJson);
48 |
49 | Map toJson() => _$Welcome_imgToJson(this);
50 |
51 | }
52 |
53 |
54 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.2.71'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.2.1'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 |
13 | subprojects {
14 | project.configurations.all {
15 | resolutionStrategy.eachDependency { details ->
16 | if (details.requested.group == 'com.android.support'
17 | && !details.requested.name.contains('multidex') ) {
18 | details.useVersion "28.0.0"
19 | }
20 |
21 | if (details.requested.group == 'androidx.core'
22 | && !details.requested.name.contains('androidx') ) {
23 | details.useVersion "1.0.0"
24 | }
25 | }
26 | }
27 | }
28 | }
29 |
30 | allprojects {
31 | repositories {
32 | google()
33 | jcenter()
34 | }
35 | }
36 |
37 | rootProject.buildDir = '../build'
38 | subprojects {
39 | project.buildDir = "${rootProject.buildDir}/${project.name}"
40 | }
41 | subprojects {
42 | project.evaluationDependsOn(':app')
43 | }
44 |
45 | task clean(type: Delete) {
46 | delete rootProject.buildDir
47 | }
48 |
--------------------------------------------------------------------------------
/lib/model/home_tools.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'home_tools.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | HomeTools _$HomeToolsFromJson(Map json) {
10 | return HomeTools(
11 | json['success'] as bool,
12 | json['msg'] as String,
13 | (json['data'] as List)
14 | ?.map(
15 | (e) => e == null ? null : Data.fromJson(e as Map))
16 | ?.toList(),
17 | );
18 | }
19 |
20 | Map _$HomeToolsToJson(HomeTools instance) => {
21 | 'success': instance.success,
22 | 'msg': instance.msg,
23 | 'data': instance.data,
24 | };
25 |
26 | Data _$DataFromJson(Map json) {
27 | return Data(
28 | json['id'] as int,
29 | json['name'] as String,
30 | json['code'] as String,
31 | json['visible'] as bool,
32 | json['editable'] as bool,
33 | );
34 | }
35 |
36 | Map _$DataToJson(Data instance) => {
37 | 'id': instance.id,
38 | 'name': instance.name,
39 | 'code': instance.code,
40 | 'visible': instance.visible,
41 | 'editable': instance.editable,
42 | };
43 |
--------------------------------------------------------------------------------
/lib/widget/round_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/common/colors.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | /// 通用的圆角button按钮
5 | class RoundButton extends StatelessWidget {
6 | final Color backgroundColor;
7 | final Text buttonText;
8 | final Function onPressed;
9 | final String text;
10 | final EdgeInsetsGeometry padding;
11 | final double radius;
12 |
13 | RoundButton(
14 | {this.backgroundColor,
15 | this.buttonText,
16 | this.onPressed,
17 | this.padding,
18 | this.radius: 20,
19 | this.text});
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return ButtonTheme(
24 | materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
25 | padding: EdgeInsets.all(0),
26 | height: 1,
27 | minWidth: 1,
28 | child: FlatButton(
29 | padding:
30 | padding ?? EdgeInsets.only(left: 7, right: 7, top: 4, bottom: 4),
31 | shape: new RoundedRectangleBorder(
32 | borderRadius: new BorderRadius.circular(radius)),
33 | color: this.backgroundColor ?? color00CDA2,
34 | child: buttonText ??
35 | Text(
36 | text,
37 | style: TextStyle(fontSize: 10, color: Colors.white),
38 | ),
39 | onPressed: onPressed ?? () {},
40 | ),
41 | );
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/lib/app/route/route_handlers.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * fluro
3 | * Created by Yakka
4 | * https://theyakka.com
5 | *
6 | * Copyright (c) 2019 Yakka, LLC. All rights reserved.
7 | * See LICENSE for distribution and usage details.
8 | */
9 | import 'package:boohee_flutter/views/common/browser_page.dart';
10 | import 'package:boohee_flutter/views/common/wallpaper_page.dart';
11 | import 'package:boohee_flutter/views/login/login_page.dart';
12 | import 'package:boohee_flutter/views/main_page.dart';
13 | import 'package:fluro/fluro.dart';
14 | import 'package:flutter/material.dart';
15 |
16 | var rootHandler = new Handler(
17 | handlerFunc: (BuildContext context, Map> params) {
18 | return new MainPage();
19 | });
20 |
21 | var loginHandler = new Handler(
22 | handlerFunc: (BuildContext context, Map> params) {
23 | return new LoginPage();
24 | });
25 |
26 | var webViewHandler = new Handler(
27 | handlerFunc: (BuildContext context, Map> params) {
28 | String param = params["web_url"]?.first;
29 | return new BrowserPage(
30 | webViewUrl: param,
31 | );
32 | });
33 |
34 | var wallPaperHandler = new Handler(
35 | handlerFunc: (BuildContext context, Map> params) {
36 | String param = params["image_url"]?.first;
37 | return new WallPaperPage(
38 | wallPaperImageUrl: param,
39 | );
40 | });
41 |
--------------------------------------------------------------------------------
/lib/model/login_user.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'login_user.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class LoginUser extends Object {
8 |
9 | @JsonKey(name: 'user')
10 | User user;
11 |
12 | @JsonKey(name: 'token')
13 | String token;
14 |
15 | LoginUser(this.user,this.token,);
16 |
17 | factory LoginUser.fromJson(Map srcJson) => _$LoginUserFromJson(srcJson);
18 |
19 | Map toJson() => _$LoginUserToJson(this);
20 |
21 | }
22 |
23 |
24 | @JsonSerializable()
25 | class User extends Object {
26 |
27 | @JsonKey(name: 'user_key')
28 | String userKey;
29 |
30 | @JsonKey(name: 'user_name')
31 | String userName;
32 |
33 | @JsonKey(name: 'cellphone')
34 | String cellphone;
35 |
36 | @JsonKey(name: 'cellphone_state')
37 | bool cellphoneState;
38 |
39 | @JsonKey(name: 'user_type')
40 | int userType;
41 |
42 | @JsonKey(name: 'created_at')
43 | String createdAt;
44 |
45 | @JsonKey(name: 'avatar_url')
46 | String avatarUrl;
47 |
48 | @JsonKey(name: 'at_coin_balance')
49 | int atCoinBalance;
50 |
51 | User(this.userKey,this.userName,this.cellphone,this.cellphoneState,this.userType,this.createdAt,this.avatarUrl,this.atCoinBalance,);
52 |
53 | factory User.fromJson(Map srcJson) => _$UserFromJson(srcJson);
54 |
55 | Map toJson() => _$UserToJson(this);
56 |
57 | }
58 |
59 |
60 |
--------------------------------------------------------------------------------
/lib/model/home_wall_paper.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'home_wall_paper.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | HomeWallPaper _$HomeWallPaperFromJson(Map json) {
10 | return HomeWallPaper(
11 | json['welcome_img'] == null
12 | ? null
13 | : Welcome_img.fromJson(json['welcome_img'] as Map),
14 | );
15 | }
16 |
17 | Map _$HomeWallPaperToJson(HomeWallPaper instance) =>
18 | {
19 | 'welcome_img': instance.welcomeImg,
20 | };
21 |
22 | Welcome_img _$Welcome_imgFromJson(Map json) {
23 | return Welcome_img(
24 | json['hello_text'] as String,
25 | json['back_img'] as String,
26 | json['back_img_small'] as String,
27 | json['back_img_x'] as String,
28 | json['video_url'] as String,
29 | json['link'] as String,
30 | json['date'] as String,
31 | );
32 | }
33 |
34 | Map _$Welcome_imgToJson(Welcome_img instance) =>
35 | {
36 | 'hello_text': instance.helloText,
37 | 'back_img': instance.backImg,
38 | 'back_img_small': instance.backImgSmall,
39 | 'back_img_x': instance.backImgX,
40 | 'video_url': instance.videoUrl,
41 | 'link': instance.link,
42 | 'date': instance.date,
43 | };
44 |
--------------------------------------------------------------------------------
/lib/app/route/routes.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * fluro
3 | * Created by Yakka
4 | * https://theyakka.com
5 | *
6 | * Copyright (c) 2019 Yakka, LLC. All rights reserved.
7 | * See LICENSE for distribution and usage details.
8 | */
9 | import 'package:fluro/fluro.dart';
10 | import 'package:flutter/cupertino.dart';
11 |
12 | import './route_handlers.dart';
13 |
14 | class Routes {
15 | /// 首页
16 | static String root = "/home";
17 |
18 | /// 登陆
19 | static String login = "/login";
20 |
21 | /// WebView
22 | static String webView = "/browserweb";
23 |
24 | /// 壁纸
25 | static String wallPaper = "/wallPaper";
26 |
27 | static void configureRoutes(Router router) {
28 | router.define(root, handler: rootHandler);
29 | router.define(login, handler: loginHandler);
30 | router.define(webView, handler: webViewHandler);
31 | router.define(wallPaper, handler: wallPaperHandler);
32 | }
33 |
34 | /// 从顶部弹出动画
35 | static RouteTransitionsBuilder transitionTopToBottom() {
36 | return (BuildContext context, Animation animation,
37 | Animation secondaryAnimation, Widget child) {
38 | /// x,y代表是的相对自己x轴移动一倍的自己 y轴移动2倍的自己
39 | const Offset begin = const Offset(0.0, -1.0);
40 | const Offset end = const Offset(0.0, 0.0);
41 |
42 | /// 相对自己移动的动画
43 | return SlideTransition(
44 | position: Tween(
45 | begin: begin,
46 | end: end,
47 | ).animate(animation),
48 | child: child,
49 | );
50 | };
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/lib/model/login_user.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'login_user.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | LoginUser _$LoginUserFromJson(Map json) {
10 | return LoginUser(
11 | json['user'] == null
12 | ? null
13 | : User.fromJson(json['user'] as Map),
14 | json['token'] as String,
15 | );
16 | }
17 |
18 | Map _$LoginUserToJson(LoginUser instance) => {
19 | 'user': instance.user,
20 | 'token': instance.token,
21 | };
22 |
23 | User _$UserFromJson(Map json) {
24 | return User(
25 | json['user_key'] as String,
26 | json['user_name'] as String,
27 | json['cellphone'] as String,
28 | json['cellphone_state'] as bool,
29 | json['user_type'] as int,
30 | json['created_at'] as String,
31 | json['avatar_url'] as String,
32 | json['at_coin_balance'] as int,
33 | );
34 | }
35 |
36 | Map _$UserToJson(User instance) => {
37 | 'user_key': instance.userKey,
38 | 'user_name': instance.userName,
39 | 'cellphone': instance.cellphone,
40 | 'cellphone_state': instance.cellphoneState,
41 | 'user_type': instance.userType,
42 | 'created_at': instance.createdAt,
43 | 'avatar_url': instance.avatarUrl,
44 | 'at_coin_balance': instance.atCoinBalance,
45 | };
46 |
--------------------------------------------------------------------------------
/assets/json/me/mine_cards.json:
--------------------------------------------------------------------------------
1 | {
2 | "success": true,
3 | "msg": "",
4 | "data": [
5 | {
6 | "id": 7,
7 | "name": "健康报告",
8 | "icon_url": "https://up.boohee.cn/house/u/mycard/report.png",
9 | "url": "boohee://new_health_report/mine_health_report"
10 | },
11 | {
12 | "id": 1,
13 | "name": "NICE服务",
14 | "icon_url": "https://up.boohee.cn/house/u/mycard/NICE.png",
15 | "url": "https://nice.boohee.cn/api/v1/contracts.html"
16 | },
17 | {
18 | "id": 3,
19 | "name": "智能设备",
20 | "icon_url": "https://up.boohee.cn/house/u/mycard/facility.png",
21 | "url": "boohee://new_hardware_activity"
22 | },
23 | {
24 | "id": 5,
25 | "name": "我的收藏",
26 | "icon_url": "https://up.boohee.cn/house/u/mycard/mycollection.png",
27 | "url": "boohee://new_my_collection"
28 | },
29 | {
30 | "id": 6,
31 | "name": "我的食物",
32 | "icon_url": "https://up.boohee.cn/house/u/mycard/myfood.png",
33 | "url": "boohee://new_my_food"
34 | },
35 | {
36 | "id": 2,
37 | "name": "挑战赛",
38 | "icon_url": "https://up.boohee.cn/house/u/mycard/challenge.png",
39 | "url": "boohee://new_challenge"
40 | },
41 | {
42 | "id": 4,
43 | "name": "打卡群",
44 | "icon_url": "https://up.boohee.cn/house/u/mycard/group.png",
45 | "url": "boohee://new_clock_in_group"
46 | },
47 | {
48 | "id": 8,
49 | "name": "兑换",
50 | "icon_url": "https://up.boohee.cn/house/u/mycard/exchange.png",
51 | "url": "https://truck.boohee.com/wisdom/exchange"
52 | }
53 | ]
54 | }
--------------------------------------------------------------------------------
/lib/utils/browser_url.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/common/constant.dart';
2 | import 'package:flustars/flustars.dart';
3 |
4 | class BrowserUrlManager {
5 | static const String URL_BASE = "https://pixiu.boohee.com/";
6 |
7 | // static const String URL_BASE = "https://pixiu.iboohee.cn/";
8 |
9 | /// 智慧营养师首页
10 | static const String URL_PAY_SMART_ANALYSIS = URL_BASE + "recipe-detail?date=";
11 |
12 | /// 饮食运动记录h5
13 | static const String URL_CALORY = "https://calory.boohee.com/";
14 |
15 | static String getSmartAnalysisUrl() {
16 | return URL_PAY_SMART_ANALYSIS +
17 | DateUtil.formatDate(DateTime.now(), format: Constant.y_mo_d_v2);
18 | }
19 |
20 | static Future handleUrl(String url) async {
21 | await SpUtil.getInstance();
22 | if (url.isEmpty) {
23 | return null;
24 | }
25 | url = appendBaseParams(url);
26 | url = appendToken(url);
27 | return url;
28 | }
29 |
30 | /// 为所有url添加基本参数
31 | static String appendBaseParams(String url) {
32 | if (url.contains("?")) {
33 | url += "&app_device=Android";
34 | } else {
35 | url += "?app_device=Android";
36 | }
37 | url += "&channel=" + "boohee";
38 | url += "&app_key=" + "one";
39 | return url;
40 | }
41 |
42 | /// 来自薄荷的url会加上token
43 | static String appendToken(String url) {
44 | if (url.contains("boohee.com") ||
45 | url.contains("boohee.cn") ||
46 | url.contains("iboohee.cn")) {
47 | if (url.contains("?")) {
48 | url += "&token=";
49 | } else {
50 | url += "?token=";
51 | }
52 | url += SpUtil.getString(Constant.token, defValue: "");
53 | }
54 | return url;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 薄荷APP Flutter
2 |
3 |
4 | ### [Flutter构建首页解析](http://note.youdao.com/noteshare?id=461c33405d38b4877291cfa08f59c48e)
5 |
6 |
7 | ### [下载地址](https://fir.im/nf8x)
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 |
39 |
40 |
41 |
42 |
43 | 商店
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 我的
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/lib/widget/tool_bar.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/common/colors.dart';
2 | import 'package:boohee_flutter/res/styles.dart';
3 | import 'package:boohee_flutter/utils/utils.dart';
4 | import 'package:flustars/flustars.dart';
5 | import 'package:flutter/material.dart';
6 |
7 | /// 通用的顶部标题栏
8 | class Toolbar extends StatelessWidget implements PreferredSizeWidget {
9 | final String text;
10 | final Function onTabRightOne;
11 |
12 | Toolbar({this.text, this.onTabRightOne});
13 |
14 | @override
15 | Widget build(BuildContext context) {
16 | return Container(
17 | color: color00CDA2,
18 | padding: EdgeInsets.only(
19 | left: 17,
20 | right: 17,
21 | top: ScreenUtil.getStatusBarH(context) + 17,
22 | bottom: 17),
23 | child: Row(
24 | children: [
25 | Expanded(
26 | child: Container(
27 | margin: EdgeInsets.only(top: 11, bottom: 11),
28 | child: Text(text ?? "",
29 | style: TextStyle(fontSize: 14, color: Colors.white)),
30 | )),
31 | PaddingStyles.getPadding(14),
32 | InkWell(
33 | child: Image.asset(
34 | Utils.getImgPath("ic_settings_white"),
35 | width: 24,
36 | height: 24,
37 | ),
38 | onTap: onTabRightOne ?? () {},
39 | ),
40 | PaddingStyles.getPadding(14),
41 | Image.asset(
42 | Utils.getImgPath("ic_message_white"),
43 | width: 24,
44 | height: 24,
45 | )
46 | ],
47 | ),
48 | );
49 | }
50 |
51 | @override
52 | Size get preferredSize => Size.fromHeight(200);
53 | }
54 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/assets/json/home/home_health_tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "success": true,
3 | "msg": "",
4 | "data": [
5 | {
6 | "id": 1,
7 | "name": "饮食&运动记录",
8 | "code": "diet_exercise_record",
9 | "visible": true,
10 | "editable": true
11 | },
12 | {
13 | "id": 3,
14 | "name": "饮食计划",
15 | "code": "wisdom",
16 | "visible": true,
17 | "editable": true
18 | },
19 | {
20 | "id": 2,
21 | "name": "体重记录",
22 | "code": "weight_record",
23 | "visible": true,
24 | "editable": true
25 | },
26 | {
27 | "id": 4,
28 | "name": "健康习惯",
29 | "code": "health_habits",
30 | "visible": true,
31 | "editable": true
32 | },
33 | {
34 | "id": 5,
35 | "name": "运动训练",
36 | "code": "exercise",
37 | "visible": true,
38 | "editable": true
39 | },
40 | {
41 | "id": 6,
42 | "name": "围度记录",
43 | "code": "measure_record",
44 | "visible": true,
45 | "editable": true
46 | },
47 | {
48 | "id": 7,
49 | "name": "经期记录",
50 | "code": "periods_record",
51 | "visible": true,
52 | "editable": true
53 | },
54 | {
55 | "id": 9,
56 | "name": "步数记录",
57 | "code": "steps_record",
58 | "visible": true,
59 | "editable": true
60 | },
61 | {
62 | "id": 10,
63 | "name": "睡眠记录",
64 | "code": "sleep_record",
65 | "visible": true,
66 | "editable": true
67 | },
68 | {
69 | "id": 11,
70 | "name": "宝宝记录",
71 | "code": "baby",
72 | "visible": true,
73 | "editable": true
74 | }
75 | ],
76 | "extra": {
77 | "wisdom": {
78 | "bought": true,
79 | "show": true,
80 | "name": "饮食计划"
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .flutter-plugins-dependencies
26 | .packages
27 | .pub-cache/
28 | .pub/
29 | /build/
30 |
31 | # Android related
32 | **/android/**/gradle-wrapper.jar
33 | **/android/.gradle
34 | **/android/captures/
35 | **/android/gradlew
36 | **/android/gradlew.bat
37 | **/android/local.properties
38 | **/android/**/GeneratedPluginRegistrant.java
39 |
40 | # iOS/XCode related
41 | **/ios/**/*.mode1v3
42 | **/ios/**/*.mode2v3
43 | **/ios/**/*.moved-aside
44 | **/ios/**/*.pbxuser
45 | **/ios/**/*.perspectivev3
46 | **/ios/**/*sync/
47 | **/ios/**/.sconsign.dblite
48 | **/ios/**/.tags*
49 | **/ios/**/.vagrant/
50 | **/ios/**/DerivedData/
51 | **/ios/**/Icon?
52 | **/ios/**/Pods/
53 | **/ios/**/.symlinks/
54 | **/ios/**/profile
55 | **/ios/**/xcuserdata
56 | **/ios/.generated/
57 | **/ios/Flutter/App.framework
58 | **/ios/Flutter/Flutter.framework
59 | **/ios/Flutter/Generated.xcconfig
60 | **/ios/Flutter/app.flx
61 | **/ios/Flutter/app.zip
62 | **/ios/Flutter/flutter_assets/
63 | **/ios/ServiceDefinitions.json
64 | **/ios/Runner/GeneratedPluginRegistrant.*
65 |
66 | # Exceptions to above rules.
67 | !**/ios/**/default.mode1v3
68 | !**/ios/**/default.mode2v3
69 | !**/ios/**/default.pbxuser
70 | !**/ios/**/default.perspectivev3
71 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
72 | ios/Podfile
73 | ios/Podfile.lock
74 | ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
75 | ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
76 |
77 |
78 |
--------------------------------------------------------------------------------
/lib/widget/home_common_card.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/res/styles.dart';
2 | import 'package:boohee_flutter/utils/utils.dart';
3 | import 'package:flutter/cupertino.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | /// 首页通用卡片样式
7 | class CommonCard extends StatelessWidget {
8 | final String iconUrl;
9 | final String title;
10 | final Widget subWidget;
11 | final Function onPressed;
12 |
13 | CommonCard({
14 | this.iconUrl,
15 | this.title,
16 | this.subWidget,
17 | this.onPressed,
18 | });
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return InkWell(
23 | onTap: onPressed,
24 | child: Container(
25 | margin: EdgeInsets.only(top: 19, bottom: 19),
26 | padding: EdgeInsets.only(left: 15, right: 15),
27 | child: Row(
28 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
29 | children: [
30 | Row(
31 | children: [
32 | Image.asset(
33 | Utils.getImgPath(iconUrl),
34 | height: 18,
35 | width: 18,
36 | ),
37 | PaddingStyles.getPadding(6),
38 | Text(
39 | title,
40 | style: TextStyles.get14TextBold_373D52(),
41 | )
42 | ],
43 | ),
44 | Row(
45 | children: [
46 | subWidget == null ? Text("") : subWidget,
47 | Image.asset(
48 | Utils.getImgPath(
49 | "ic_arrow_grey",
50 | ),
51 | height: 18,
52 | width: 18,
53 | )
54 | ],
55 | )
56 | ],
57 | ),
58 | ),
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/lib/views/common/wallpaper_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/app/route/fluro_navigator.dart';
2 | import 'package:boohee_flutter/utils/base64_utils.dart';
3 | import 'package:extended_image/extended_image.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | /// 壁纸
7 | class WallPaperPage extends StatefulWidget {
8 | final String wallPaperImageUrl;
9 |
10 | WallPaperPage({this.wallPaperImageUrl});
11 |
12 | @override
13 | _WallPaperPageState createState() => _WallPaperPageState(wallPaperImageUrl);
14 | }
15 |
16 | class _WallPaperPageState extends State {
17 | String wallPaperImageUrl;
18 |
19 | _WallPaperPageState(String wallPaperImageUrl) {
20 | this.wallPaperImageUrl =
21 | Base64.decodeBase64(wallPaperImageUrl.replaceAll("Chen*boohee", "/"));
22 | }
23 |
24 | double _top;
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return Scaffold(
29 | body: Container(
30 | color: Colors.black,
31 | height: double.infinity,
32 | width: double.infinity,
33 | child: GestureDetector(
34 | child: ExtendedImage.network(
35 | wallPaperImageUrl,
36 | cache: true,
37 | fit: BoxFit.cover,
38 | ),
39 | //垂直方向拖动事件
40 | onVerticalDragUpdate: (DragUpdateDetails details) {
41 | _top += details.delta.dy;
42 | },
43 | onVerticalDragDown: (DragDownDetails details) {
44 | _top = 0;
45 | },
46 | onVerticalDragEnd: (DragEndDetails details) {
47 | if (details.velocity.pixelsPerSecond.dy < 0 && _top <= -150) {
48 | // 向上滑
49 | NavigatorUtils.goBack(context);
50 | }
51 | // 重置滑动值
52 | _top = 0;
53 | },
54 | ),
55 | ),
56 | );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | io.flutter.embedded_views_preview
6 |
7 | NSAppTransportSecurity
8 |
9 | NSAllowsArbitraryLoads
10 |
11 |
12 | CFBundleDevelopmentRegion
13 | en
14 | CFBundleExecutable
15 | $(EXECUTABLE_NAME)
16 | CFBundleIdentifier
17 | $(PRODUCT_BUNDLE_IDENTIFIER)
18 | CFBundleInfoDictionaryVersion
19 | 6.0
20 | CFBundleName
21 | 薄荷flutter
22 | CFBundlePackageType
23 | APPL
24 | CFBundleShortVersionString
25 | $(FLUTTER_BUILD_NAME)
26 | CFBundleSignature
27 | ????
28 | CFBundleVersion
29 | $(FLUTTER_BUILD_NUMBER)
30 | LSRequiresIPhoneOS
31 |
32 | UILaunchStoryboardName
33 | LaunchScreen
34 | UIMainStoryboardFile
35 | Main
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UISupportedInterfaceOrientations~ipad
43 |
44 | UIInterfaceOrientationPortrait
45 | UIInterfaceOrientationPortraitUpsideDown
46 | UIInterfaceOrientationLandscapeLeft
47 | UIInterfaceOrientationLandscapeRight
48 |
49 | UIViewControllerBasedStatusBarAppearance
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
11 |
15 |
22 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/lib/res/styles.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:boohee_flutter/common/colors.dart';
4 | import 'package:flutter/cupertino.dart';
5 | import 'package:flutter/material.dart';
6 |
7 | class TextStyles {
8 | static TextStyle get11Text_00CDA2() {
9 | return TextStyle(fontSize: 11, color: color00CDA2);
10 | }
11 |
12 | static TextStyle get11TextA8ACBC() {
13 | return TextStyle(fontSize: 11, color: colorA8ACBC);
14 | }
15 |
16 | static TextStyle get14TextBold_373D52() {
17 | return TextStyle(
18 | fontSize: 14, color: color373D52, fontWeight: FontWeight.w700);
19 | }
20 |
21 | static TextStyle get15Text_373D52() {
22 | return TextStyle(fontSize: 15, color: color373D52);
23 | }
24 |
25 | static TextStyle get15TextBold_373D52() {
26 | return TextStyle(
27 | fontSize: 15, color: color373D52, fontWeight: FontWeight.w700);
28 | }
29 |
30 | static TextStyle get14Text_373D52() {
31 | return TextStyle(fontSize: 14, color: color373D52);
32 | }
33 |
34 | static TextStyle get14TextA8ACBC() {
35 | return TextStyle(fontSize: 14, color: colorA8ACBC);
36 | }
37 |
38 | static TextStyle get12TextA8ACBC() {
39 | return TextStyle(fontSize: 12, color: colorA8ACBC);
40 | }
41 |
42 | static TextStyle get12Text_373D52() {
43 | return TextStyle(fontSize: 12, color: color373D52);
44 | }
45 |
46 | static TextStyle get10TextA8ACBC() {
47 | return TextStyle(fontSize: 10, color: colorA8ACBC);
48 | }
49 |
50 | static TextStyle get15White() {
51 | return TextStyle(fontSize: 15, color: Colors.white);
52 | }
53 | }
54 |
55 | class PaddingStyles {
56 | static Padding getPadding(double padding) {
57 | return Padding(
58 | padding: EdgeInsets.only(
59 | top: 0, left: padding / 2, right: padding / 2, bottom: 0));
60 | }
61 | }
62 |
63 | class SizeBoxFactory {
64 | /// 垂直间距
65 | static SizedBox getVerticalSizeBox(double height) {
66 | return SizedBox(height: height);
67 | }
68 |
69 | /// 水平间隔
70 | static SizedBox getHorizontalSizeBox(double width) {
71 | return SizedBox(width: width);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/lib/app/route/fluro_navigator.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/app/route/routes.dart';
2 | import 'package:boohee_flutter/utils/base64_utils.dart';
3 | import 'package:fluro/fluro.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | import 'application.dart';
7 |
8 | /// fluro的路由跳转工具类
9 | class NavigatorUtils {
10 | static push(BuildContext context, String path,
11 | {bool replace = false, bool clearStack = false}) {
12 | Application.router.navigateTo(context, path,
13 | replace: replace,
14 | clearStack: clearStack,
15 | transition: TransitionType.native);
16 | }
17 |
18 | static pushResult(
19 | BuildContext context, String path, Function(Object) function,
20 | {bool replace = false, bool clearStack = false}) {
21 | Application.router
22 | .navigateTo(context, path,
23 | replace: replace,
24 | clearStack: clearStack,
25 | transition: TransitionType.native)
26 | .then((result) {
27 | // 页面返回result为null
28 | if (result == null) {
29 | return;
30 | }
31 | function(result);
32 | }).catchError((error) {
33 | print("$error");
34 | });
35 | }
36 |
37 | /// 返回
38 | static void goBack(BuildContext context) {
39 | Navigator.pop(context);
40 | }
41 |
42 | /// 通用的浏览器page
43 | static void goBrowserPage(BuildContext context, String url) {
44 | /// 这里使用替换/主要是路由不支持链接中带有/和&,否则会出错
45 | url = Base64.encodeBase64(url).replaceAll("/", "Chen*boohee");
46 | Application.router.navigateTo(context, '${Routes.webView}?web_url=$url',
47 | replace: false,
48 | clearStack: false,
49 | transition: TransitionType.inFromBottom);
50 | }
51 |
52 | /// 壁纸
53 | static void goWallPaper(BuildContext context, String imageUrl) {
54 | /// 这里使用替换/主要是路由不支持链接中带有/和&,否则会出错
55 | imageUrl = Base64.encodeBase64(imageUrl).replaceAll("/", "Chen*boohee");
56 | Application.router.navigateTo(
57 | context, '${Routes.wallPaper}?image_url=$imageUrl',
58 | replace: false,
59 | clearStack: false,
60 | transition: TransitionType.custom,
61 | transitionBuilder: Routes.transitionTopToBottom());
62 | }
63 |
64 | /// 带参数返回
65 | static void goBackWithParams(BuildContext context, result) {
66 | Navigator.pop(context, result);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lib/views/common/browser_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:boohee_flutter/common/colors.dart';
4 | import 'package:boohee_flutter/utils/base64_utils.dart';
5 | import 'package:flutter/cupertino.dart';
6 | import 'package:flutter/material.dart';
7 | import 'package:webview_flutter/webview_flutter.dart';
8 |
9 | class BrowserPage extends StatefulWidget {
10 | final String webViewUrl;
11 |
12 | BrowserPage( {this.webViewUrl});
13 |
14 | @override
15 | _BrowserPageState createState() => _BrowserPageState(webViewUrl);
16 | }
17 |
18 | class _BrowserPageState extends State {
19 | final Completer _controller =
20 | Completer();
21 | String webViewUrl;
22 | String title;
23 |
24 | _BrowserPageState(String url) {
25 | // 解析路由传递的参数
26 | webViewUrl = Base64.decodeBase64(url.replaceAll("Chen*boohee", "/"));
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return WillPopScope(
32 | child: Scaffold(
33 | appBar: AppBar(
34 | backgroundColor: mainColor,
35 | title: Text(title ?? "薄荷"),
36 | ),
37 | body: WebView(
38 | initialUrl: webViewUrl,
39 | javascriptMode: JavascriptMode.unrestricted,
40 | onWebViewCreated: (WebViewController webViewController) {
41 | _controller.complete(webViewController);
42 | },
43 | javascriptChannels: [
44 | _toasterJavascriptChannel(context),
45 | ].toSet(),
46 | onPageFinished: (String url) {},
47 | ),
48 | ),
49 | onWillPop: () async {
50 | var controller = await _controller.future;
51 | if (await controller.canGoBack()) {
52 | // 是否可以回退到上一步
53 | controller.goBack();
54 | return false;
55 | } else {
56 | return true;
57 | }
58 | });
59 | }
60 |
61 | JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
62 | return JavascriptChannel(
63 | name: 'Toaster',
64 | onMessageReceived: (JavascriptMessage message) {
65 | Scaffold.of(context).showSnackBar(
66 | SnackBar(content: Text(message.message)),
67 | );
68 | });
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/lib/views/discover_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/common/colors.dart';
2 | import 'package:boohee_flutter/views/discover/discover_child_page.dart';
3 | import 'package:boohee_flutter/widget/common_search_bar.dart';
4 | import 'package:boohee_flutter/widget/md2_tab_indicator.dart';
5 | import 'package:flutter/material.dart';
6 |
7 | class DiscoverPage extends StatefulWidget {
8 | @override
9 | State createState() => _DiscoverPageState();
10 | }
11 |
12 | class _DiscoverPageState extends State
13 | with SingleTickerProviderStateMixin {
14 | TabController _tabController;
15 | var mTabs = ["发现", "精选", "好友圈"];
16 |
17 | @override
18 | void initState() {
19 | super.initState();
20 | // 创建Controller
21 | _tabController = TabController(length: mTabs.length, vsync: this);
22 | _tabController.addListener(() {
23 | switch (_tabController.index) {
24 | }
25 | });
26 | }
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 | return Scaffold(
31 | appBar: SearchBar(
32 | text: "搜索动态、文章、话题、用户",
33 | ),
34 | body: DefaultTabController(
35 | length: mTabs.length,
36 | child: Column(
37 | crossAxisAlignment: CrossAxisAlignment.start,
38 | children: [
39 | TabBar(
40 | controller: _tabController,
41 | labelStyle:
42 | TextStyle(fontSize: 17, fontWeight: FontWeight.w700),
43 | indicatorSize: TabBarIndicatorSize.label,
44 | labelColor: mainColor,
45 | unselectedLabelColor: color373D52,
46 | isScrollable: true,
47 | indicator: MD2Indicator(
48 | indicatorHeight: 5,
49 | indicatorColor: mainColor,
50 | indicatorSize: MD2IndicatorSize.tiny,
51 | ),
52 | tabs: mTabs.map((e) => Tab(text: e)).toList(),
53 | ),
54 | Expanded(
55 | child: TabBarView(
56 | controller: _tabController,
57 | children: [
58 | DiscoverChildPage(),
59 | new Center(child: new Text('精选')),
60 | new Center(child: new Text('好友圈')),
61 | ],
62 | ))
63 | ],
64 | )),
65 | );
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/lib/widget/md2_tab_indicator.dart:
--------------------------------------------------------------------------------
1 | library md2_tab_indicator;
2 |
3 | import 'package:flutter/widgets.dart';
4 |
5 | enum MD2IndicatorSize {
6 | tiny,
7 | normal,
8 | full,
9 | }
10 |
11 | /// 自定义indicator
12 | class MD2Indicator extends Decoration {
13 | final double indicatorHeight;
14 | final Color indicatorColor;
15 | final MD2IndicatorSize indicatorSize;
16 |
17 | const MD2Indicator(
18 | {@required this.indicatorHeight,
19 | @required this.indicatorColor,
20 | @required this.indicatorSize});
21 |
22 | @override
23 | _MD2Painter createBoxPainter([VoidCallback onChanged]) {
24 | return new _MD2Painter(this, onChanged);
25 | }
26 | }
27 |
28 | class _MD2Painter extends BoxPainter {
29 | final MD2Indicator decoration;
30 |
31 | _MD2Painter(this.decoration, VoidCallback onChanged)
32 | : assert(decoration != null),
33 | super(onChanged);
34 |
35 | @override
36 | void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
37 | assert(configuration != null);
38 | assert(configuration.size != null);
39 |
40 | Rect rect;
41 | if (decoration.indicatorSize == MD2IndicatorSize.full) {
42 | rect = Offset(offset.dx,
43 | (configuration.size.height - decoration.indicatorHeight ?? 3)) &
44 | Size(configuration.size.width, decoration.indicatorHeight ?? 3);
45 | } else if (decoration.indicatorSize == MD2IndicatorSize.normal) {
46 | rect = Offset(offset.dx + 6,
47 | (configuration.size.height - decoration.indicatorHeight ?? 3)) &
48 | Size(configuration.size.width - 12, decoration.indicatorHeight ?? 3);
49 | } else if (decoration.indicatorSize == MD2IndicatorSize.tiny) {
50 | rect = Offset(
51 | offset.dx + configuration.size.width / 2 - 8,
52 | (configuration.size.height - decoration.indicatorHeight - 5 ??
53 | 3)) &
54 | Size(12, decoration.indicatorHeight ?? 3);
55 | }
56 |
57 | final Paint paint = Paint();
58 | paint.color = decoration.indicatorColor ?? Color(0xff1967d2);
59 | paint.style = PaintingStyle.fill;
60 | canvas.drawRRect(
61 | RRect.fromRectAndCorners(rect,
62 | topRight: Radius.circular(8),
63 | topLeft: Radius.circular(8),
64 | bottomRight: Radius.circular(8),
65 | bottomLeft: Radius.circular(8)),
66 | paint);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/widget/header/home_wallpaper_header.dart:
--------------------------------------------------------------------------------
1 | import 'package:extended_image/extended_image.dart';
2 | import 'package:flutter/cupertino.dart';
3 | import 'package:flutter/src/painting/basic_types.dart';
4 | import 'package:flutter/src/widgets/framework.dart';
5 | import 'package:flutter_easyrefresh/easy_refresh.dart';
6 |
7 | class WallPaperHeader extends Header {
8 | final Key key;
9 | final String wallPaperUrl;
10 |
11 | final LinkHeaderNotifier linkNotifier = LinkHeaderNotifier();
12 |
13 | WallPaperHeader({
14 | this.key,
15 | this.wallPaperUrl,
16 | bool enableHapticFeedback = false,
17 | }) : super(
18 | extent: 120,
19 | triggerDistance: 120,
20 | float: false,
21 | enableHapticFeedback: enableHapticFeedback,
22 | enableInfiniteRefresh: false,
23 | );
24 |
25 | @override
26 | Widget contentBuilder(
27 | BuildContext context,
28 | RefreshMode refreshState,
29 | double pulledExtent,
30 | double refreshTriggerPullDistance,
31 | double refreshIndicatorExtent,
32 | AxisDirection axisDirection,
33 | bool float,
34 | Duration completeDuration,
35 | bool enableInfiniteRefresh,
36 | bool success,
37 | bool noMore) {
38 | linkNotifier.contentBuilder(
39 | context,
40 | refreshState,
41 | pulledExtent,
42 | refreshTriggerPullDistance,
43 | refreshIndicatorExtent,
44 | axisDirection,
45 | float,
46 | completeDuration,
47 | enableInfiniteRefresh,
48 | success,
49 | noMore);
50 |
51 | return WallPaperHeaderPage(
52 | wallPaperUrl: wallPaperUrl,
53 | linkNotifier: linkNotifier,
54 | key: key,
55 | );
56 | }
57 | }
58 |
59 | class WallPaperHeaderPage extends StatefulWidget {
60 | final String wallPaperUrl;
61 | final LinkHeaderNotifier linkNotifier;
62 |
63 | WallPaperHeaderPage({this.wallPaperUrl, Key key, this.linkNotifier})
64 | : super(key: key);
65 |
66 | @override
67 | _WallPaperHeaderPageState createState() => _WallPaperHeaderPageState();
68 | }
69 |
70 | class _WallPaperHeaderPageState extends State {
71 | RefreshMode get _refreshState => widget.linkNotifier.refreshState;
72 |
73 | double get _pulledExtent => widget.linkNotifier.pulledExtent;
74 |
75 | double get _indicatorExtent => widget.linkNotifier.refreshIndicatorExtent;
76 |
77 | @override
78 | Widget build(BuildContext context) {
79 | return ExtendedImage.network(
80 | widget.wallPaperUrl,
81 | cache: true,
82 | fit: BoxFit.fitWidth,
83 | );
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/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 | def keystorePropertiesFile = rootProject.file("key.properties")
29 | def keystoreProperties = new Properties()
30 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
31 |
32 | android {
33 | compileSdkVersion 28
34 |
35 | sourceSets {
36 | main.java.srcDirs += 'src/main/kotlin'
37 | }
38 |
39 | lintOptions {
40 | disable 'InvalidPackage'
41 | }
42 |
43 | defaultConfig {
44 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
45 | applicationId "com.boohee.one.boohee_flutter"
46 | minSdkVersion 16
47 | targetSdkVersion 28
48 | versionCode flutterVersionCode.toInteger()
49 | versionName flutterVersionName
50 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
51 | }
52 |
53 | signingConfigs {
54 | release {
55 | keyAlias keystoreProperties['keyAlias']
56 | keyPassword keystoreProperties['keyPassword']
57 | storePassword keystoreProperties['storePassword']
58 | // 适配不同os上需要配置不同的jks的路径
59 | storeFile file("../minic_applicaion.jks")
60 | }
61 | }
62 | buildTypes {
63 | release {
64 | signingConfig signingConfigs.release
65 | }
66 | }
67 | }
68 |
69 | flutter {
70 | source '../..'
71 | }
72 |
73 | dependencies {
74 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
75 | testImplementation 'junit:junit:4.12'
76 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
77 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
78 | }
79 |
--------------------------------------------------------------------------------
/lib/model/discover/sub_discover.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'sub_discover.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class SubDiscover extends Object {
8 |
9 | @JsonKey(name: 'banners')
10 | List banners;
11 |
12 | @JsonKey(name: 'labels')
13 | List labels;
14 |
15 | @JsonKey(name: 'sections')
16 | List sections;
17 |
18 | SubDiscover(this.banners,this.labels,this.sections,);
19 |
20 | factory SubDiscover.fromJson(Map srcJson) => _$SubDiscoverFromJson(srcJson);
21 |
22 | Map toJson() => _$SubDiscoverToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Banners extends Object {
29 |
30 | @JsonKey(name: 'id')
31 | int id;
32 |
33 | @JsonKey(name: 'title')
34 | String title;
35 |
36 | @JsonKey(name: 'link')
37 | String link;
38 |
39 | @JsonKey(name: 'pic_url')
40 | String picUrl;
41 |
42 | Banners(this.id,this.title,this.link,this.picUrl,);
43 |
44 | factory Banners.fromJson(Map srcJson) => _$BannersFromJson(srcJson);
45 |
46 | Map toJson() => _$BannersToJson(this);
47 |
48 | }
49 |
50 |
51 | @JsonSerializable()
52 | class Labels extends Object {
53 |
54 | @JsonKey(name: 'title')
55 | String title;
56 |
57 | @JsonKey(name: 'url')
58 | String url;
59 |
60 | @JsonKey(name: 'pic_url')
61 | String picUrl;
62 |
63 | Labels(this.title,this.url,this.picUrl,);
64 |
65 | factory Labels.fromJson(Map srcJson) => _$LabelsFromJson(srcJson);
66 |
67 | Map toJson() => _$LabelsToJson(this);
68 |
69 | }
70 |
71 |
72 | @JsonSerializable()
73 | class Sections extends Object {
74 |
75 | @JsonKey(name: 'name')
76 | String name;
77 |
78 | @JsonKey(name: 'sub_contents')
79 | List subContents;
80 |
81 | Sections(this.name,this.subContents,);
82 |
83 | factory Sections.fromJson(Map srcJson) => _$SectionsFromJson(srcJson);
84 |
85 | Map toJson() => _$SectionsToJson(this);
86 |
87 | }
88 |
89 |
90 | @JsonSerializable()
91 | class Sub_contents extends Object {
92 |
93 | @JsonKey(name: 'title')
94 | String title;
95 |
96 | @JsonKey(name: 'sub_title')
97 | String subTitle;
98 |
99 | @JsonKey(name: 'img_url')
100 | String imgUrl;
101 |
102 | @JsonKey(name: 'redirect_url')
103 | String redirectUrl;
104 |
105 | Sub_contents(this.title,this.subTitle,this.imgUrl,this.redirectUrl,);
106 |
107 | factory Sub_contents.fromJson(Map srcJson) => _$Sub_contentsFromJson(srcJson);
108 |
109 | Map toJson() => _$Sub_contentsToJson(this);
110 |
111 | }
112 |
113 |
114 |
--------------------------------------------------------------------------------
/lib/model/ShopRecommendList.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'ShopRecommendList.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class ShopRecommendList extends Object {
8 |
9 | @JsonKey(name: 'id')
10 | int id;
11 |
12 | @JsonKey(name: 'name')
13 | String name;
14 |
15 | @JsonKey(name: 'description')
16 | String description;
17 |
18 | @JsonKey(name: 'sub_labels')
19 | List subLabels;
20 |
21 | @JsonKey(name: 'banner_showcases')
22 | List bannerShowcases;
23 |
24 | @JsonKey(name: 'goods')
25 | List goods;
26 |
27 | @JsonKey(name: 'page')
28 | int page;
29 |
30 | @JsonKey(name: 'total_pages')
31 | int totalPages;
32 |
33 | ShopRecommendList(this.id,this.name,this.description,this.subLabels,this.bannerShowcases,this.goods,this.page,this.totalPages,);
34 |
35 | factory ShopRecommendList.fromJson(Map srcJson) => _$ShopRecommendListFromJson(srcJson);
36 |
37 | Map toJson() => _$ShopRecommendListToJson(this);
38 |
39 | }
40 |
41 |
42 | @JsonSerializable()
43 | class Sub_labels extends Object {
44 |
45 | @JsonKey(name: 'id')
46 | int id;
47 |
48 | @JsonKey(name: 'name')
49 | String name;
50 |
51 | Sub_labels(this.id,this.name,);
52 |
53 | factory Sub_labels.fromJson(Map srcJson) => _$Sub_labelsFromJson(srcJson);
54 |
55 | Map toJson() => _$Sub_labelsToJson(this);
56 |
57 | }
58 |
59 |
60 | @JsonSerializable()
61 | class Goods extends Object {
62 |
63 | @JsonKey(name: 'id')
64 | int id;
65 |
66 | @JsonKey(name: 'title')
67 | String title;
68 |
69 | @JsonKey(name: 'total_quantity')
70 | int totalQuantity;
71 |
72 | @JsonKey(name: 'category_name')
73 | String categoryName;
74 |
75 | @JsonKey(name: 'thumb_photo_url')
76 | String thumbPhotoUrl;
77 |
78 | @JsonKey(name: 'big_photo_url')
79 | String bigPhotoUrl;
80 |
81 | @JsonKey(name: 'flag_url')
82 | String flagUrl;
83 |
84 | @JsonKey(name: 'flag_name')
85 | String flagName;
86 |
87 | @JsonKey(name: 'state')
88 | String state;
89 |
90 | @JsonKey(name: 'buy_url')
91 | String buyUrl;
92 |
93 | @JsonKey(name: 'has_video_thumb')
94 | bool hasVideoThumb;
95 |
96 | @JsonKey(name: 'base_price')
97 | int basePrice;
98 |
99 | @JsonKey(name: 'market_price')
100 | int marketPrice;
101 |
102 | Goods(this.id,this.title,this.totalQuantity,this.categoryName,this.thumbPhotoUrl,this.bigPhotoUrl,this.flagUrl,this.flagName,this.state,this.buyUrl,this.hasVideoThumb,this.basePrice,this.marketPrice,);
103 |
104 | factory Goods.fromJson(Map srcJson) => _$GoodsFromJson(srcJson);
105 |
106 | Map toJson() => _$GoodsToJson(this);
107 |
108 | }
109 |
110 |
111 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "icon_20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "icon_20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon_29@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "icon_29@3x.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "icon_40@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "icon_40@3x.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "icon_60@2x.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "icon_60@3x.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "20x20",
53 | "idiom" : "ipad",
54 | "filename" : "icon_20@1x.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "icon_20@2x-1.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "29x29",
65 | "idiom" : "ipad",
66 | "filename" : "icon_29@1x.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "icon_29@2x-1.png",
73 | "scale" : "2x"
74 | },
75 | {
76 | "size" : "40x40",
77 | "idiom" : "ipad",
78 | "filename" : "icon_40@1x.png",
79 | "scale" : "1x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "icon_40@2x-1.png",
85 | "scale" : "2x"
86 | },
87 | {
88 | "size" : "76x76",
89 | "idiom" : "ipad",
90 | "filename" : "icon_76@1x.png",
91 | "scale" : "1x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "icon_76@2x.png",
97 | "scale" : "2x"
98 | },
99 | {
100 | "size" : "83.5x83.5",
101 | "idiom" : "ipad",
102 | "filename" : "icon_83.5@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "1024x1024",
107 | "idiom" : "ios-marketing",
108 | "filename" : "icon_1024.png",
109 | "scale" : "1x"
110 | }
111 | ],
112 | "info" : {
113 | "version" : 1,
114 | "author" : "xcode"
115 | }
116 | }
--------------------------------------------------------------------------------
/lib/model/ShopRecommendList.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'ShopRecommendList.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | ShopRecommendList _$ShopRecommendListFromJson(Map json) {
10 | return ShopRecommendList(
11 | json['id'] as int,
12 | json['name'] as String,
13 | json['description'] as String,
14 | (json['sub_labels'] as List)
15 | ?.map((e) =>
16 | e == null ? null : Sub_labels.fromJson(e as Map))
17 | ?.toList(),
18 | json['banner_showcases'] as List,
19 | (json['goods'] as List)
20 | ?.map(
21 | (e) => e == null ? null : Goods.fromJson(e as Map))
22 | ?.toList(),
23 | json['page'] as int,
24 | json['total_pages'] as int,
25 | );
26 | }
27 |
28 | Map _$ShopRecommendListToJson(ShopRecommendList instance) =>
29 | {
30 | 'id': instance.id,
31 | 'name': instance.name,
32 | 'description': instance.description,
33 | 'sub_labels': instance.subLabels,
34 | 'banner_showcases': instance.bannerShowcases,
35 | 'goods': instance.goods,
36 | 'page': instance.page,
37 | 'total_pages': instance.totalPages,
38 | };
39 |
40 | Sub_labels _$Sub_labelsFromJson(Map json) {
41 | return Sub_labels(
42 | json['id'] as int,
43 | json['name'] as String,
44 | );
45 | }
46 |
47 | Map _$Sub_labelsToJson(Sub_labels instance) =>
48 | {
49 | 'id': instance.id,
50 | 'name': instance.name,
51 | };
52 |
53 | Goods _$GoodsFromJson(Map json) {
54 | return Goods(
55 | json['id'] as int,
56 | json['title'] as String,
57 | json['total_quantity'] as int,
58 | json['category_name'] as String,
59 | json['thumb_photo_url'] as String,
60 | json['big_photo_url'] as String,
61 | json['flag_url'] as String,
62 | json['flag_name'] as String,
63 | json['state'] as String,
64 | json['buy_url'] as String,
65 | json['has_video_thumb'] as bool,
66 | json['base_price'] as int,
67 | json['market_price'] as int,
68 | );
69 | }
70 |
71 | Map _$GoodsToJson(Goods instance) => {
72 | 'id': instance.id,
73 | 'title': instance.title,
74 | 'total_quantity': instance.totalQuantity,
75 | 'category_name': instance.categoryName,
76 | 'thumb_photo_url': instance.thumbPhotoUrl,
77 | 'big_photo_url': instance.bigPhotoUrl,
78 | 'flag_url': instance.flagUrl,
79 | 'flag_name': instance.flagName,
80 | 'state': instance.state,
81 | 'buy_url': instance.buyUrl,
82 | 'has_video_thumb': instance.hasVideoThumb,
83 | 'base_price': instance.basePrice,
84 | 'market_price': instance.marketPrice,
85 | };
86 |
--------------------------------------------------------------------------------
/assets/json/home/home_wallpaper.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "welcome_img": {
4 | "hello_text": "我的目标就在下个路口 现在要做的就是加点油门",
5 | "back_img": "http://up.boohee.cn/house/u/one/wallpaper/1664_big.jpg",
6 | "back_img_small": "http://up.boohee.cn/house/u/one/wallpaper/1664_small.jpg",
7 | "back_img_x": "http://up.boohee.cn/house/u/one/wallpaper/1664_x.jpg",
8 | "video_url": "",
9 | "link": "",
10 | "date": "2019-08-17"
11 | }
12 | },
13 | {
14 | "welcome_img": {
15 | "hello_text": "我的目标就在下个路口 现在要做的就是加点油门",
16 | "back_img": "http://up.boohee.cn/house/u/one/wallpaper/1665_big.jpg",
17 | "back_img_small": "http://up.boohee.cn/house/u/one/wallpaper/1665_small.jpg",
18 | "back_img_x": "http://up.boohee.cn/house/u/one/wallpaper/1665_x.jpg",
19 | "video_url": "",
20 | "link": "",
21 | "date": "2019-08-17"
22 | }
23 | },
24 | {
25 | "welcome_img": {
26 | "hello_text": "我的目标就在下个路口 现在要做的就是加点油门",
27 | "back_img": "http://up.boohee.cn/house/u/one/wallpaper/1666_big.jpg",
28 | "back_img_small": "http://up.boohee.cn/house/u/one/wallpaper/1666_small.jpg",
29 | "back_img_x": "http://up.boohee.cn/house/u/one/wallpaper/1666_x.jpg",
30 | "video_url": "",
31 | "link": "",
32 | "date": "2019-08-17"
33 | }
34 | },
35 | {
36 | "welcome_img": {
37 | "hello_text": "我的目标就在下个路口 现在要做的就是加点油门",
38 | "back_img": "http://up.boohee.cn/house/u/one/wallpaper/1667_big.jpg",
39 | "back_img_small": "http://up.boohee.cn/house/u/one/wallpaper/1667_small.jpg",
40 | "back_img_x": "http://up.boohee.cn/house/u/one/wallpaper/1667_x.jpg",
41 | "video_url": "",
42 | "link": "",
43 | "date": "2019-08-17"
44 | }
45 | },
46 | {
47 | "welcome_img": {
48 | "hello_text": "我的目标就在下个路口 现在要做的就是加点油门",
49 | "back_img": "http://up.boohee.cn/house/u/one/wallpaper/1668_big.jpg",
50 | "back_img_small": "http://up.boohee.cn/house/u/one/wallpaper/1668_small.jpg",
51 | "back_img_x": "http://up.boohee.cn/house/u/one/wallpaper/1668_x.jpg",
52 | "video_url": "",
53 | "link": "",
54 | "date": "2019-08-17"
55 | }
56 | },
57 | {
58 | "welcome_img": {
59 | "hello_text": "我的目标就在下个路口 现在要做的就是加点油门",
60 | "back_img": "http://up.boohee.cn/house/u/one/wallpaper/1669_big.jpg",
61 | "back_img_small": "http://up.boohee.cn/house/u/one/wallpaper/1669_small.jpg",
62 | "back_img_x": "http://up.boohee.cn/house/u/one/wallpaper/1669_x.jpg",
63 | "video_url": "",
64 | "link": "",
65 | "date": "2019-08-17"
66 | }
67 | },
68 | {
69 | "welcome_img": {
70 | "hello_text": "我的目标就在下个路口 现在要做的就是加点油门",
71 | "back_img": "http://up.boohee.cn/house/u/one/wallpaper/1671_big.jpg",
72 | "back_img_small": "http://up.boohee.cn/house/u/one/wallpaper/1671_small.jpg",
73 | "back_img_x": "http://up.boohee.cn/house/u/one/wallpaper/1671_x.jpg",
74 | "video_url": "",
75 | "link": "",
76 | "date": "2019-08-17"
77 | }
78 | }
79 | ]
--------------------------------------------------------------------------------
/lib/model/discover/sub_discover.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'sub_discover.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | SubDiscover _$SubDiscoverFromJson(Map json) {
10 | return SubDiscover(
11 | (json['banners'] as List)
12 | ?.map((e) =>
13 | e == null ? null : Banners.fromJson(e as Map))
14 | ?.toList(),
15 | (json['labels'] as List)
16 | ?.map((e) =>
17 | e == null ? null : Labels.fromJson(e as Map))
18 | ?.toList(),
19 | (json['sections'] as List)
20 | ?.map((e) =>
21 | e == null ? null : Sections.fromJson(e as Map))
22 | ?.toList(),
23 | );
24 | }
25 |
26 | Map _$SubDiscoverToJson(SubDiscover instance) =>
27 | {
28 | 'banners': instance.banners,
29 | 'labels': instance.labels,
30 | 'sections': instance.sections,
31 | };
32 |
33 | Banners _$BannersFromJson(Map json) {
34 | return Banners(
35 | json['id'] as int,
36 | json['title'] as String,
37 | json['link'] as String,
38 | json['pic_url'] as String,
39 | );
40 | }
41 |
42 | Map _$BannersToJson(Banners instance) => {
43 | 'id': instance.id,
44 | 'title': instance.title,
45 | 'link': instance.link,
46 | 'pic_url': instance.picUrl,
47 | };
48 |
49 | Labels _$LabelsFromJson(Map json) {
50 | return Labels(
51 | json['title'] as String,
52 | json['url'] as String,
53 | json['pic_url'] as String,
54 | );
55 | }
56 |
57 | Map _$LabelsToJson(Labels instance) => {
58 | 'title': instance.title,
59 | 'url': instance.url,
60 | 'pic_url': instance.picUrl,
61 | };
62 |
63 | Sections _$SectionsFromJson(Map json) {
64 | return Sections(
65 | json['name'] as String,
66 | (json['sub_contents'] as List)
67 | ?.map((e) =>
68 | e == null ? null : Sub_contents.fromJson(e as Map))
69 | ?.toList(),
70 | );
71 | }
72 |
73 | Map _$SectionsToJson(Sections instance) => {
74 | 'name': instance.name,
75 | 'sub_contents': instance.subContents,
76 | };
77 |
78 | Sub_contents _$Sub_contentsFromJson(Map json) {
79 | return Sub_contents(
80 | json['title'] as String,
81 | json['sub_title'] as String,
82 | json['img_url'] as String,
83 | json['redirect_url'] as String,
84 | );
85 | }
86 |
87 | Map _$Sub_contentsToJson(Sub_contents instance) =>
88 | {
89 | 'title': instance.title,
90 | 'sub_title': instance.subTitle,
91 | 'img_url': instance.imgUrl,
92 | 'redirect_url': instance.redirectUrl,
93 | };
94 |
--------------------------------------------------------------------------------
/lib/model/ShopBanner.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'ShopBanner.g.dart';
4 |
5 |
6 | @JsonSerializable()
7 | class ShopBanner extends Object {
8 |
9 | @JsonKey(name: 'banner_showcases')
10 | List bannerShowcases;
11 |
12 | @JsonKey(name: 'shop_modules')
13 | List shopModules;
14 |
15 | @JsonKey(name: 'categories')
16 | List categories;
17 |
18 | ShopBanner(this.bannerShowcases,this.shopModules,this.categories,);
19 |
20 | factory ShopBanner.fromJson(Map srcJson) => _$ShopBannerFromJson(srcJson);
21 |
22 | Map toJson() => _$ShopBannerToJson(this);
23 |
24 | }
25 |
26 |
27 | @JsonSerializable()
28 | class Banner_showcases extends Object {
29 |
30 | @JsonKey(name: 'id')
31 | int id;
32 |
33 | @JsonKey(name: 'exhibit')
34 | String exhibit;
35 |
36 | @JsonKey(name: 'default_photo_url')
37 | String defaultPhotoUrl;
38 |
39 | @JsonKey(name: 'default_photo_height')
40 | int defaultPhotoHeight;
41 |
42 | @JsonKey(name: 'default_photo_width')
43 | int defaultPhotoWidth;
44 |
45 | @JsonKey(name: 'exhibit_type')
46 | String exhibitType;
47 |
48 | @JsonKey(name: 'page_title')
49 | String pageTitle;
50 |
51 | Banner_showcases(this.id,this.exhibit,this.defaultPhotoUrl,this.defaultPhotoHeight,this.defaultPhotoWidth,this.exhibitType,this.pageTitle,);
52 |
53 | factory Banner_showcases.fromJson(Map srcJson) => _$Banner_showcasesFromJson(srcJson);
54 |
55 | Map toJson() => _$Banner_showcasesToJson(this);
56 |
57 | }
58 |
59 |
60 | @JsonSerializable()
61 | class Shop_modules extends Object {
62 |
63 | @JsonKey(name: 'position')
64 | int position;
65 |
66 | @JsonKey(name: 'title')
67 | String title;
68 |
69 | @JsonKey(name: 'sub_title')
70 | String subTitle;
71 |
72 | @JsonKey(name: 'picture_url1')
73 | String pictureUrl1;
74 |
75 | @JsonKey(name: 'picture_url2')
76 | String pictureUrl2;
77 |
78 | @JsonKey(name: 'redirect_url')
79 | String redirectUrl;
80 |
81 | @JsonKey(name: 'display')
82 | bool display;
83 |
84 | @JsonKey(name: 'new_tag')
85 | String newTag;
86 |
87 | Shop_modules(this.position,this.title,this.subTitle,this.pictureUrl1,this.pictureUrl2,this.redirectUrl,this.display,this.newTag,);
88 |
89 | factory Shop_modules.fromJson(Map srcJson) => _$Shop_modulesFromJson(srcJson);
90 |
91 | Map toJson() => _$Shop_modulesToJson(this);
92 |
93 | }
94 |
95 |
96 | @JsonSerializable()
97 | class Categories extends Object {
98 |
99 | @JsonKey(name: 'id')
100 | int id;
101 |
102 | @JsonKey(name: 'name')
103 | String name;
104 |
105 | @JsonKey(name: 'description')
106 | String description;
107 |
108 | @JsonKey(name: 'icon_url')
109 | String iconUrl;
110 |
111 | Categories(this.id,this.name,this.description,this.iconUrl,);
112 |
113 | factory Categories.fromJson(Map srcJson) => _$CategoriesFromJson(srcJson);
114 |
115 | Map toJson() => _$CategoriesToJson(this);
116 |
117 | }
118 |
119 |
120 |
--------------------------------------------------------------------------------
/lib/model/ShopBanner.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'ShopBanner.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | ShopBanner _$ShopBannerFromJson(Map json) {
10 | return ShopBanner(
11 | (json['banner_showcases'] as List)
12 | ?.map((e) => e == null
13 | ? null
14 | : Banner_showcases.fromJson(e as Map))
15 | ?.toList(),
16 | (json['shop_modules'] as List)
17 | ?.map((e) =>
18 | e == null ? null : Shop_modules.fromJson(e as Map))
19 | ?.toList(),
20 | (json['categories'] as List)
21 | ?.map((e) =>
22 | e == null ? null : Categories.fromJson(e as Map))
23 | ?.toList(),
24 | );
25 | }
26 |
27 | Map _$ShopBannerToJson(ShopBanner instance) =>
28 | {
29 | 'banner_showcases': instance.bannerShowcases,
30 | 'shop_modules': instance.shopModules,
31 | 'categories': instance.categories,
32 | };
33 |
34 | Banner_showcases _$Banner_showcasesFromJson(Map json) {
35 | return Banner_showcases(
36 | json['id'] as int,
37 | json['exhibit'] as String,
38 | json['default_photo_url'] as String,
39 | json['default_photo_height'] as int,
40 | json['default_photo_width'] as int,
41 | json['exhibit_type'] as String,
42 | json['page_title'] as String,
43 | );
44 | }
45 |
46 | Map _$Banner_showcasesToJson(Banner_showcases instance) =>
47 | {
48 | 'id': instance.id,
49 | 'exhibit': instance.exhibit,
50 | 'default_photo_url': instance.defaultPhotoUrl,
51 | 'default_photo_height': instance.defaultPhotoHeight,
52 | 'default_photo_width': instance.defaultPhotoWidth,
53 | 'exhibit_type': instance.exhibitType,
54 | 'page_title': instance.pageTitle,
55 | };
56 |
57 | Shop_modules _$Shop_modulesFromJson(Map json) {
58 | return Shop_modules(
59 | json['position'] as int,
60 | json['title'] as String,
61 | json['sub_title'] as String,
62 | json['picture_url1'] as String,
63 | json['picture_url2'] as String,
64 | json['redirect_url'] as String,
65 | json['display'] as bool,
66 | json['new_tag'] as String,
67 | );
68 | }
69 |
70 | Map _$Shop_modulesToJson(Shop_modules instance) =>
71 | {
72 | 'position': instance.position,
73 | 'title': instance.title,
74 | 'sub_title': instance.subTitle,
75 | 'picture_url1': instance.pictureUrl1,
76 | 'picture_url2': instance.pictureUrl2,
77 | 'redirect_url': instance.redirectUrl,
78 | 'display': instance.display,
79 | 'new_tag': instance.newTag,
80 | };
81 |
82 | Categories _$CategoriesFromJson(Map json) {
83 | return Categories(
84 | json['id'] as int,
85 | json['name'] as String,
86 | json['description'] as String,
87 | json['icon_url'] as String,
88 | );
89 | }
90 |
91 | Map _$CategoriesToJson(Categories instance) =>
92 | {
93 | 'id': instance.id,
94 | 'name': instance.name,
95 | 'description': instance.description,
96 | 'icon_url': instance.iconUrl,
97 | };
98 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/lib/views/main_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/common/colors.dart';
2 | import 'package:boohee_flutter/utils/toast_utils.dart';
3 | import 'package:boohee_flutter/views/shop_pages/shop_page.dart';
4 | import 'package:flutter/material.dart';
5 |
6 | import 'discover_page.dart';
7 | import 'home_page.dart';
8 | import 'mine_page.dart';
9 |
10 | class MainPage extends StatefulWidget {
11 | @override
12 | State createState() => _MainPageState();
13 | }
14 |
15 | class _MainPageState extends State
16 | with SingleTickerProviderStateMixin {
17 | DateTime _lastPressedAt; //上次点击时间
18 |
19 | int _selectedIndex = 0;
20 | List _list = List();
21 | List _selectIcon = [
22 | Image.asset(
23 | "images/ic_tab_bar_home_green.png",
24 | width: 22,
25 | height: 22,
26 | ),
27 | Image.asset(
28 | "images/ic_tab_bar_partner_green.png",
29 | width: 22,
30 | height: 22,
31 | ),
32 | Image.asset(
33 | "images/ic_home_tabbar_plus.png",
34 | width: 36,
35 | height: 36,
36 | ),
37 | Image.asset(
38 | "images/ic_tab_bar_shop_green.png",
39 | width: 22,
40 | height: 22,
41 | ),
42 | Image.asset(
43 | "images/ic_tab_bar_me_green.png",
44 | width: 22,
45 | height: 22,
46 | ),
47 | ];
48 | List _unselectIcon = [
49 | Image.asset(
50 | "images/ic_tab_bar_home_grey.png",
51 | width: 22,
52 | height: 22,
53 | ),
54 | Image.asset(
55 | "images/ic_tab_bar_partner_grey.png",
56 | width: 22,
57 | height: 22,
58 | ),
59 | Image.asset(
60 | "images/ic_home_tabbar_plus.png",
61 | width: 36,
62 | height: 36,
63 | ),
64 | Image.asset(
65 | "images/ic_tab_bar_shop_grey.png",
66 | width: 22,
67 | height: 22,
68 | ),
69 | Image.asset(
70 | "images/ic_tab_bar_me_grey.png",
71 | width: 22,
72 | height: 22,
73 | ),
74 | ];
75 | static List tabData = [
76 | "首页",
77 | "伙伴",
78 | "",
79 | "商店",
80 | "我",
81 | ];
82 | List _myTabs = [];
83 |
84 | @override
85 | void initState() {
86 | super.initState();
87 | for (int i = 0; i < tabData.length; i++) {
88 | // 初始化底部Tab
89 | _myTabs.add(BottomNavigationBarItem(
90 | icon: _unselectIcon[i],
91 | activeIcon: _selectIcon[i],
92 | title: Text(
93 | tabData[i],
94 | ),
95 | ));
96 | }
97 | _list
98 | ..add(HomePage())
99 | ..add(DiscoverPage())
100 | ..add(ShopPage())
101 | ..add(MinePage());
102 | }
103 |
104 | @override
105 | void dispose() {
106 | super.dispose();
107 | }
108 |
109 | @override
110 | Widget build(BuildContext context) {
111 | return WillPopScope(
112 | child: Scaffold(
113 | body: IndexedStack(
114 | // --是因为页面只有4个,但是底部tab的index是5个导致tab索引混乱
115 | index: _selectedIndex > 2 ? _selectedIndex - 1 : _selectedIndex,
116 | children: _list,
117 | ),
118 | bottomNavigationBar: BottomNavigationBar(
119 | selectedFontSize: 10,
120 | unselectedFontSize: 10,
121 | backgroundColor: Colors.white,
122 | items: _myTabs,
123 | currentIndex: _selectedIndex,
124 | onTap: _onItemTapped,
125 | type: BottomNavigationBarType.fixed,
126 | fixedColor: mainColor,
127 | ),
128 | ),
129 | onWillPop: () async {
130 | if (_lastPressedAt == null ||
131 | DateTime.now().difference(_lastPressedAt) >
132 | Duration(seconds: 2)) {
133 | //两次点击间隔超过1秒则重新计时
134 | _lastPressedAt = DateTime.now();
135 | ToastUtils.showToast(context, "再按一次返回退出APP");
136 | return false;
137 | }
138 | return true;
139 | });
140 | }
141 |
142 | // 导航tab 点击回调
143 | void _onItemTapped(int index) {
144 | if (index == 2) {
145 | ToastUtils.showToast(context, "暂无");
146 | return;
147 | }
148 | // 刷新widget
149 | setState(() {
150 | _selectedIndex = index;
151 | });
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/lib/widget/common_search_bar.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/common/colors.dart';
2 | import 'package:boohee_flutter/res/styles.dart';
3 | import 'package:boohee_flutter/utils/utils.dart';
4 | import 'package:flustars/flustars.dart';
5 | import 'package:flutter/material.dart';
6 |
7 | /// 通用的搜索头部Widget
8 | class SearchBar extends StatefulWidget implements PreferredSizeWidget {
9 | final Key key;
10 | final Function onPressed;
11 | final String text;
12 | final bool isShowCartIcon;
13 | final SearchBarController controller;
14 |
15 | SearchBar(
16 | {this.onPressed,
17 | this.controller,
18 | this.key,
19 | this.isShowCartIcon: false,
20 | @required this.text})
21 | : super(key: key);
22 |
23 | @override
24 | SearchBarState createState() => SearchBarState();
25 |
26 | @override
27 | Size get preferredSize => Size.fromHeight(200);
28 | }
29 |
30 | class SearchBarState extends State {
31 | SearchBarController _controller;
32 |
33 | @override
34 | Widget build(BuildContext context) {
35 | if (widget.controller == null) {
36 | _controller = new SearchBarController();
37 | _controller.value.alpha = 255;
38 | _controller.value.searchBarBg = color0EB794;
39 | _controller.value.appbarTitleColor = Colors.white;
40 | _controller.value.appbarLeftIcon = "ic_search_white";
41 | _controller.value.appbarRightIcon = "ic_message_white";
42 | } else {
43 | _controller = widget.controller;
44 | }
45 | return Container(
46 | color: Color.fromARGB(_controller.value.alpha, 0, 205, 162),
47 | padding: EdgeInsets.only(
48 | left: 17,
49 | right: 17,
50 | top: ScreenUtil.getStatusBarH(context) + 17,
51 | bottom: 17),
52 | child: Row(
53 | children: [
54 | Expanded(
55 | child: Container(
56 | child: DecoratedBox(
57 | decoration: BoxDecoration(
58 | color: _controller.value.searchBarBg,
59 | borderRadius: BorderRadius.circular(100),
60 | ),
61 | child: Padding(
62 | padding: EdgeInsets.only(top: 7, bottom: 7),
63 | child: Row(
64 | children: [
65 | PaddingStyles.getPadding(14),
66 | Image.asset(
67 | Utils.getImgPath(_controller.value.appbarLeftIcon),
68 | width: 24,
69 | height: 24,
70 | ),
71 | PaddingStyles.getPadding(7),
72 | Text(
73 | widget.text,
74 | style: TextStyle(
75 | fontSize: 14,
76 | color: _controller.value.appbarTitleColor),
77 | )
78 | ],
79 | ),
80 | ),
81 | ),
82 | )),
83 | Offstage(
84 | child: SizeBoxFactory.getHorizontalSizeBox(14),
85 | offstage: !widget.isShowCartIcon,
86 | ),
87 | Offstage(
88 | offstage: !widget.isShowCartIcon,
89 | child: Image.asset(
90 | Utils.getImgPath("ic_shop_cart_white"),
91 | width: 24,
92 | height: 24,
93 | ),
94 | ),
95 | SizeBoxFactory.getHorizontalSizeBox(14),
96 | Image.asset(
97 | Utils.getImgPath(_controller.value.appbarRightIcon),
98 | width: 24,
99 | height: 24,
100 | )
101 | ],
102 | ),
103 | );
104 | }
105 | }
106 |
107 | class SearchBarController extends ValueNotifier {
108 | int alpha;
109 | Color searchBarBg;
110 | Color appbarTitleColor;
111 | String appbarLeftIcon;
112 | String appbarRightIcon;
113 |
114 | SearchBarController({
115 | this.alpha,
116 | this.searchBarBg,
117 | this.appbarTitleColor,
118 | this.appbarLeftIcon,
119 | this.appbarRightIcon,
120 | }) : super(new SearchBarAlphaValue(
121 | alpha: alpha,
122 | searchBarBg: searchBarBg,
123 | appbarTitleColor: appbarTitleColor,
124 | appbarLeftIcon: appbarLeftIcon,
125 | appbarRightIcon: appbarRightIcon));
126 | }
127 |
128 | class SearchBarAlphaValue {
129 | int alpha;
130 | Color searchBarBg;
131 |
132 | Color appbarTitleColor;
133 | String appbarLeftIcon;
134 | String appbarRightIcon;
135 |
136 | SearchBarAlphaValue({
137 | this.alpha,
138 | this.searchBarBg,
139 | this.appbarTitleColor,
140 | this.appbarLeftIcon,
141 | this.appbarRightIcon,
142 | });
143 | }
144 |
--------------------------------------------------------------------------------
/lib/views/login/login_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/app/route/fluro_navigator.dart';
2 | import 'package:boohee_flutter/app/route/routes.dart';
3 | import 'package:boohee_flutter/common/Colors.dart';
4 | import 'package:boohee_flutter/common/constant.dart';
5 | import 'package:boohee_flutter/model/login_user.dart';
6 | import 'package:boohee_flutter/res/styles.dart';
7 | import 'package:boohee_flutter/utils/account_utils.dart';
8 | import 'package:boohee_flutter/utils/repository_utils.dart';
9 | import 'package:boohee_flutter/utils/toast_utils.dart';
10 | import 'package:boohee_flutter/utils/utils.dart';
11 | import 'package:flustars/flustars.dart';
12 | import 'package:flutter/cupertino.dart';
13 | import 'package:flutter/material.dart';
14 |
15 | class LoginPage extends StatefulWidget {
16 | @override
17 | _LoginPageState createState() => _LoginPageState();
18 | }
19 |
20 | class _LoginPageState extends State {
21 | var leftRightPadding = 30.0;
22 | var topBottomPadding = 4.0;
23 |
24 | var _userPassController = new TextEditingController();
25 | var _userNameController = new TextEditingController();
26 |
27 | @override
28 | Widget build(BuildContext context) {
29 | return new Scaffold(
30 | backgroundColor: Colors.white,
31 | appBar: new AppBar(
32 | backgroundColor: mainColor,
33 | title: Text("账号登陆"),
34 | ),
35 | body: SingleChildScrollView(
36 | child: new Column(
37 | mainAxisSize: MainAxisSize.max,
38 | mainAxisAlignment: MainAxisAlignment.start,
39 | children: [
40 | Padding(
41 | padding: EdgeInsets.only(top: 80),
42 | child: Row(
43 | mainAxisAlignment: MainAxisAlignment.center,
44 | children: [
45 | Image.asset(
46 | Utils.getImgPath("ic_boohee_logo"),
47 | height: 35,
48 | width: 35,
49 | ),
50 | SizeBoxFactory.getHorizontalSizeBox(20),
51 | Text(
52 | "薄荷健康",
53 | style: TextStyle(
54 | color: color373D52,
55 | fontSize: 23,
56 | fontWeight: FontWeight.w600),
57 | )
58 | ],
59 | ),
60 | ),
61 | new Padding(
62 | padding: new EdgeInsets.fromLTRB(
63 | leftRightPadding, 50.0, leftRightPadding, topBottomPadding),
64 | child: new TextField(
65 | style: new TextStyle(fontSize: 16.0, color: color373D52),
66 | controller: _userNameController,
67 | decoration: new InputDecoration(
68 | hintText: "用户名/手机号/邮箱",
69 | hintStyle: TextStyle(fontSize: 16, color: colorA8ACBC)),
70 | ),
71 | ),
72 | new Padding(
73 | padding: new EdgeInsets.fromLTRB(
74 | leftRightPadding, 30.0, leftRightPadding, topBottomPadding),
75 | child: new TextField(
76 | style: TextStyle(fontSize: 16.0, color: color373D52),
77 | controller: _userPassController,
78 | decoration: new InputDecoration(
79 | hintText: "密码",
80 | hintStyle: TextStyle(fontSize: 16, color: colorA8ACBC)),
81 | obscureText: true,
82 | ),
83 | ),
84 | new Container(
85 | width: 360.0,
86 | margin: new EdgeInsets.fromLTRB(10.0, 80, 10.0, 0.0),
87 | padding: new EdgeInsets.fromLTRB(leftRightPadding,
88 | topBottomPadding, leftRightPadding, topBottomPadding),
89 | child: new Card(
90 | color: mainColor,
91 | elevation: 6.0,
92 | child: new FlatButton(
93 | onPressed: () {
94 | login();
95 | },
96 | child: new Padding(
97 | padding: new EdgeInsets.all(10.0),
98 | child: new Text(
99 | '登录',
100 | style: new TextStyle(
101 | color: Colors.white, fontSize: 16.0),
102 | ),
103 | )),
104 | ),
105 | )
106 | ],
107 | ),
108 | ));
109 | }
110 |
111 | void login() async {
112 | if (_userNameController.text.isEmpty || _userPassController.text.isEmpty) {
113 | ToastUtils.showToast(context, "用户名或密码不能为空");
114 | return;
115 | }
116 | Repository.loadAsset("login_user", fileDir: "user").then((json) async {
117 | LoginUser loginUser = LoginUser.fromJson(Repository.toMap(json));
118 | await SpUtil.getInstance();
119 | AccountUtils.saveUser(loginUser);
120 | SpUtil.putString(Constant.token, loginUser.token);
121 | SpUtil.putString(Constant.user_key, loginUser.user.userKey);
122 | if (loginUser != null && loginUser.token.isNotEmpty) {
123 | // 登录成功,跳转首页
124 | NavigatorUtils.push(context, Routes.root, replace: true);
125 | }
126 | });
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: boohee_flutter
2 | description: A new Flutter application.
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # In Android, build-name is used as versionName while build-number used as versionCode.
10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
12 | # Read more about iOS versioning at
13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
14 | version: 1.0.0+1
15 |
16 | environment:
17 | sdk: ">=2.1.0 <3.0.0"
18 |
19 | dependencies:
20 | flutter:
21 | sdk: flutter
22 |
23 | cupertino_icons: ^0.1.2
24 | # 网络请求库
25 | dio: 2.1.7
26 | # bean对象
27 | json_annotation: ^3.0.0
28 | # 轮播图
29 | # banner: ^0.1.3
30 | banner_view: ^1.1.2
31 | # 刷新控件
32 | flutter_easyrefresh: ^2.0.4
33 | # 聚合工具类
34 | # flustars: ^0.2.6+1
35 | # 路由
36 | fluro: ^1.5.1
37 | # toast
38 | toast: ^0.1.5
39 | # 进度条
40 | percent_indicator: ^2.1.1+1
41 | # webview
42 | webview_flutter: ^0.3.14+1
43 | # flutter_webview_plugin: ^0.3.5
44 | # 折线图
45 | fl_chart: ^0.2.2
46 | # Image Cache
47 | extended_image: ^0.6.8
48 | flustars: ^0.2.6+1
49 | auto_size:
50 | git:
51 | url: git://github.com/flutterchina/auto_size.git
52 |
53 | dev_dependencies:
54 | flutter_test:
55 | sdk: flutter
56 | build_runner: ^1.7.0
57 | json_serializable: ^3.2.2
58 | # shared_preferences: '>=0.1.1 <3.0.0'
59 | synchronized: '>=0.1.0 <3.0.0'
60 | rxdart: ^0.22.2
61 | crypto: ^2.1.3
62 |
63 | # For information on the generic Dart part of this file, see the
64 | # following page: https://www.dartlang.org/tools/pub/pubspec
65 |
66 | # The following section is specific to Flutter.
67 | flutter:
68 |
69 | # The following line ensures that the Material Icons font is
70 | # included with your application, so that you can use the icons in
71 | # the material Icons class.
72 | uses-material-design: true
73 |
74 | assets:
75 | - assets/json/discover/discover_sub.json
76 | - assets/json/common/splash_ad.json
77 | - assets/json/home/home_health_tools.json
78 | - assets/json/home/home_wallpaper.json
79 | - assets/json/shop/shop_banner.json
80 | - assets/json/shop/shop_recommend_list.json
81 | - assets/json/me/mine_cards.json
82 | - assets/json/user/login_user.json
83 | - images/ic_tab_bar_home_grey.png
84 | - images/ic_tab_bar_me_grey.png
85 | - images/ic_tab_bar_partner_grey.png
86 | - images/ic_tab_bar_shop_grey.png
87 | - images/ic_tab_bar_home_green.png
88 | - images/ic_tab_bar_me_green.png
89 | - images/ic_tab_bar_partner_green.png
90 | - images/ic_tab_bar_shop_green.png
91 | - images/ic_boohee_logo.png
92 | - images/ic_home_calorie.png
93 | - images/ic_home_sleep.png
94 | - images/ic_home_sport.png
95 | - images/ic_home_step.png
96 | - images/ic_home_weight.png
97 | - images/ic_home_dietician.png
98 | - images/ic_arrow_grey.png
99 | - images/ic_home_habit.png
100 | - images/ic_home_circumference.png
101 | - images/ic_home_baby.png
102 | - images/ic_home_food_plan.png
103 | - images/ic_home_menstruation.png
104 | - images/ic_message_grey.png
105 | - images/ic_search_grey.png
106 | - images/ic_message_white.png
107 | - images/ic_search_white.png
108 | - images/ic_shop_cart_white.png
109 | - images/ic_settings_white.png
110 | - images/ic_me_address.png
111 | - images/ic_me_order.png
112 | - images/ic_me_shopping_cart.png
113 | - images/ic_me_ticket.png
114 | - images/ic_home_tabbar_plus.png
115 | - images/ic_arrow_light_yellow.png
116 | - images/ic_dietician_logo.png
117 | - images/ic_home_default_wallpaper.webp
118 | # To add assets to your application, add an assets section, like this:
119 | # assets:
120 | # - images/a_dot_burr.jpeg
121 | # - images/a_dot_ham.jpeg
122 |
123 | # An image asset can refer to one or more resolution-specific "variants", see
124 | # https://flutter.dev/assets-and-images/#resolution-aware.
125 |
126 | # For details regarding adding assets from package dependencies, see
127 | # https://flutter.dev/assets-and-images/#from-packages
128 |
129 | # To add custom fonts to your application, add a fonts section here,
130 | # in this "flutter" section. Each entry in this list should have a
131 | # "family" key with the font family name, and a "fonts" key with a
132 | # list giving the asset and other descriptors for the font. For
133 | # example:
134 | # fonts:
135 | # - family: Schyler
136 | # fonts:
137 | # - asset: fonts/Schyler-Regular.ttf
138 | # - asset: fonts/Schyler-Italic.ttf
139 | # style: italic
140 | # - family: Trajan Pro
141 | # fonts:
142 | # - asset: fonts/TrajanPro.ttf
143 | # - asset: fonts/TrajanPro_Bold.ttf
144 | # weight: 700
145 | #
146 | # For details regarding fonts from package dependencies,
147 | # see https://flutter.dev/custom-fonts/#from-packages
148 |
149 | fonts:
150 | - family: Montserrat
151 | fonts:
152 | - asset: fonts/Montserrat-Bold.otf
153 |
--------------------------------------------------------------------------------
/lib/splash_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/res/styles.dart';
2 | import 'package:boohee_flutter/utils/repository_utils.dart';
3 | import 'package:boohee_flutter/utils/utils.dart';
4 | import 'package:boohee_flutter/widget/round_button.dart';
5 | import 'package:extended_image/extended_image.dart';
6 | import 'package:fluro/fluro.dart';
7 | import 'package:flustars/flustars.dart';
8 | import 'package:flutter/cupertino.dart';
9 | import 'package:flutter/material.dart';
10 |
11 | import 'app/route/application.dart';
12 | import 'app/route/fluro_navigator.dart';
13 | import 'app/route/routes.dart';
14 | import 'common/colors.dart';
15 | import 'common/constant.dart';
16 | import 'model/splash_ad.dart';
17 |
18 | class SplashPage extends StatefulWidget {
19 | @override
20 | _SplashPageState createState() => _SplashPageState();
21 | }
22 |
23 | class _SplashPageState extends State {
24 | _SplashPageState() {
25 | final router = new Router();
26 | Routes.configureRoutes(router);
27 | Application.router = router;
28 | }
29 |
30 | bool isLogin = false;
31 |
32 | // 因为offstage属性为true是隐藏,false为显示,所以默认属性为true
33 | bool inVisible = true;
34 | SplashAd splashAd;
35 | TimerUtil _timerUtil;
36 | int countdownTime = 3 * 1000;
37 | int currentTime = 3;
38 |
39 | @override
40 | void initState() {
41 | super.initState();
42 | _loadLoginStatus();
43 | }
44 |
45 | @override
46 | Widget build(BuildContext context) {
47 | return MaterialApp(
48 | home: Scaffold(
49 | body: Container(
50 | height: double.infinity,
51 | child: Column(
52 | children: [
53 | Expanded(
54 | child: Stack(
55 | alignment: Alignment.bottomCenter,
56 | children: [
57 | ExtendedImage.network(
58 | splashAd == null ? "" : splashAd.startUpUrl,
59 | width: double.infinity,
60 | height: double.infinity,
61 | fit: BoxFit.cover,
62 | cache: true,
63 | enableLoadState: false,
64 | ),
65 | Offstage(
66 | offstage: inVisible,
67 | child: Container(
68 | height: 50,
69 | width: double.infinity,
70 | color: Colors.black38,
71 | child: Center(
72 | child: Text(
73 | splashAd == null ? "" : splashAd.text,
74 | style: TextStyle(color: Colors.white, fontSize: 15),
75 | ),
76 | ),
77 | ),
78 | )
79 | ],
80 | )),
81 | Stack(
82 | alignment: Alignment.center,
83 | children: [
84 | Container(
85 | height: 105,
86 | width: double.infinity,
87 | child: Row(
88 | mainAxisAlignment: MainAxisAlignment.center,
89 | children: [
90 | Image.asset(
91 | Utils.getImgPath("ic_boohee_logo"),
92 | height: 35,
93 | width: 35,
94 | ),
95 | PaddingStyles.getPadding(10),
96 | Text(
97 | "薄荷健康",
98 | style: TextStyle(
99 | color: color373D52,
100 | fontSize: 18,
101 | fontWeight: FontWeight.w600),
102 | )
103 | ],
104 | ),
105 | ),
106 | Padding(
107 | padding: EdgeInsets.only(right: 10),
108 | child: Align(
109 | alignment: Alignment.centerRight,
110 | child: Offstage(
111 | offstage: inVisible,
112 | child: RoundButton(
113 | padding: EdgeInsets.only(
114 | left: 5, right: 5, top: 2, bottom: 2),
115 | backgroundColor: Colors.black45,
116 | radius: 2,
117 | buttonText: Text(
118 | "跳过广告 $currentTime",
119 | style:
120 | TextStyle(fontSize: 12, color: Colors.white),
121 | ),
122 | onPressed: () {
123 | _timerUtil.cancel();
124 | goHome();
125 | },
126 | ),
127 | )),
128 | )
129 | ],
130 | )
131 | ],
132 | ),
133 | ),
134 | ),
135 | );
136 | }
137 |
138 | void _loadLoginStatus() async {
139 | await SpUtil.getInstance();
140 | if (!mounted) return;
141 | _loadLocale();
142 | _loadSplashAd();
143 | }
144 |
145 | void _loadLocale() {
146 | setState(() {
147 | String token = SpUtil.getString(Constant.token, defValue: "");
148 | if (token.isNotEmpty) {
149 | isLogin = true;
150 | }
151 | });
152 | }
153 |
154 | void _loadSplashAd() {
155 | Repository.loadAsset("splash_ad").then((json) {
156 | splashAd = SplashAd.fromJson(Repository.toMapForList(json));
157 | inVisible = !splashAd.isAd;
158 | if (inVisible) {
159 | // 没有广告,倒计时1s
160 | countdownTime = 1 * 1000;
161 | }
162 | initCountDown(countdownTime);
163 | // 开始倒计时
164 | _timerUtil.startCountDown();
165 | setState(() {});
166 | });
167 | }
168 |
169 | @override
170 | void dispose() {
171 | super.dispose();
172 | if (_timerUtil != null) _timerUtil.cancel(); //记得中dispose里面把timer cancel。
173 | }
174 |
175 | void goHome() {
176 | if (isLogin) {
177 | NavigatorUtils.push(context, Routes.root, replace: true);
178 | } else {
179 | NavigatorUtils.push(context, Routes.login, replace: true);
180 | }
181 | }
182 |
183 | /// 初始化倒计时
184 | void initCountDown(int countdownTime) {
185 | _timerUtil = new TimerUtil(mTotalTime: countdownTime);
186 | _timerUtil.setOnTimerTickCallback((int tick) {
187 | double _tick = tick / 1000;
188 | setState(() {
189 | currentTime = _tick.toInt();
190 | });
191 | if (_tick == 0) {
192 | goHome();
193 | }
194 | });
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/assets/json/discover/discover_sub.json:
--------------------------------------------------------------------------------
1 | {
2 | "banners": [
3 | {
4 | "id": 192,
5 | "title": "薄荷×雀巢 3周群服务",
6 | "link": "https://truck.boohee.com/nice/collections/29/apply",
7 | "pic_url": "http://up.boohee.cn/house/u/shop/ad_page/20190820/OPbanner240.jpg"
8 | },
9 | {
10 | "id": 172,
11 | "title": "甩掉秋膘,满200返200",
12 | "link": "https://one.boohee.com/store/pages/august_week3?page_from=community",
13 | "pic_url": "http://up.boohee.cn/house/u/shop/ad_page/0812/banner250.jpg"
14 | },
15 | {
16 | "id": 176,
17 | "title": "成功故事0814",
18 | "link": "https://status.boohee.com/story/new%20story190813?page_from=course",
19 | "pic_url": "http://up.boohee.cn/house/u/shop/ad_page/0813/banner.jpg"
20 | },
21 | {
22 | "id": 169,
23 | "title": "NICE服务(八月新的)",
24 | "link": "https://bhapp.boohee.com/webapp/virtual_goods/nice_2019/intro?type=nice&source=faxianbanner",
25 | "pic_url": "http://up.boohee.cn/house/u/shop/ad_page/20190819/banner240.jpg"
26 | },
27 | {
28 | "id": 157,
29 | "title": "生蚝队长",
30 | "link": "boohee://comments/67314724",
31 | "pic_url": "http://up.boohee.cn/house/u/one/slider/20190819/guide_vol399_banner.jpg"
32 | },
33 | {
34 | "id": 162,
35 | "title": "怡文好好吃",
36 | "link": "boohee://comments/67111786",
37 | "pic_url": "http://up.boohee.cn/house/u/one/slider/20190813/guide_vol397_banner.jpg"
38 | },
39 | {
40 | "id": 194,
41 | "title": "雅琪",
42 | "link": "boohee://comments/6912249",
43 | "pic_url": "http://up.boohee.cn/house/u/one/slider/20190807/guide_vol395_banner.jpg"
44 | }
45 | ],
46 |
47 | "labels": [
48 | {
49 | "title": "减肥知识",
50 | "url": "boohee://status_knowledge",
51 | "pic_url": "http://up.boohee.cn/house/u/shop/ad_page/0505/ss.png"
52 | },
53 | {
54 | "title": "饮食广场",
55 | "url": "boohee://meal_square",
56 | "pic_url": "http://up.boohee.cn/house/u/shop/ad_page/0505/food.png"
57 | },
58 | {
59 | "title": "瘦身定制",
60 | "url": "https://bhapp.boohee.com/webapp/virtual_goods/nice_2019/intro?type=nice&source=labels",
61 | "pic_url": "http://up.boohee.cn/house/u/shop/ad_page/0505/zhishi.png"
62 | }
63 | ]
64 |
65 | ,
66 | "sections": [
67 | {
68 | "name": "微信群",
69 | "more_content_text": null,
70 | "more_content_url": null,
71 | "sub_contents": [
72 | {
73 | "title": "食物 值得认真对待",
74 | "sub_title": "薄荷智慧营养师 7天群",
75 | "img_url": "http://up.boohee.cn/house/u/one/slider/20190705/yys.png",
76 | "redirect_url": "boohee://dietitian_purchase"
77 | },
78 | {
79 | "title": "拿出超模的态度",
80 | "sub_title": "超模25代餐 3周减重群",
81 | "img_url": "http://up.boohee.cn/house/u/one/slider/20190705/qun.png",
82 | "redirect_url": "boohee://goods/3751"
83 | },
84 | {
85 | "title": "限制热量 平衡饮食",
86 | "sub_title": "21天10斤挑战+群服务",
87 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/mai.jpg",
88 | "redirect_url": "boohee://goods/3863"
89 | }
90 | ]
91 | },
92 | {
93 | "name": "成功故事",
94 | "more_content_text": null,
95 | "more_content_url": null,
96 | "sub_contents": [
97 | {
98 | "title": "圆脸阿姨变美少女",
99 | "sub_title": "(55.4-49.35)KG",
100 | "img_url": "http://up.boohee.cn/house/u/one/slider/20190717/1.png",
101 | "redirect_url": "https://status.boohee.com/story/new%20story190813?page_from=hbstory"
102 | },
103 | {
104 | "title": "小肚子变马甲线!",
105 | "sub_title": "(50-46.1)KG",
106 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190627/88.jpg",
107 | "redirect_url": "https://status.boohee.com/story/new%20story190806?page_from=hbstory"
108 | },
109 | {
110 | "title": "穿上24码裤子不是梦",
111 | "sub_title": "(64.7-54)KG",
112 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190627/731.png",
113 | "redirect_url": "https://status.boohee.com/story/new%20story190730?page_from=hbstory"
114 | },
115 | {
116 | "title": "告别反弹,健康减重",
117 | "sub_title": "(55-46.5)KG",
118 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190627/724.png",
119 | "redirect_url": "https://status.boohee.com/story/new%20story190723?page_from=hbstory"
120 | },
121 | {
122 | "title": "更多成功故事",
123 | "sub_title": "戳这里→",
124 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190505/more.jpg",
125 | "redirect_url": "https://one.boohee.com/store/pages/nice_story_list"
126 | }
127 | ]
128 | },
129 | {
130 | "name": "推荐达人",
131 | "more_content_text": null,
132 | "more_content_url": null,
133 | "sub_contents": [
134 | {
135 | "title": " 群星直播间",
136 | "sub_title": "带你探索健康好物",
137 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/0722/lab.jpg",
138 | "redirect_url": "https://one.boohee.com/store/pages/boheezbj"
139 | },
140 | {
141 | "title": "薄荷首席营养师",
142 | "sub_title": "怡文好好吃",
143 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/yw.jpg",
144 | "redirect_url": "boohee://channel/vlog_yiwen"
145 | },
146 | {
147 | "title": "爱吃爱笑的台湾营养师",
148 | "sub_title": "雅琪的万事屋",
149 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/yq.jpg",
150 | "redirect_url": "boohee://channel/vlog_yaqi"
151 | },
152 | {
153 | "title": "热爱嘻哈的健身小钢炮",
154 | "sub_title": "生蚝队长",
155 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/sh.jpg",
156 | "redirect_url": "boohee://channel/vlog_oasher"
157 | },
158 | {
159 | "title": "管不住嘴的减肥戏精",
160 | "sub_title": "大圣好瘦",
161 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/ds.jpg",
162 | "redirect_url": "boohee://channel/vlog_dasheng"
163 | }
164 | ]
165 | },
166 | {
167 | "name": "推荐课程",
168 | "more_content_text": "更多课程",
169 | "more_content_url": "boohee://recommond_courses",
170 | "sub_contents": [
171 | {
172 | "title": "最科学的减肥",
173 | "sub_title": "减肥必学的基础课知识",
174 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/class_1.jpg",
175 | "redirect_url": "boohee://training_course/1"
176 | },
177 | {
178 | "title": "明星营养师教你怎么吃",
179 | "sub_title": "这么吃才能瘦",
180 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/class_2.jpg",
181 | "redirect_url": "boohee://training_course/2"
182 | },
183 | {
184 | "title": "让你吃饱又能瘦",
185 | "sub_title": "减肥怎么吃主食",
186 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/class_3.jpg",
187 | "redirect_url": "boohee://training_course/3"
188 | },
189 | {
190 | "title": "怎么运动才减得快?",
191 | "sub_title": "运动减肥必学的基础课",
192 | "img_url": "http://up.boohee.cn/house/u/shop/ad_page/20190212/class_4.jpg",
193 | "redirect_url": "boohee://training_course/15"
194 | }
195 | ]
196 | }
197 | ]
198 | }
--------------------------------------------------------------------------------
/assets/json/shop/shop_banner.json:
--------------------------------------------------------------------------------
1 | {
2 | "banner_showcases": [
3 | {
4 | "id": 1961,
5 | "exhibit": "3847",
6 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/0618/k375.jpg",
7 | "default_photo_height": 375,
8 | "default_photo_width": 750,
9 | "exhibit_type": "goods",
10 | "page_title": ""
11 | },
12 | {
13 | "id": 1630,
14 | "exhibit": "3746",
15 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/20180731/naidong375.jpg",
16 | "default_photo_height": 375,
17 | "default_photo_width": 700,
18 | "exhibit_type": "goods",
19 | "page_title": ""
20 | },
21 | {
22 | "id": 2016,
23 | "exhibit": "3100",
24 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/0812/mp.jpg",
25 | "default_photo_height": 340,
26 | "default_photo_width": 640,
27 | "exhibit_type": "goods",
28 | "page_title": ""
29 | },
30 | {
31 | "id": 1904,
32 | "exhibit": "3609",
33 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/0422/mm.jpg",
34 | "default_photo_height": 375,
35 | "default_photo_width": 750,
36 | "exhibit_type": "goods",
37 | "page_title": ""
38 | },
39 | {
40 | "id": 2011,
41 | "exhibit": "https://one.boohee.com/store/pages/august_week3?page_from=shopbanner",
42 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/0812/banner750.jpg",
43 | "default_photo_height": 375,
44 | "default_photo_width": 750,
45 | "exhibit_type": "page",
46 | "page_title": "查看"
47 | },
48 | {
49 | "id": 1753,
50 | "exhibit": "3216",
51 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/0812/dg.jpg",
52 | "default_photo_height": 375,
53 | "default_photo_width": 750,
54 | "exhibit_type": "goods",
55 | "page_title": ""
56 | },
57 | {
58 | "id": 1948,
59 | "exhibit": "https://bhapp.boohee.com/webapp/virtual_goods/nice_2019/intro?type=nice&source=store_home_banner",
60 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/20190813/banner375.jpg",
61 | "default_photo_height": 375,
62 | "default_photo_width": 750,
63 | "exhibit_type": "page",
64 | "page_title": "查看"
65 | },
66 | {
67 | "id": 1934,
68 | "exhibit": "https://truck.boohee.com/nice/collections/29/apply?page_from=shopbanner",
69 | "default_photo_url": "http://up.boohee.cn/house/u/shop/ad_page/20190812/banner375.jpg",
70 | "default_photo_height": 375,
71 | "default_photo_width": 750,
72 | "exhibit_type": "page",
73 | "page_title": "查看"
74 | }
75 | ],
76 | "shop_modules": [
77 | {
78 | "position": 1,
79 | "display": true,
80 | "title": "❤️满200返200",
81 | "sub_title": "鸡肉肠新包装>>",
82 | "picture_url1": "http://up.boohee.cn/house/u/20190121spsl/160_CHANG.png",
83 | "picture_url2": "http://up.boohee.cn/house/u/shop/ad_page/0513/sss.png",
84 | "redirect_url": "https://one.boohee.com/store/pages/august_week3",
85 | "new_tag": "2019-08-17 16:00:00"
86 | },
87 | {
88 | "position": 2,
89 | "display": true,
90 | "title": "😊薄荷新人推荐",
91 | "sub_title": "人气榜单在此>>",
92 | "picture_url1": "http://up.boohee.cn/house/u/shop/ad_page/0722/bang.jpg",
93 | "picture_url2": "http://up.boohee.cn/house/u/shop/ad_page/0422/c.png",
94 | "redirect_url": "boohee://goods_list/86",
95 | "new_tag": "2019-07-29 15:00:00"
96 | },
97 | {
98 | "position": 3,
99 | "display": true,
100 | "title": "限时抢购",
101 | "start_time": "2019-08-12T16:00:00.000+00:00",
102 | "end_time": "2019-08-19T16:00:00.000+00:00",
103 | "picture_url1": "http://up.boohee.cn/house/u/20190121spsl/zs_new.png",
104 | "picture_url2": "http://up.boohee.cn/house/u/20190121spsl/kfdb1_1601.jpg",
105 | "redirect_url": "https://truck.boohee.com/promotion",
106 | "new_tag": "2019-07-08 00:00:00"
107 | },
108 | {
109 | "position": 4,
110 | "display": true,
111 | "title": "顾问陪你瘦",
112 | "sub_title": "送267元减脂包>>>",
113 | "picture_url1": "http://up.boohee.cn/house/u/shop/ad_page/0806/160-160.png",
114 | "picture_url2": "http://up.boohee.cn/house/u/shop/ad_page/0806/160-160l.png",
115 | "redirect_url": "https://bhapp.boohee.com/webapp/virtual_goods/nice_2019/intro?type=nice&source=store_homepage_promotion",
116 | "new_tag": ""
117 | },
118 | {
119 | "position": 5,
120 | "display": false,
121 | "title": "春季礼包精选",
122 | "picture_url1": "http://up.boohee.cn/house/u/shop/ad_page/0225/3.jpg",
123 | "redirect_url": "boohee://goods_list/277",
124 | "sub_title": "打包起来折扣更大",
125 | "new_tag": ""
126 | },
127 | {
128 | "position": 6,
129 | "display": true,
130 | "title": "节后减肥",
131 | "sub_title": "进群更好瘦!",
132 | "picture_url1": "http://up.boohee.cn/house/u/shop/ad_page/0221/yt.jpg",
133 | "redirect_url": "http://nice.boohee.com/webapp/collections/19",
134 | "new_tag": "2019-2-21"
135 | },
136 | {
137 | "position": 7,
138 | "display": true,
139 | "title": "商品福利",
140 | "sub_title": "入群早知道",
141 | "picture_url1": "http://up.boohee.cn/house/u/shop/ad_page/20180806/libao1.jpg",
142 | "redirect_url": "https://beauty.boohee.com/webapp/ice_room_banners/home?group_id=5",
143 | "new_tag": ""
144 | }
145 | ],
146 | "categories": [
147 | {
148 | "id": 9,
149 | "name": "新品购",
150 | "description": "所有商品按上新排序",
151 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F9%2Fxin.png"
152 | },
153 | {
154 | "id": 17,
155 | "name": "控卡餐",
156 | "description": "正餐",
157 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F17%2Fmeal.png"
158 | },
159 | {
160 | "id": 28,
161 | "name": "高蛋白",
162 | "description": "高蛋白",
163 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F28%2Fgao.png"
164 | },
165 | {
166 | "id": 27,
167 | "name": "燃燃燃",
168 | "description": "加强",
169 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F27%2Fxiao.png"
170 | },
171 | {
172 | "id": 25,
173 | "name": "瘦身定制",
174 | "description": "瘦身定制",
175 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F25%2Fshou.png"
176 | },
177 | {
178 | "id": 7,
179 | "name": "人气秤",
180 | "description": "硬件",
181 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F7%2Fcheng.png"
182 | },
183 | {
184 | "id": 18,
185 | "name": "轻零食",
186 | "description": "零食",
187 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F18%2Fqing.png"
188 | },
189 | {
190 | "id": 29,
191 | "name": "低脂肪",
192 | "description": "低脂肪",
193 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F29%2Ffat.png"
194 | },
195 | {
196 | "id": 13,
197 | "name": "好喝的",
198 | "description": "湿泡",
199 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F13%2Fhao.png"
200 | },
201 | {
202 | "id": 23,
203 | "name": "BR肌密",
204 | "description": "BR肌密",
205 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F23%2Fa.png"
206 | },
207 | {
208 | "id": 26,
209 | "name": "其它",
210 | "description": "其它",
211 | "icon_url": "http://one.boohee.cn/uploads%2Fcategory%2Ficon%2F26%2Fa.png"
212 | }
213 | ]
214 | }
--------------------------------------------------------------------------------
/lib/views/discover/discover_child_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:banner_view/banner_view.dart';
2 | import 'package:boohee_flutter/common/colors.dart';
3 | import 'package:boohee_flutter/model/discover/sub_discover.dart';
4 | import 'package:boohee_flutter/res/styles.dart';
5 | import 'package:boohee_flutter/utils/repository_utils.dart';
6 | import 'package:boohee_flutter/widget/top_bottom_widget.dart';
7 | import 'package:extended_image/extended_image.dart';
8 | import 'package:flustars/flustars.dart';
9 | import 'package:flutter/cupertino.dart';
10 | import 'package:flutter/material.dart';
11 | import 'package:flutter_easyrefresh/easy_refresh.dart';
12 | import 'package:flutter_easyrefresh/material_header.dart';
13 |
14 | class DiscoverChildPage extends StatefulWidget {
15 | @override
16 | _DiscoverChildPageState createState() => _DiscoverChildPageState();
17 | }
18 |
19 | class _DiscoverChildPageState extends State {
20 | EasyRefreshController _controller = EasyRefreshController();
21 | SubDiscover _subDiscover;
22 |
23 | /// tab、列表集合合集
24 | var mList = [];
25 |
26 | @override
27 | void initState() {
28 | super.initState();
29 | loadData();
30 | }
31 |
32 | @override
33 | Widget build(BuildContext context) {
34 | return EasyRefresh.custom(
35 | slivers: [
36 | createBannerView(),
37 | SliverList(
38 | delegate:
39 | SliverChildBuilderDelegate((BuildContext context, int index) {
40 | Widget widget;
41 | if (mList[index] is List) {
42 | var list = (mList[index] as List);
43 |
44 | /// tab
45 | widget = createTabView(list);
46 | } else if (mList[index] is Sections) {
47 | /// 列表
48 | widget = createListChild(mList[index] as Sections);
49 | }
50 | return widget;
51 | }, childCount: mList.length))
52 | ],
53 | header: MaterialHeader(
54 | valueColor: AlwaysStoppedAnimation(mainColor),
55 | ),
56 | controller: _controller,
57 | onRefresh: () async {
58 | loadData();
59 | _controller.finishRefresh();
60 | setState(() {});
61 | },
62 | );
63 | }
64 |
65 | Widget createBannerView() {
66 | return SliverToBoxAdapter(
67 | child: Container(
68 | height: ScreenUtil.getScreenW(context) * (250 / 750 * 1.0).toDouble(),
69 | child: BannerView(
70 | _subDiscover.banners
71 | .map((bean) => (createBannerChildView(bean)))
72 | .toList(),
73 | intervalDuration: Duration(seconds: 3),
74 | indicatorMargin: 5,
75 | indicatorNormal: new Container(
76 | width: 8.0,
77 | height: 5.0,
78 | decoration: new BoxDecoration(
79 | color: Colors.white,
80 | shape: BoxShape.rectangle,
81 | borderRadius: new BorderRadius.all(
82 | new Radius.circular(20.0),
83 | ),
84 | ),
85 | ),
86 | indicatorSelected: new Container(
87 | width: 15.0,
88 | height: 5.0,
89 | decoration: new BoxDecoration(
90 | color: Color(0xFFEEEFF3),
91 | shape: BoxShape.rectangle,
92 | borderRadius: new BorderRadius.all(
93 | new Radius.circular(20.0),
94 | ),
95 | ),
96 | ),
97 | indicatorBuilder: (context, indicator) {
98 | Widget cc = new Container(
99 | margin: EdgeInsets.only(bottom: 8),
100 | alignment: Alignment.bottomCenter,
101 | height: double.infinity,
102 | child: indicator,
103 | );
104 | return cc;
105 | },
106 | ),
107 | ),
108 | );
109 | }
110 |
111 | /// 发现页数据 banner、tab、列表数据
112 | void loadData() {
113 | Repository.loadAsset("discover_sub", fileDir: "discover").then((response) {
114 | _subDiscover = SubDiscover.fromJson(Repository.toMap(response));
115 | mList.clear();
116 | mList.add(_subDiscover.labels);
117 | mList.addAll(_subDiscover.sections);
118 | setState(() {});
119 | });
120 | }
121 |
122 | Widget createBannerChildView(Banners data) {
123 | return Container(
124 | margin: EdgeInsets.only(top: 13.0, left: 17, right: 17),
125 | decoration: BoxDecoration(
126 | image: DecorationImage(
127 | image: ExtendedNetworkImageProvider(data.picUrl, cache: true),
128 | fit: BoxFit.cover,
129 | ),
130 | borderRadius: BorderRadius.all(
131 | Radius.circular(12.0),
132 | ),
133 | ),
134 | );
135 | }
136 |
137 | /// Tab
138 | Widget createTabView(List list) {
139 | return Container(
140 | padding: EdgeInsets.only(top: 20),
141 | child: GridView.builder(
142 | shrinkWrap: true,
143 | physics: NeverScrollableScrollPhysics(),
144 | // 禁用GradView滚动事件
145 | itemCount: list.length,
146 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
147 | crossAxisCount: 3, childAspectRatio: 2.2),
148 | itemBuilder: (BuildContext context, int index) {
149 | return TopBottom(
150 | margin: 5,
151 | top: ExtendedImage.network(
152 | list[index].picUrl,
153 | enableLoadState: false,
154 | height: 34,
155 | width: 34,
156 | ),
157 | bottom: Text(
158 | list[index].title,
159 | style: TextStyles.get12Text_373D52(),
160 | ),
161 | );
162 | }),
163 | );
164 | }
165 |
166 | /// 列表
167 | Widget createListChild(Sections sections) {
168 | return Container(
169 | height: 172,
170 | margin: EdgeInsets.only(top: 33),
171 | padding: EdgeInsets.only(left: 17),
172 | child: Column(
173 | crossAxisAlignment: CrossAxisAlignment.start,
174 | children: [
175 | Text(
176 | sections.name,
177 | style: TextStyles.get15TextBold_373D52(),
178 | ),
179 | _getHorizontalListView(sections.subContents)
180 | ],
181 | ),
182 | );
183 | }
184 |
185 | /// 横向列表
186 | Widget _getHorizontalListView(List subContents) {
187 | var horizontalList = ListView.builder(
188 | scrollDirection: Axis.horizontal,
189 | itemBuilder: (context, index) {
190 | return Column(
191 | crossAxisAlignment: CrossAxisAlignment.start,
192 | children: [
193 | Container(
194 | margin: EdgeInsets.only(right: 11, top: 14, bottom: 10),
195 | height: 92,
196 | width: 144,
197 | decoration: BoxDecoration(
198 | image: DecorationImage(
199 | image: ExtendedNetworkImageProvider(
200 | subContents[index].imgUrl,
201 | cache: true),
202 | fit: BoxFit.cover,
203 | ),
204 | borderRadius: BorderRadius.all(
205 | Radius.circular(12.0),
206 | ),
207 | ),
208 | ),
209 | Text(
210 | subContents[index].title,
211 | style: TextStyle(fontSize: 13, color: color373D52),
212 | maxLines: 1,
213 | overflow: TextOverflow.ellipsis,
214 | ),
215 | SizeBoxFactory.getVerticalSizeBox(1),
216 | Text(
217 | subContents[index].subTitle,
218 | style: TextStyle(fontSize: 11, color: colorA8ACBC),
219 | maxLines: 1,
220 | overflow: TextOverflow.ellipsis,
221 | )
222 | ],
223 | );
224 | },
225 | itemCount: subContents.length);
226 |
227 | return Expanded(
228 | child: Container(width: double.infinity, child: horizontalList));
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/lib/views/mine_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:boohee_flutter/app/route/fluro_navigator.dart';
2 | import 'package:boohee_flutter/app/route/routes.dart';
3 | import 'package:boohee_flutter/common/colors.dart';
4 | import 'package:boohee_flutter/model/login_user.dart';
5 | import 'package:boohee_flutter/model/mine_cards.dart';
6 | import 'package:boohee_flutter/res/styles.dart';
7 | import 'package:boohee_flutter/utils/account_utils.dart';
8 | import 'package:boohee_flutter/utils/repository_utils.dart';
9 | import 'package:boohee_flutter/utils/utils.dart';
10 | import 'package:boohee_flutter/widget/card_view.dart';
11 | import 'package:boohee_flutter/widget/tool_bar.dart';
12 | import 'package:boohee_flutter/widget/top_bottom_widget.dart';
13 | import 'package:extended_image/extended_image.dart';
14 | import 'package:flustars/flustars.dart';
15 | import 'package:flutter/cupertino.dart';
16 | import 'package:flutter/material.dart';
17 |
18 | class MinePage extends StatefulWidget {
19 | @override
20 | State createState() => _MinePageState();
21 | }
22 |
23 | class _MinePageState extends State {
24 | User mUser;
25 | List mCards = [];
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 | mUser = AccountUtils.getUser();
31 | getMineCards();
32 | setState(() {});
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return Scaffold(
38 | appBar: Toolbar(
39 | onTabRightOne: () {
40 | settingClick();
41 | },
42 | ),
43 | body: CustomScrollView(
44 | physics: BouncingScrollPhysics(),
45 | slivers: [
46 | SliverToBoxAdapter(child: createMineHeader()),
47 | createMenuTab()
48 | ],
49 | ),
50 | );
51 | }
52 |
53 | /// 我的页面头部
54 | Widget createMineHeader() {
55 | return Stack(
56 | children: [
57 | Container(
58 | padding: EdgeInsets.only(top: 10, bottom: 47),
59 | color: color00CDA2,
60 | child: Column(
61 | crossAxisAlignment: CrossAxisAlignment.start,
62 | children: [
63 | Row(
64 | crossAxisAlignment: CrossAxisAlignment.center,
65 | children: [
66 | PaddingStyles.getPadding(17),
67 | new ClipOval(
68 | child: ExtendedImage.network(
69 | mUser.avatarUrl,
70 | fit: BoxFit.cover,
71 | height: 60,
72 | width: 60,
73 | ),
74 | ),
75 | PaddingStyles.getPadding(13),
76 | Column(
77 | crossAxisAlignment: CrossAxisAlignment.start,
78 | children: [
79 | Text(
80 | mUser.userName,
81 | style: TextStyle(
82 | fontSize: 17,
83 | color: Colors.white,
84 | fontWeight: FontWeight.w700),
85 | ),
86 | Text(
87 | "修改个人资料",
88 | style: TextStyle(
89 | fontSize: 12,
90 | color: Colors.white,
91 | ),
92 | )
93 | ],
94 | )
95 | ],
96 | ),
97 | SizeBoxFactory.getVerticalSizeBox(25),
98 | Row(
99 | mainAxisAlignment: MainAxisAlignment.spaceAround,
100 | mainAxisSize: MainAxisSize.max,
101 | children: [
102 | TopBottom(
103 | top: Text(
104 | "57",
105 | style: TextStyles.get15White(),
106 | ),
107 | bottom: Text(
108 | "动态",
109 | style: TextStyle(fontSize: 12, color: Color(0x9EFFFFFF)),
110 | ),
111 | margin: 2,
112 | ),
113 | TopBottom(
114 | top: Text(
115 | "74",
116 | style: TextStyles.get15White(),
117 | ),
118 | bottom: Text(
119 | "关注",
120 | style: TextStyle(fontSize: 12, color: Color(0x9EFFFFFF)),
121 | ),
122 | margin: 2,
123 | ),
124 | TopBottom(
125 | top: Text(
126 | "423",
127 | style: TextStyles.get15White(),
128 | ),
129 | bottom: Text(
130 | "粉丝",
131 | style: TextStyle(fontSize: 12, color: Color(0x9EFFFFFF)),
132 | ),
133 | margin: 2,
134 | )
135 | ],
136 | ),
137 | ],
138 | ),
139 | ),
140 | CardView(
141 | margin: EdgeInsets.only(left: 17, right: 17, top: 160),
142 | child: Padding(
143 | padding: EdgeInsets.only(top: 22, bottom: 22, left: 30, right: 30),
144 | child: Row(
145 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
146 | children: [
147 | TopBottom(
148 | top: Image.asset(
149 | Utils.getImgPath("ic_me_order"),
150 | width: 34,
151 | height: 34,
152 | ),
153 | bottom: Text(
154 | "订单",
155 | style: TextStyles.get12Text_373D52(),
156 | ),
157 | margin: 5,
158 | ),
159 | TopBottom(
160 | top: Image.asset(
161 | Utils.getImgPath("ic_me_shopping_cart"),
162 | width: 34,
163 | height: 34,
164 | ),
165 | bottom: Text(
166 | "购物车",
167 | style: TextStyles.get12Text_373D52(),
168 | ),
169 | margin: 5,
170 | ),
171 | TopBottom(
172 | top: Image.asset(
173 | Utils.getImgPath("ic_me_ticket"),
174 | width: 34,
175 | height: 34,
176 | ),
177 | bottom: Text(
178 | "优惠券",
179 | style: TextStyles.get12Text_373D52(),
180 | ),
181 | margin: 5,
182 | ),
183 | TopBottom(
184 | top: Image.asset(
185 | Utils.getImgPath("ic_me_address"),
186 | width: 34,
187 | height: 34,
188 | ),
189 | bottom: Text(
190 | "收货地址",
191 | style: TextStyles.get12Text_373D52(),
192 | ),
193 | margin: 5,
194 | )
195 | ],
196 | ),
197 | ),
198 | )
199 | ],
200 | );
201 | }
202 |
203 | /// 分类
204 | Widget createMenuTab() {
205 | return SliverToBoxAdapter(
206 | child: Container(
207 | height: 176,
208 | child: CardView(
209 | margin: EdgeInsets.only(left: 17, right: 17, top: 14),
210 | child: Padding(
211 | padding: EdgeInsets.only(top: 20, left: 10, right: 10),
212 | child: GridView.builder(
213 | physics: NeverScrollableScrollPhysics(), // 禁用GradView滚动事件
214 | itemCount: mCards.length,
215 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
216 | crossAxisCount: 4,
217 | ),
218 | itemBuilder: (BuildContext context, int index) {
219 | return createCard(mCards[index]);
220 | }),
221 | ),
222 | ),
223 | ),
224 | );
225 | }
226 |
227 | /// 卡片,后台配置
228 | void getMineCards() {
229 | Repository.loadAsset("mine_cards", fileDir: "me").then((json) {
230 | MineCards mineCards = MineCards.fromJson(Repository.toMap(json));
231 | mCards = mineCards.data;
232 | setState(() {});
233 | });
234 | }
235 |
236 | /// 菜单卡片
237 | Widget createCard(Data mCard) {
238 | return TopBottom(
239 | top: ExtendedImage.network(
240 | mCard.iconUrl,
241 | width: 22,
242 | height: 22,
243 | ),
244 | bottom: Text(
245 | mCard.name,
246 | style: TextStyles.get12Text_373D52(),
247 | ),
248 | margin: 6,
249 | );
250 | }
251 |
252 | /// 退出登陆弹框
253 | void settingClick() {
254 | showDialog(
255 | context: context,
256 | builder: (context) {
257 | return new AlertDialog(
258 | content: Text(
259 | "是否确认退出登录?",
260 | style: TextStyles.get15Text_373D52(),
261 | ),
262 | actions: [
263 | FlatButton(
264 | onPressed: () async {
265 | // 清空登陆信息
266 | SpUtil.clear();
267 | // 关闭弹框
268 | Navigator.of(context).pop();
269 | // 打开登陆页面
270 | NavigatorUtils.push(context, Routes.login,
271 | replace: true, clearStack: true);
272 | },
273 | child: new Text(
274 | "确定",
275 | style: TextStyle(color: mainColor),
276 | ),
277 | ),
278 | FlatButton(
279 | onPressed: () {
280 | Navigator.of(context).pop();
281 | },
282 | child: new Text("取消", style: TextStyle(color: mainColor)),
283 | ),
284 | ],
285 | );
286 | });
287 | }
288 | }
289 |
--------------------------------------------------------------------------------
/lib/views/shop_pages/shop_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:banner_view/banner_view.dart';
2 | import 'package:boohee_flutter/common/colors.dart';
3 | import 'package:boohee_flutter/model/ShopBanner.dart';
4 | import 'package:boohee_flutter/model/ShopRecommendList.dart';
5 | import 'package:boohee_flutter/res/styles.dart';
6 | import 'package:boohee_flutter/utils/repository_utils.dart';
7 | import 'package:boohee_flutter/widget/card_view.dart';
8 | import 'package:boohee_flutter/widget/common_search_bar.dart';
9 | import 'package:extended_image/extended_image.dart';
10 | import 'package:flutter/material.dart';
11 | import 'package:flutter_easyrefresh/easy_refresh.dart';
12 | import 'package:flutter_easyrefresh/material_header.dart';
13 |
14 | class ShopPage extends StatefulWidget {
15 | @override
16 | State createState() => _ShopPageState();
17 | }
18 |
19 | class _ShopPageState extends State {
20 | List _bannerList = [];
21 | List _categoriseList = [];
22 | List _goodsList = [];
23 | double bannerHeight = 200;
24 | EasyRefreshController _controller = EasyRefreshController();
25 |
26 | @override
27 | void initState() {
28 | // TODO: implement initState
29 | super.initState();
30 | loadData();
31 | }
32 |
33 | /// 加载数据
34 | void loadData() {
35 | /// 商店Banner
36 | Repository.loadAsset("shop_banner", fileDir: "shop").then((json) {
37 | _categoriseList.clear();
38 | ShopBanner data = ShopBanner.fromJson(Repository.toMap(json));
39 | _bannerList = data.bannerShowcases;
40 | // 保证数据最多为10条
41 | data.categories.forEach((it) {
42 | // 默认第一个分类
43 | if (data.categories.indexOf(it) < 10) {
44 | _categoriseList.add(it);
45 | }
46 | });
47 | // 计算Banner的高度
48 | double screenWidth = MediaQuery.of(context).size.width;
49 | if (_bannerList.length > 0) {
50 | bannerHeight = (screenWidth - 2 * 17) *
51 | (_bannerList[0].defaultPhotoHeight /
52 | _bannerList[0].defaultPhotoWidth);
53 | }
54 | _controller.finishRefresh();
55 | setState(() {});
56 | });
57 |
58 | /// 商店推荐商品
59 | Repository.loadAsset("shop_recommend_list", fileDir: "shop").then((json) {
60 | ShopRecommendList data =
61 | ShopRecommendList.fromJson(Repository.toMap(json));
62 | _goodsList.clear();
63 | _goodsList.addAll(data.goods);
64 | setState(() {});
65 | });
66 | }
67 |
68 | @override
69 | Widget build(BuildContext context) {
70 | return Scaffold(
71 | appBar: SearchBar(
72 | isShowCartIcon: true,
73 | text: "商店搜索",
74 | ),
75 | body: EasyRefresh.custom(
76 | slivers: [
77 | createBannerView(),
78 | createCategoryGridView(),
79 | createGoodsGridView(),
80 | ],
81 | header: MaterialHeader(
82 | valueColor: AlwaysStoppedAnimation(mainColor),
83 | ),
84 | taskIndependence: true,
85 | enableControlFinishRefresh: true,
86 | firstRefresh: true,
87 | controller: _controller,
88 | onRefresh: () async {
89 | loadData();
90 | },
91 | ));
92 | }
93 |
94 | Widget createBannerView() {
95 | return SliverToBoxAdapter(
96 | child: Container(
97 | height: bannerHeight,
98 | child: BannerView(
99 | _bannerList.map((bean) => (createBannerChildView(bean))).toList(),
100 | intervalDuration: Duration(seconds: 3),
101 | indicatorMargin: 5,
102 | indicatorNormal: new Container(
103 | width: 8.0,
104 | height: 5.0,
105 | decoration: new BoxDecoration(
106 | color: Colors.white,
107 | shape: BoxShape.rectangle,
108 | borderRadius: new BorderRadius.all(
109 | new Radius.circular(20.0),
110 | ),
111 | ),
112 | ),
113 | indicatorSelected: new Container(
114 | width: 15.0,
115 | height: 5.0,
116 | decoration: new BoxDecoration(
117 | color: Color(0xFFEEEFF3),
118 | shape: BoxShape.rectangle,
119 | borderRadius: new BorderRadius.all(
120 | new Radius.circular(20.0),
121 | ),
122 | ),
123 | ),
124 | indicatorBuilder: (context, indicator) {
125 | Widget cc = new Container(
126 | margin: EdgeInsets.only(bottom: 8),
127 | alignment: Alignment.bottomCenter,
128 | height: double.infinity,
129 | child: indicator,
130 | );
131 | return cc;
132 | },
133 | ),
134 | ),
135 | );
136 | }
137 |
138 | Widget createBannerChildView(Banner_showcases data) {
139 | return Container(
140 | margin: EdgeInsets.only(top: 13.0, left: 17, right: 17),
141 | decoration: BoxDecoration(
142 | image: DecorationImage(
143 | image:
144 | ExtendedNetworkImageProvider(data.defaultPhotoUrl, cache: true),
145 | fit: BoxFit.cover,
146 | ),
147 | borderRadius: BorderRadius.all(
148 | Radius.circular(12.0),
149 | ),
150 | ),
151 | );
152 | }
153 |
154 | // 分类
155 | Widget createCategoryGridView() {
156 | return SliverToBoxAdapter(
157 | child: Container(
158 | child: CardView(
159 | margin: EdgeInsets.only(left: 17, right: 17, top: 13),
160 | child: Padding(
161 | padding: EdgeInsets.only(top: 13, left: 10, right: 10),
162 | child: GridView.builder(
163 | shrinkWrap: true,
164 | physics: NeverScrollableScrollPhysics(),
165 | // 禁用GradView滚动事件
166 | itemCount: _categoriseList.length,
167 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
168 | crossAxisCount: 5),
169 | itemBuilder: (BuildContext context, int index) {
170 | return getCategoryItemContainer(_categoriseList[index]);
171 | }),
172 | ),
173 | ),
174 | ),
175 | );
176 | }
177 |
178 | Widget getCategoryItemContainer(Categories item) {
179 | return Column(
180 | mainAxisAlignment: MainAxisAlignment.start,
181 | children: [
182 | ExtendedImage.network(
183 | item.iconUrl,
184 | width: 35,
185 | cache: true,
186 | height: 35,
187 | ),
188 | Text(
189 | item.name,
190 | style: TextStyle(fontSize: 12, color: color373D52),
191 | ),
192 | ],
193 | );
194 | }
195 |
196 | Widget createGoodsGridView() {
197 | return SliverPadding(
198 | padding: EdgeInsets.only(top: 13.0, bottom: 13, left: 17.0, right: 17),
199 | sliver: SliverGrid(
200 | gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
201 | crossAxisCount: 2,
202 | mainAxisSpacing: 10,
203 | crossAxisSpacing: 8,
204 | childAspectRatio: 0.68),
205 | delegate: new SliverChildBuilderDelegate(
206 | (BuildContext context, int index) {
207 | return getGoodsItemContainer(_goodsList[index]);
208 | },
209 | childCount: _goodsList.length,
210 | )),
211 | );
212 | }
213 |
214 | Widget getGoodsItemContainer(Goods item) {
215 | return CardView(
216 | margin: EdgeInsets.all(0.0),
217 | child: Column(
218 | crossAxisAlignment: CrossAxisAlignment.start,
219 | children: [
220 | Container(
221 | height: 150,
222 | decoration: BoxDecoration(
223 | image: DecorationImage(
224 | image:
225 | ExtendedNetworkImageProvider(item.bigPhotoUrl, cache: true),
226 | fit: BoxFit.cover,
227 | ),
228 | borderRadius: BorderRadius.only(
229 | topLeft: Radius.circular(10.0),
230 | topRight: Radius.circular(10.0)),
231 | ),
232 | ),
233 | Expanded(
234 | child: Column(
235 | crossAxisAlignment: CrossAxisAlignment.start,
236 | children: [
237 | Padding(
238 | padding: EdgeInsets.only(left: 10, right: 10, top: 8),
239 | child: Text(
240 | item.title.split("|")[0] ?? "",
241 | style: TextStyle(fontSize: 13, color: color373D52),
242 | maxLines: 1,
243 | overflow: TextOverflow.ellipsis,
244 | ),
245 | ),
246 | Padding(
247 | padding: EdgeInsets.only(left: 10, right: 10, top: 1),
248 | child: Text(
249 | item.title.split("|").length > 1
250 | ? item.title.split("|")[1]
251 | : "",
252 | style: TextStyle(fontSize: 11, color: colorA8ACBC),
253 | maxLines: 2,
254 | overflow: TextOverflow.ellipsis,
255 | ),
256 | ),
257 | Padding(
258 | padding:
259 | EdgeInsets.only(left: 10, right: 10, top: 12, bottom: 12),
260 | child: Row(
261 | children: [
262 | Text(
263 | "¥" + item.basePrice.toString(),
264 | style: TextStyle(fontSize: 11, color: colorFF6C65),
265 | ),
266 | SizeBoxFactory.getHorizontalSizeBox(8),
267 | Text(
268 | "¥" + item.marketPrice.toString(),
269 | style: TextStyle(
270 | fontSize: 11,
271 | color: colorA8ACBC,
272 | decoration: TextDecoration.lineThrough),
273 | )
274 | ],
275 | ),
276 | )
277 | ],
278 | ))
279 | ],
280 | ),
281 | );
282 | }
283 | }
284 |
--------------------------------------------------------------------------------
/lib/views/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:boohee_flutter/app/route/fluro_navigator.dart';
4 | import 'package:boohee_flutter/common/colors.dart';
5 | import 'package:boohee_flutter/common/constant.dart';
6 | import 'package:boohee_flutter/model/home_tools.dart';
7 | import 'package:boohee_flutter/model/home_wall_paper.dart';
8 | import 'package:boohee_flutter/res/styles.dart';
9 | import 'package:boohee_flutter/utils/repository_utils.dart';
10 | import 'package:boohee_flutter/utils/toast_utils.dart';
11 | import 'package:boohee_flutter/widget/card_view.dart';
12 | import 'package:boohee_flutter/widget/common_search_bar.dart';
13 | import 'package:boohee_flutter/widget/header/home_wallpaper_header.dart';
14 | import 'package:boohee_flutter/widget/home_common_card.dart';
15 | import 'package:boohee_flutter/widget/main/main_widgets.dart';
16 | import 'package:flutter/material.dart';
17 | import 'package:flutter_easyrefresh/easy_refresh.dart';
18 | import 'package:rxdart/rxdart.dart';
19 |
20 | class HomePage extends StatefulWidget {
21 | @override
22 | State createState() => _HomePageState();
23 | }
24 |
25 | class _HomePageState extends State {
26 | /// 控制顶部搜索框的颜色
27 | SearchBarController _searchBarController = new SearchBarController(
28 | alpha: 0,
29 | searchBarBg: Color(0x1FFFFFFF),
30 | appbarTitleColor: colorA8ACBC,
31 | appbarLeftIcon: "ic_search_grey",
32 | appbarRightIcon: "ic_message_grey");
33 |
34 | /// 是否需要设置渐变色
35 | bool _isNeedSetAlpha = false;
36 |
37 | /// 用于单独控制搜索框的状态
38 | GlobalKey _mTitleKey = new GlobalKey();
39 |
40 | /// 顶部卡片
41 | List topCards = List();
42 | List bottomCards = List();
43 | List topCardItems = [
44 | HomeCard.DIET_SPORT_RECORD,
45 | HomeCard.WISDOM,
46 | HomeCard.HEALTH_HABITS,
47 | HomeCard.WEIGHT_RECORD,
48 | ];
49 |
50 | /// 滑动监听
51 | ScrollController _controller = new ScrollController();
52 |
53 | double percent = 0.0;
54 |
55 | @override
56 | void initState() {
57 | super.initState();
58 | loadData();
59 | //监听滚动事件,打印滚动位置
60 | _searchBarController.value.alpha = 0;
61 | _controller.addListener(() {
62 | if (_controller.offset < 0) {
63 | return;
64 | }
65 | if (_controller.offset < 100) {
66 | // 变化头部颜色
67 | _isNeedSetAlpha = true;
68 | double alpha = _controller.offset / 100;
69 | _searchBarController.value.alpha = (255 * alpha).toInt();
70 | _searchBarController.value.appbarTitleColor = colorA8ACBC;
71 | _searchBarController.value.searchBarBg = Color(0x1FFFFFFF);
72 | _searchBarController.value.appbarLeftIcon = "ic_search_grey";
73 | _searchBarController.value.appbarRightIcon = "ic_message_grey";
74 | _mTitleKey.currentState.setState(() {}); // 刷新单个控件的状态,防止卡顿
75 | } else {
76 | /// 防止多次渲染
77 | if (_isNeedSetAlpha) {
78 | _searchBarController.value.appbarLeftIcon = "ic_search_white";
79 | _searchBarController.value.appbarRightIcon = "ic_message_white";
80 | _searchBarController.value.appbarTitleColor = Colors.white;
81 | _searchBarController.value.searchBarBg = color0EB794;
82 | _searchBarController.value.alpha = 255;
83 | _mTitleKey.currentState.setState(() {});
84 | _isNeedSetAlpha = false;
85 | }
86 | }
87 | });
88 | }
89 |
90 | @override
91 | Widget build(BuildContext context) {
92 | return Stack(
93 | children: [
94 | EasyRefresh.custom(
95 | header: WallPaperHeader(
96 | wallPaperUrl:
97 | wallPaper != null ? wallPaper.welcomeImg.backImg : ""),
98 | scrollController: _controller,
99 | onRefresh: () async {
100 | NavigatorUtils.goWallPaper(
101 | context, wallPaper != null ? wallPaper.welcomeImg.backImg : "");
102 | },
103 | slivers: [
104 | SliverToBoxAdapter(
105 | child: HomeHeaderWidget(
106 | /// 壁纸+减肥进度条Widget
107 | wallImg:
108 | wallPaper != null ? wallPaper.welcomeImg.backImgSmall : "",
109 | progressPercent: percent,
110 | )),
111 | SliverList(
112 | delegate: SliverChildBuilderDelegate(
113 | (BuildContext context, int index) {
114 | Widget widget;
115 | if (topCards[index].code == HomeCard.DIET_SPORT_RECORD) {
116 | /// 饮食运动记录
117 | widget = DietSportRecordWidget(
118 | topCard: topCards[index],
119 | );
120 | } else if (topCards[index].code == HomeCard.WISDOM) {
121 | /// 智慧营养师
122 | widget = WisdomWidget(
123 | topCard: topCards[index],
124 | );
125 | } else if (topCards[index].code == HomeCard.WEIGHT_RECORD) {
126 | /// 体重记录
127 | widget = WeightRecordWidget(
128 | topCard: topCards[index],
129 | );
130 | } else if (topCards[index].code == HomeCard.HEALTH_HABITS) {
131 | widget = HealthHabitsWidget(
132 | iconUrl: "ic_home_habit",
133 | title: "健康习惯",
134 | );
135 | }
136 | return widget;
137 | }, childCount: topCards.length)),
138 | createToolsCards()
139 | ],
140 | ),
141 | SearchBar(
142 | text: "搜索食物和热量",
143 | controller: _searchBarController,
144 | key: _mTitleKey,
145 | )
146 | ],
147 | );
148 | }
149 |
150 | /// 壁纸、底部定制tab数据
151 | void loadData() {
152 | Repository.loadAsset("home_health_tools", fileDir: "home").then((json) {
153 | HomeTools homeTools = HomeTools.fromJson(Repository.toMap(json));
154 | topCards = homeTools.data
155 | .where((item) => item.visible && topCardItems.contains(item.code))
156 | .toList();
157 | bottomCards = homeTools.data
158 | .where((item) => item.visible && !topCardItems.contains(item.code))
159 | .toList();
160 | setState(() {});
161 | });
162 | Repository.loadAsset("home_wallpaper", fileDir: "home").then((json) {
163 | wallPaper = HomeWallPaper.fromJson(Repository.toMapForList(json));
164 | setState(() {});
165 | });
166 | // 体重记录圆环动画
167 | Observable.just(3).delay(new Duration(milliseconds: 3 * 1000)).listen((_) {
168 | percent = 0.8;
169 | setState(() {});
170 | });
171 | }
172 |
173 | HomeWallPaper wallPaper;
174 |
175 | /// 底部健康工具列表
176 | Widget createToolsCards() {
177 | return SliverToBoxAdapter(
178 | child: Container(
179 | margin: EdgeInsets.only(top: 13, bottom: 30),
180 | child: CardView(
181 | margin: EdgeInsets.only(
182 | left: 17,
183 | right: 17,
184 | ),
185 | child: ListView.separated(
186 | shrinkWrap: true,
187 | separatorBuilder: (BuildContext context, int index) {
188 | return Container(
189 | height: 0.0,
190 | margin: EdgeInsetsDirectional.only(start: 16, end: 16),
191 | decoration: BoxDecoration(
192 | border: Border(
193 | bottom:
194 | Divider.createBorderSide(context, color: colorEEEFF3),
195 | ),
196 | ),
197 | );
198 | },
199 | padding: EdgeInsets.only(top: 0),
200 | physics: NeverScrollableScrollPhysics(),
201 | itemBuilder: (BuildContext context, int index) {
202 | Widget widget;
203 | if (bottomCards[index].code == HomeCard.EXERCISE) {
204 | // 运动训练
205 | widget = CommonCard(
206 | onPressed: () {
207 | ToastUtils.showToast(context, bottomCards[index].name);
208 | },
209 | title: bottomCards[index].name,
210 | iconUrl: "ic_home_sport",
211 | subWidget: RichText(
212 | text: TextSpan(children: [
213 | TextSpan(
214 | text: "35 ", style: TextStyles.get11Text_00CDA2()),
215 | TextSpan(
216 | text: "分钟", style: TextStyles.get11TextA8ACBC()),
217 | ]),
218 | ));
219 | } else if (bottomCards[index].code == HomeCard.MEASURE_RECORD) {
220 | // 围度记录
221 | widget = CommonCard(
222 | onPressed: () {
223 | ToastUtils.showToast(context, bottomCards[index].name);
224 | },
225 | iconUrl: "ic_home_circumference",
226 | title: bottomCards[index].name);
227 | } else if (bottomCards[index].code == HomeCard.STEPS_RECORD) {
228 | // 步数记录
229 | widget = CommonCard(
230 | onPressed: () {
231 | ToastUtils.showToast(context, bottomCards[index].name);
232 | },
233 | iconUrl: "ic_home_step",
234 | title: bottomCards[index].name);
235 | } else if (bottomCards[index].code == HomeCard.BABY) {
236 | // 宝宝记录
237 | widget = CommonCard(
238 | onPressed: () {
239 | ToastUtils.showToast(context, bottomCards[index].name);
240 | },
241 | iconUrl: "ic_home_baby",
242 | title: bottomCards[index].name);
243 | } else if (bottomCards[index].code == HomeCard.DIET_PLAN) {
244 | // 饮食计划
245 | widget = CommonCard(
246 | onPressed: () {
247 | ToastUtils.showToast(context, bottomCards[index].name);
248 | },
249 | iconUrl: "ic_home_food_plan",
250 | title: bottomCards[index].name);
251 | } else if (bottomCards[index].code == HomeCard.SLEEP_RECORD) {
252 | // 睡眠记录
253 | widget = CommonCard(
254 | onPressed: () {
255 | ToastUtils.showToast(context, bottomCards[index].name);
256 | },
257 | iconUrl: "ic_home_sleep",
258 | title: bottomCards[index].name);
259 | } else if (bottomCards[index].code == HomeCard.PERIODS_RECORD) {
260 | // 经期记录
261 | widget = CommonCard(
262 | onPressed: () {
263 | ToastUtils.showToast(context, bottomCards[index].name);
264 | },
265 | iconUrl: "ic_home_menstruation",
266 | title: bottomCards[index].name);
267 | }
268 | return widget;
269 | },
270 | itemCount: bottomCards.length,
271 | ),
272 | ),
273 | ),
274 | );
275 | }
276 |
277 | @override
278 | void dispose() {
279 | //为了避免内存泄露,需要调用_controller.dispose
280 | _controller.dispose();
281 | _searchBarController.dispose();
282 | super.dispose();
283 | }
284 | }
285 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | analyzer:
5 | dependency: transitive
6 | description:
7 | name: analyzer
8 | url: "https://pub.flutter-io.cn"
9 | source: hosted
10 | version: "0.38.2"
11 | archive:
12 | dependency: transitive
13 | description:
14 | name: archive
15 | url: "https://pub.flutter-io.cn"
16 | source: hosted
17 | version: "2.0.11"
18 | args:
19 | dependency: transitive
20 | description:
21 | name: args
22 | url: "https://pub.flutter-io.cn"
23 | source: hosted
24 | version: "1.5.2"
25 | async:
26 | dependency: transitive
27 | description:
28 | name: async
29 | url: "https://pub.flutter-io.cn"
30 | source: hosted
31 | version: "2.4.0"
32 | auto_size:
33 | dependency: "direct main"
34 | description:
35 | path: "."
36 | ref: HEAD
37 | resolved-ref: "8fad57098f2852e7f220a6764e2eb1ff1f7dc5ad"
38 | url: "git://github.com/flutterchina/auto_size.git"
39 | source: git
40 | version: "0.0.1"
41 | banner_view:
42 | dependency: "direct main"
43 | description:
44 | name: banner_view
45 | url: "https://pub.flutter-io.cn"
46 | source: hosted
47 | version: "1.1.2"
48 | boolean_selector:
49 | dependency: transitive
50 | description:
51 | name: boolean_selector
52 | url: "https://pub.flutter-io.cn"
53 | source: hosted
54 | version: "1.0.5"
55 | build:
56 | dependency: transitive
57 | description:
58 | name: build
59 | url: "https://pub.flutter-io.cn"
60 | source: hosted
61 | version: "1.1.6"
62 | build_config:
63 | dependency: transitive
64 | description:
65 | name: build_config
66 | url: "https://pub.flutter-io.cn"
67 | source: hosted
68 | version: "0.4.1+1"
69 | build_daemon:
70 | dependency: transitive
71 | description:
72 | name: build_daemon
73 | url: "https://pub.flutter-io.cn"
74 | source: hosted
75 | version: "2.1.0"
76 | build_resolvers:
77 | dependency: transitive
78 | description:
79 | name: build_resolvers
80 | url: "https://pub.flutter-io.cn"
81 | source: hosted
82 | version: "1.0.7"
83 | build_runner:
84 | dependency: "direct dev"
85 | description:
86 | name: build_runner
87 | url: "https://pub.flutter-io.cn"
88 | source: hosted
89 | version: "1.7.0"
90 | build_runner_core:
91 | dependency: transitive
92 | description:
93 | name: build_runner_core
94 | url: "https://pub.flutter-io.cn"
95 | source: hosted
96 | version: "4.0.0"
97 | built_collection:
98 | dependency: transitive
99 | description:
100 | name: built_collection
101 | url: "https://pub.flutter-io.cn"
102 | source: hosted
103 | version: "4.2.2"
104 | built_value:
105 | dependency: transitive
106 | description:
107 | name: built_value
108 | url: "https://pub.flutter-io.cn"
109 | source: hosted
110 | version: "6.7.1"
111 | charcode:
112 | dependency: transitive
113 | description:
114 | name: charcode
115 | url: "https://pub.flutter-io.cn"
116 | source: hosted
117 | version: "1.1.2"
118 | checked_yaml:
119 | dependency: transitive
120 | description:
121 | name: checked_yaml
122 | url: "https://pub.flutter-io.cn"
123 | source: hosted
124 | version: "1.0.2"
125 | code_builder:
126 | dependency: transitive
127 | description:
128 | name: code_builder
129 | url: "https://pub.flutter-io.cn"
130 | source: hosted
131 | version: "3.2.0"
132 | collection:
133 | dependency: transitive
134 | description:
135 | name: collection
136 | url: "https://pub.flutter-io.cn"
137 | source: hosted
138 | version: "1.14.11"
139 | common_utils:
140 | dependency: transitive
141 | description:
142 | name: common_utils
143 | url: "https://pub.flutter-io.cn"
144 | source: hosted
145 | version: "1.1.3"
146 | convert:
147 | dependency: transitive
148 | description:
149 | name: convert
150 | url: "https://pub.flutter-io.cn"
151 | source: hosted
152 | version: "2.1.1"
153 | cookie_jar:
154 | dependency: transitive
155 | description:
156 | name: cookie_jar
157 | url: "https://pub.flutter-io.cn"
158 | source: hosted
159 | version: "1.0.1"
160 | crypto:
161 | dependency: "direct dev"
162 | description:
163 | name: crypto
164 | url: "https://pub.flutter-io.cn"
165 | source: hosted
166 | version: "2.1.3"
167 | csslib:
168 | dependency: transitive
169 | description:
170 | name: csslib
171 | url: "https://pub.flutter-io.cn"
172 | source: hosted
173 | version: "0.16.1"
174 | cupertino_icons:
175 | dependency: "direct main"
176 | description:
177 | name: cupertino_icons
178 | url: "https://pub.flutter-io.cn"
179 | source: hosted
180 | version: "0.1.2"
181 | dart_style:
182 | dependency: transitive
183 | description:
184 | name: dart_style
185 | url: "https://pub.flutter-io.cn"
186 | source: hosted
187 | version: "1.2.10"
188 | decimal:
189 | dependency: transitive
190 | description:
191 | name: decimal
192 | url: "https://pub.flutter-io.cn"
193 | source: hosted
194 | version: "0.3.5"
195 | dio:
196 | dependency: "direct main"
197 | description:
198 | name: dio
199 | url: "https://pub.flutter-io.cn"
200 | source: hosted
201 | version: "2.1.7"
202 | extended_image:
203 | dependency: "direct main"
204 | description:
205 | name: extended_image
206 | url: "https://pub.flutter-io.cn"
207 | source: hosted
208 | version: "0.6.8"
209 | extended_image_library:
210 | dependency: transitive
211 | description:
212 | name: extended_image_library
213 | url: "https://pub.flutter-io.cn"
214 | source: hosted
215 | version: "0.1.9"
216 | fixnum:
217 | dependency: transitive
218 | description:
219 | name: fixnum
220 | url: "https://pub.flutter-io.cn"
221 | source: hosted
222 | version: "0.10.9"
223 | fl_chart:
224 | dependency: "direct main"
225 | description:
226 | name: fl_chart
227 | url: "https://pub.flutter-io.cn"
228 | source: hosted
229 | version: "0.2.2"
230 | fluro:
231 | dependency: "direct main"
232 | description:
233 | name: fluro
234 | url: "https://pub.flutter-io.cn"
235 | source: hosted
236 | version: "1.5.1"
237 | flustars:
238 | dependency: "direct main"
239 | description:
240 | name: flustars
241 | url: "https://pub.flutter-io.cn"
242 | source: hosted
243 | version: "0.2.6+1"
244 | flutter:
245 | dependency: "direct main"
246 | description: flutter
247 | source: sdk
248 | version: "0.0.0"
249 | flutter_easyrefresh:
250 | dependency: "direct main"
251 | description:
252 | name: flutter_easyrefresh
253 | url: "https://pub.flutter-io.cn"
254 | source: hosted
255 | version: "2.0.4"
256 | flutter_test:
257 | dependency: "direct dev"
258 | description: flutter
259 | source: sdk
260 | version: "0.0.0"
261 | front_end:
262 | dependency: transitive
263 | description:
264 | name: front_end
265 | url: "https://pub.flutter-io.cn"
266 | source: hosted
267 | version: "0.1.24"
268 | glob:
269 | dependency: transitive
270 | description:
271 | name: glob
272 | url: "https://pub.flutter-io.cn"
273 | source: hosted
274 | version: "1.1.7"
275 | graphs:
276 | dependency: transitive
277 | description:
278 | name: graphs
279 | url: "https://pub.flutter-io.cn"
280 | source: hosted
281 | version: "0.2.0"
282 | html:
283 | dependency: transitive
284 | description:
285 | name: html
286 | url: "https://pub.flutter-io.cn"
287 | source: hosted
288 | version: "0.14.0+2"
289 | http:
290 | dependency: transitive
291 | description:
292 | name: http
293 | url: "https://pub.flutter-io.cn"
294 | source: hosted
295 | version: "0.12.0+2"
296 | http_client_helper:
297 | dependency: transitive
298 | description:
299 | name: http_client_helper
300 | url: "https://pub.flutter-io.cn"
301 | source: hosted
302 | version: "0.2.1"
303 | http_multi_server:
304 | dependency: transitive
305 | description:
306 | name: http_multi_server
307 | url: "https://pub.flutter-io.cn"
308 | source: hosted
309 | version: "2.1.0"
310 | http_parser:
311 | dependency: transitive
312 | description:
313 | name: http_parser
314 | url: "https://pub.flutter-io.cn"
315 | source: hosted
316 | version: "3.1.3"
317 | image:
318 | dependency: transitive
319 | description:
320 | name: image
321 | url: "https://pub.flutter-io.cn"
322 | source: hosted
323 | version: "2.1.4"
324 | io:
325 | dependency: transitive
326 | description:
327 | name: io
328 | url: "https://pub.flutter-io.cn"
329 | source: hosted
330 | version: "0.3.3"
331 | js:
332 | dependency: transitive
333 | description:
334 | name: js
335 | url: "https://pub.flutter-io.cn"
336 | source: hosted
337 | version: "0.6.1+1"
338 | json_annotation:
339 | dependency: "direct main"
340 | description:
341 | name: json_annotation
342 | url: "https://pub.flutter-io.cn"
343 | source: hosted
344 | version: "3.0.0"
345 | json_serializable:
346 | dependency: "direct dev"
347 | description:
348 | name: json_serializable
349 | url: "https://pub.flutter-io.cn"
350 | source: hosted
351 | version: "3.2.2"
352 | kernel:
353 | dependency: transitive
354 | description:
355 | name: kernel
356 | url: "https://pub.flutter-io.cn"
357 | source: hosted
358 | version: "0.3.24"
359 | logging:
360 | dependency: transitive
361 | description:
362 | name: logging
363 | url: "https://pub.flutter-io.cn"
364 | source: hosted
365 | version: "0.11.3+2"
366 | matcher:
367 | dependency: transitive
368 | description:
369 | name: matcher
370 | url: "https://pub.flutter-io.cn"
371 | source: hosted
372 | version: "0.12.6"
373 | meta:
374 | dependency: transitive
375 | description:
376 | name: meta
377 | url: "https://pub.flutter-io.cn"
378 | source: hosted
379 | version: "1.1.8"
380 | mime:
381 | dependency: transitive
382 | description:
383 | name: mime
384 | url: "https://pub.flutter-io.cn"
385 | source: hosted
386 | version: "0.9.6+3"
387 | package_config:
388 | dependency: transitive
389 | description:
390 | name: package_config
391 | url: "https://pub.flutter-io.cn"
392 | source: hosted
393 | version: "1.1.0"
394 | package_resolver:
395 | dependency: transitive
396 | description:
397 | name: package_resolver
398 | url: "https://pub.flutter-io.cn"
399 | source: hosted
400 | version: "1.0.10"
401 | path:
402 | dependency: transitive
403 | description:
404 | name: path
405 | url: "https://pub.flutter-io.cn"
406 | source: hosted
407 | version: "1.6.4"
408 | path_provider:
409 | dependency: transitive
410 | description:
411 | name: path_provider
412 | url: "https://pub.flutter-io.cn"
413 | source: hosted
414 | version: "1.3.0"
415 | pedantic:
416 | dependency: transitive
417 | description:
418 | name: pedantic
419 | url: "https://pub.flutter-io.cn"
420 | source: hosted
421 | version: "1.8.0+1"
422 | percent_indicator:
423 | dependency: "direct main"
424 | description:
425 | name: percent_indicator
426 | url: "https://pub.flutter-io.cn"
427 | source: hosted
428 | version: "2.1.1+1"
429 | petitparser:
430 | dependency: transitive
431 | description:
432 | name: petitparser
433 | url: "https://pub.flutter-io.cn"
434 | source: hosted
435 | version: "2.4.0"
436 | platform:
437 | dependency: transitive
438 | description:
439 | name: platform
440 | url: "https://pub.flutter-io.cn"
441 | source: hosted
442 | version: "2.2.1"
443 | pool:
444 | dependency: transitive
445 | description:
446 | name: pool
447 | url: "https://pub.flutter-io.cn"
448 | source: hosted
449 | version: "1.4.0"
450 | pub_semver:
451 | dependency: transitive
452 | description:
453 | name: pub_semver
454 | url: "https://pub.flutter-io.cn"
455 | source: hosted
456 | version: "1.4.2"
457 | pubspec_parse:
458 | dependency: transitive
459 | description:
460 | name: pubspec_parse
461 | url: "https://pub.flutter-io.cn"
462 | source: hosted
463 | version: "0.1.5"
464 | quiver:
465 | dependency: transitive
466 | description:
467 | name: quiver
468 | url: "https://pub.flutter-io.cn"
469 | source: hosted
470 | version: "2.0.5"
471 | rational:
472 | dependency: transitive
473 | description:
474 | name: rational
475 | url: "https://pub.flutter-io.cn"
476 | source: hosted
477 | version: "0.3.6"
478 | rxdart:
479 | dependency: "direct dev"
480 | description:
481 | name: rxdart
482 | url: "https://pub.flutter-io.cn"
483 | source: hosted
484 | version: "0.22.2"
485 | shared_preferences:
486 | dependency: transitive
487 | description:
488 | name: shared_preferences
489 | url: "https://pub.flutter-io.cn"
490 | source: hosted
491 | version: "0.5.3+4"
492 | shelf:
493 | dependency: transitive
494 | description:
495 | name: shelf
496 | url: "https://pub.flutter-io.cn"
497 | source: hosted
498 | version: "0.7.5"
499 | shelf_web_socket:
500 | dependency: transitive
501 | description:
502 | name: shelf_web_socket
503 | url: "https://pub.flutter-io.cn"
504 | source: hosted
505 | version: "0.2.3"
506 | sky_engine:
507 | dependency: transitive
508 | description: flutter
509 | source: sdk
510 | version: "0.0.99"
511 | source_gen:
512 | dependency: transitive
513 | description:
514 | name: source_gen
515 | url: "https://pub.flutter-io.cn"
516 | source: hosted
517 | version: "0.9.4+4"
518 | source_span:
519 | dependency: transitive
520 | description:
521 | name: source_span
522 | url: "https://pub.flutter-io.cn"
523 | source: hosted
524 | version: "1.5.5"
525 | stack_trace:
526 | dependency: transitive
527 | description:
528 | name: stack_trace
529 | url: "https://pub.flutter-io.cn"
530 | source: hosted
531 | version: "1.9.3"
532 | stream_channel:
533 | dependency: transitive
534 | description:
535 | name: stream_channel
536 | url: "https://pub.flutter-io.cn"
537 | source: hosted
538 | version: "2.0.0"
539 | stream_transform:
540 | dependency: transitive
541 | description:
542 | name: stream_transform
543 | url: "https://pub.flutter-io.cn"
544 | source: hosted
545 | version: "0.0.19"
546 | string_scanner:
547 | dependency: transitive
548 | description:
549 | name: string_scanner
550 | url: "https://pub.flutter-io.cn"
551 | source: hosted
552 | version: "1.0.5"
553 | synchronized:
554 | dependency: "direct dev"
555 | description:
556 | name: synchronized
557 | url: "https://pub.flutter-io.cn"
558 | source: hosted
559 | version: "2.1.0+1"
560 | term_glyph:
561 | dependency: transitive
562 | description:
563 | name: term_glyph
564 | url: "https://pub.flutter-io.cn"
565 | source: hosted
566 | version: "1.1.0"
567 | test_api:
568 | dependency: transitive
569 | description:
570 | name: test_api
571 | url: "https://pub.flutter-io.cn"
572 | source: hosted
573 | version: "0.2.11"
574 | timing:
575 | dependency: transitive
576 | description:
577 | name: timing
578 | url: "https://pub.flutter-io.cn"
579 | source: hosted
580 | version: "0.1.1+2"
581 | toast:
582 | dependency: "direct main"
583 | description:
584 | name: toast
585 | url: "https://pub.flutter-io.cn"
586 | source: hosted
587 | version: "0.1.5"
588 | typed_data:
589 | dependency: transitive
590 | description:
591 | name: typed_data
592 | url: "https://pub.flutter-io.cn"
593 | source: hosted
594 | version: "1.1.6"
595 | vector_math:
596 | dependency: transitive
597 | description:
598 | name: vector_math
599 | url: "https://pub.flutter-io.cn"
600 | source: hosted
601 | version: "2.0.8"
602 | watcher:
603 | dependency: transitive
604 | description:
605 | name: watcher
606 | url: "https://pub.flutter-io.cn"
607 | source: hosted
608 | version: "0.9.7+12"
609 | web_socket_channel:
610 | dependency: transitive
611 | description:
612 | name: web_socket_channel
613 | url: "https://pub.flutter-io.cn"
614 | source: hosted
615 | version: "1.0.15"
616 | webview_flutter:
617 | dependency: "direct main"
618 | description:
619 | name: webview_flutter
620 | url: "https://pub.flutter-io.cn"
621 | source: hosted
622 | version: "0.3.14+1"
623 | xml:
624 | dependency: transitive
625 | description:
626 | name: xml
627 | url: "https://pub.flutter-io.cn"
628 | source: hosted
629 | version: "3.5.0"
630 | yaml:
631 | dependency: transitive
632 | description:
633 | name: yaml
634 | url: "https://pub.flutter-io.cn"
635 | source: hosted
636 | version: "2.1.16"
637 | sdks:
638 | dart: ">=2.4.0 <3.0.0"
639 | flutter: ">=1.5.0 <2.0.0"
640 |
--------------------------------------------------------------------------------