├── .gitignore ├── .metadata ├── .vscode ├── launch.json └── settings.json ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── flutter_ui_challenge │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── data │ ├── bank.json │ ├── bank_2.json │ ├── city.json │ ├── sort_0.json │ ├── sort_1.json │ └── sort_2.json ├── fonts │ └── Roboto-Thin.ttf ├── images │ ├── account │ │ ├── bg.png │ │ ├── del.png │ │ ├── gongshang.png │ │ ├── jianhang.png │ │ ├── jiaohang.png │ │ ├── minsheng.png │ │ ├── nonghang.png │ │ ├── pufa.png │ │ ├── rmb.png │ │ ├── selected.png │ │ ├── sm.png │ │ ├── sqcg.png │ │ ├── sqsb.png │ │ ├── txwxz.png │ │ ├── txxz.png │ │ ├── wechat.png │ │ ├── xingye.png │ │ ├── yhk.png │ │ ├── zhaohang.png │ │ ├── zhonghang.png │ │ └── zhongxin.png │ ├── app_start_1.webp │ ├── app_start_2.webp │ ├── app_start_3.webp │ ├── goods │ │ ├── add.png │ │ ├── add2.png │ │ ├── ellipsis.png │ │ ├── expand.png │ │ ├── goods_delete.png │ │ ├── goods_size_1.png │ │ ├── goods_size_2.png │ │ ├── icon_dialog_close.png │ │ ├── icon_goods.png │ │ ├── icon_sm.png │ │ ├── jt.png │ │ ├── scanning.png │ │ ├── search.png │ │ ├── xz.png │ │ └── ydss.png │ ├── home │ │ ├── icon_commodity.png │ │ ├── icon_order.png │ │ ├── icon_shop.png │ │ └── icon_statistics.png │ ├── ic_arrow_right.png │ ├── ic_back_black.png │ ├── login │ │ ├── qyg_shop_icon_delete.png │ │ ├── qyg_shop_icon_display.png │ │ └── qyg_shop_icon_hide.png │ ├── logo.png │ ├── none.png │ ├── order │ │ ├── dark │ │ │ ├── icon_address.png │ │ │ ├── icon_dps_n.png │ │ │ ├── icon_dps_s.png │ │ │ ├── icon_dwc_n.png │ │ │ ├── icon_dwc_s.png │ │ │ ├── icon_phone.png │ │ │ ├── icon_selected.png │ │ │ ├── icon_xdd_n.png │ │ │ ├── icon_xdd_s.png │ │ │ ├── icon_yqx_n.png │ │ │ ├── icon_yqx_s.png │ │ │ ├── icon_ywc_n.png │ │ │ └── icon_ywc_s.png │ │ ├── dps_n.png │ │ ├── dps_s.png │ │ ├── dwc_n.png │ │ ├── dwc_s.png │ │ ├── ic_check.png │ │ ├── icon_address.png │ │ ├── icon_avatar.png │ │ ├── icon_calendar.png │ │ ├── icon_calendar_dark.png │ │ ├── icon_goods.png │ │ ├── icon_phone.png │ │ ├── icon_search.png │ │ ├── order_bg.png │ │ ├── order_bg1.png │ │ ├── order_delete.png │ │ ├── order_search.png │ │ ├── xdd_n.png │ │ ├── xdd_s.png │ │ ├── yqx_n.png │ │ ├── yqx_s.png │ │ ├── ywc_n.png │ │ └── ywc_s.png │ ├── shop │ │ ├── dark_dpsz.png │ │ ├── dark_txzh.png │ │ ├── dark_zhls.png │ │ ├── dark_zjgl.png │ │ ├── dpsz.png │ │ ├── message.png │ │ ├── setting.png │ │ ├── tj.png │ │ ├── tx.png │ │ ├── txzh.png │ │ ├── wxzyf.png │ │ ├── xz.png │ │ ├── xztm.png │ │ ├── xzyf.png │ │ ├── zhls.png │ │ ├── zjgl.png │ │ └── zybq.png │ ├── state │ │ ├── zwdd.png │ │ ├── zwsp.png │ │ ├── zwwl.png │ │ ├── zwxx.png │ │ └── zwzh.png │ ├── statistic │ │ ├── champion.png │ │ ├── chart_fg.png │ │ ├── down.png │ │ ├── dps.png │ │ ├── icon_selected.png │ │ ├── jrjye.png │ │ ├── jyetj.png │ │ ├── runnerup.png │ │ ├── sjzs.png │ │ ├── sptj.png │ │ ├── statistic_bg.png │ │ ├── statistic_bg1.png │ │ ├── thirdplace.png │ │ ├── up.png │ │ └── xdd.png │ ├── store │ │ ├── 2.0x │ │ │ ├── icon_failure.png │ │ │ ├── icon_success.png │ │ │ ├── icon_wait.png │ │ │ └── icon_zj.png │ │ ├── 3.0x │ │ │ ├── icon_failure.png │ │ │ ├── icon_success.png │ │ │ ├── icon_wait.png │ │ │ └── icon_zj.png │ │ ├── icon_failure.png │ │ ├── icon_success.png │ │ ├── icon_wait.png │ │ └── icon_zj.png │ └── update_head.jpg └── lottie │ └── bunny_new_mouth.json ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ └── Icon-App-60x60@3x.png │ ├── Contents.json │ └── logo.imageset │ │ ├── Contents.json │ │ └── logo.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── change_app_page.dart ├── examples │ ├── flutter_deer │ │ ├── common │ │ │ ├── config_providers.dart │ │ │ ├── constant.dart │ │ │ ├── deer_storage.dart │ │ │ └── user_provider.dart │ │ ├── deer_app.dart │ │ ├── modules │ │ │ ├── goods │ │ │ │ ├── goods_route.dart │ │ │ │ ├── models │ │ │ │ │ └── goods_type_model │ │ │ │ │ │ ├── goods_type_model.dart │ │ │ │ │ │ ├── goods_type_model.freezed.dart │ │ │ │ │ │ └── goods_type_model.g.dart │ │ │ │ ├── page │ │ │ │ │ ├── goods_edit_page.dart │ │ │ │ │ └── goods_page.dart │ │ │ │ ├── providers │ │ │ │ │ ├── goods_edit_providers.dart │ │ │ │ │ ├── goods_list_providers.dart │ │ │ │ │ ├── goods_providers.dart │ │ │ │ │ └── goods_type_choose_providers.dart │ │ │ │ └── widgets │ │ │ │ │ ├── goods_head_title.dart │ │ │ │ │ ├── goods_list_view.dart │ │ │ │ │ ├── goods_page_option.dart │ │ │ │ │ ├── goods_spec_edit.dart │ │ │ │ │ ├── goods_type_choose.dart │ │ │ │ │ └── goods_type_choose_sheet.dart │ │ │ ├── home │ │ │ │ ├── common_router.dart │ │ │ │ ├── deer_main_page.dart │ │ │ │ ├── loading_page.dart │ │ │ │ ├── providers │ │ │ │ │ └── home_providers.dart │ │ │ │ ├── splash_page.dart │ │ │ │ └── web_page.dart │ │ │ ├── login │ │ │ │ ├── login_route.dart │ │ │ │ ├── page │ │ │ │ │ ├── code_login_page.dart │ │ │ │ │ └── login_page.dart │ │ │ │ └── providers │ │ │ │ │ └── code_login_providers.dart │ │ │ ├── order │ │ │ │ ├── models │ │ │ │ │ └── order_models.dart │ │ │ │ ├── order_router.dart │ │ │ │ ├── page │ │ │ │ │ ├── order_detail_page.dart │ │ │ │ │ ├── order_list_page.dart │ │ │ │ │ ├── order_page.dart │ │ │ │ │ ├── order_search_page.dart │ │ │ │ │ └── order_track_page.dart │ │ │ │ ├── provider │ │ │ │ │ ├── order_header_provider.dart │ │ │ │ │ └── order_list_provider.dart │ │ │ │ └── widgets │ │ │ │ │ ├── order_details_payment_dialog.dart │ │ │ │ │ ├── order_header.dart │ │ │ │ │ ├── order_list_item.dart │ │ │ │ │ ├── order_tag_item.dart │ │ │ │ │ ├── order_type_choose.dart │ │ │ │ │ └── payment_choose_dialog.dart │ │ │ ├── settings │ │ │ │ ├── page │ │ │ │ │ └── setting_page.dart │ │ │ │ ├── setting_router.dart │ │ │ │ └── widgets │ │ │ │ │ └── setting_item.dart │ │ │ ├── shop │ │ │ │ ├── model │ │ │ │ │ ├── bank_model │ │ │ │ │ │ ├── bank_model.dart │ │ │ │ │ │ └── bank_model.g.dart │ │ │ │ │ ├── city_model │ │ │ │ │ │ ├── city_model.dart │ │ │ │ │ │ └── city_model.g.dart │ │ │ │ │ ├── shop_config_model │ │ │ │ │ │ ├── shop_config_model.dart │ │ │ │ │ │ └── shop_config_model.g.dart │ │ │ │ │ ├── shop_record_model.dart │ │ │ │ │ └── shop_withdraw_models.dart │ │ │ │ ├── page │ │ │ │ │ ├── shop_add_withdraw_page.dart │ │ │ │ │ ├── shop_capital_page.dart │ │ │ │ │ ├── shop_config_edit_page.dart │ │ │ │ │ ├── shop_config_page.dart │ │ │ │ │ ├── shop_info_choose_page.dart │ │ │ │ │ ├── shop_page.dart │ │ │ │ │ ├── shop_record_page.dart │ │ │ │ │ ├── shop_withdraw_account_page.dart │ │ │ │ │ ├── shop_withdraw_change_pwd_page.dart │ │ │ │ │ ├── shop_withdraw_choose_page.dart │ │ │ │ │ ├── shop_withdraw_page.dart │ │ │ │ │ └── shop_withdraw_pwd_page.dart │ │ │ │ ├── provider │ │ │ │ │ ├── shop_config_providers.dart │ │ │ │ │ ├── shop_info_choose_providers.dart │ │ │ │ │ ├── shop_record_providers.dart │ │ │ │ │ ├── shop_witdraw_add_providers.dart │ │ │ │ │ ├── shop_withdraw_account_providers.dart │ │ │ │ │ ├── shop_withdraw_choose_providers.dart │ │ │ │ │ └── shop_withdraw_providers.dart │ │ │ │ ├── shop_router.dart │ │ │ │ └── widgets │ │ │ │ │ ├── shop_actions.dart │ │ │ │ │ ├── shop_config_freight.dart │ │ │ │ │ ├── shop_config_payment.dart │ │ │ │ │ ├── shop_config_price_edit.dart │ │ │ │ │ ├── shop_header.dart │ │ │ │ │ ├── shop_info_choose_indicator.dart │ │ │ │ │ ├── shop_pwd_code_view.dart │ │ │ │ │ ├── shop_pwd_dialog.dart │ │ │ │ │ ├── shop_pwd_sms_dialog.dart │ │ │ │ │ ├── shop_withdraw_account.dart │ │ │ │ │ ├── shop_withdraw_account_item.dart │ │ │ │ │ └── shop_withdraw_account_type_choose.dart │ │ │ └── statistics │ │ │ │ ├── models │ │ │ │ └── statistics_goods_model.dart │ │ │ │ ├── page │ │ │ │ ├── statistics_goods_page.dart │ │ │ │ ├── statistics_info_page.dart │ │ │ │ └── statistics_page.dart │ │ │ │ ├── provider │ │ │ │ ├── statistics_calendar_providers.dart │ │ │ │ └── statistics_goods_providers.dart │ │ │ │ ├── statistics_router.dart │ │ │ │ ├── utils │ │ │ │ └── calendar_utils.dart │ │ │ │ └── widgets │ │ │ │ ├── statistics_calendar.dart │ │ │ │ ├── statistics_circle_chart.dart │ │ │ │ ├── statistics_goods_circle_chart.dart │ │ │ │ ├── statistics_goods_circle_painter.dart │ │ │ │ ├── statistics_goods_item.dart │ │ │ │ ├── statistics_header_content.dart │ │ │ │ ├── statistics_header_delegate.dart │ │ │ │ ├── statistics_item.dart │ │ │ │ ├── statistics_line_chart.dart │ │ │ │ ├── statistics_order_chart.dart │ │ │ │ └── statistics_order_item.dart │ │ ├── res │ │ │ ├── colors.dart │ │ │ └── text_styles.dart │ │ ├── routers │ │ │ ├── deer_routers.dart │ │ │ ├── deer_theme.dart │ │ │ ├── navigator_interpector.dart │ │ │ ├── navigator_utils.dart │ │ │ └── not_found_page.dart │ │ ├── utils │ │ │ ├── dialog_utils.dart │ │ │ ├── image_utils.dart │ │ │ ├── overlay_utils.dart │ │ │ ├── page_request.dart │ │ │ ├── random_utils.dart │ │ │ ├── screen_untils.dart │ │ │ ├── string_extension.dart │ │ │ └── toast.dart │ │ └── widgets │ │ │ ├── action_sheet.dart │ │ │ ├── alert_view.dart │ │ │ ├── always_keep_alive.dart │ │ │ ├── code_view.dart │ │ │ ├── common_dialog.dart │ │ │ ├── custom_show_loading.dart │ │ │ ├── custon_back_button.dart │ │ │ ├── empty_view.dart │ │ │ ├── input_dialog.dart │ │ │ ├── list_click_item.dart │ │ │ ├── load_image.dart │ │ │ ├── load_more_footer.dart │ │ │ ├── menu_filter.dart │ │ │ ├── my_app_bar.dart │ │ │ ├── my_edit_scroll_view.dart │ │ │ ├── my_scroll_view.dart │ │ │ ├── number_key_borad.dart │ │ │ ├── option_selected_view.dart │ │ │ ├── search_bar.dart │ │ │ └── simple_textfield.dart │ └── ui_chanllenge │ │ ├── curves │ │ ├── curve_type.dart │ │ ├── curves_item.dart │ │ └── curves_page.dart │ │ ├── custom_slider │ │ ├── custom_slider.dart │ │ └── custom_slider_page.dart │ │ ├── flutter_challenge_page.dart │ │ ├── routes.dart │ │ └── theme.dart └── main.dart ├── linux ├── .gitignore ├── CMakeLists.txt ├── flutter │ ├── CMakeLists.txt │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── main.cc ├── my_application.cc └── my_application.h ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── app_icon_1024.png │ │ ├── app_icon_128.png │ │ ├── app_icon_16.png │ │ ├── app_icon_256.png │ │ ├── app_icon_32.png │ │ ├── app_icon_512.png │ │ └── app_icon_64.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements ├── pubspec.lock ├── pubspec.yaml ├── web ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-192.png │ └── Icon-maskable-512.png ├── index.html └── manifest.json └── windows ├── .gitignore ├── CMakeLists.txt ├── flutter ├── CMakeLists.txt ├── generated_plugin_registrant.cc ├── generated_plugin_registrant.h └── generated_plugins.cmake └── runner ├── CMakeLists.txt ├── Runner.rc ├── flutter_window.cpp ├── flutter_window.h ├── main.cpp ├── resource.h ├── resources └── app_icon.ico ├── runner.exe.manifest ├── utils.cpp ├── utils.h ├── win32_window.cpp └── win32_window.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Web related 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /.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. 5 | 6 | version: 7 | revision: f1875d570e39de09040c8f79aa13cc56baab8db1 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 17 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 18 | - platform: android 19 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 20 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 21 | - platform: ios 22 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 23 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 24 | - platform: linux 25 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 26 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 27 | - platform: macos 28 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 29 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 30 | - platform: web 31 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 32 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 33 | - platform: windows 34 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 35 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "flutter_ui_challenge", 9 | "request": "launch", 10 | "type": "dart" 11 | }, 12 | { 13 | "name": "flutter_ui_challenge (profile mode)", 14 | "request": "launch", 15 | "type": "dart", 16 | "flutterMode": "profile" 17 | }, 18 | { 19 | "name": "flutter_ui_challenge (release mode)", 20 | "request": "launch", 21 | "type": "dart", 22 | "flutterMode": "release" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic", 3 | "dart.flutterSdkPath": "/Users/Ming/development/flutter-3.10.5", 4 | "dart.sdkPath": "/Users/Ming/development/flutter-3.10.5/bin/cache/dart-sdk" 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_ui_challenge 2 | 3 | 后续可能包含任何flutter实现,目前主要是仿写flutter_deer 4 | 5 | # flutter_deer 6 | 7 | 效果图见下方 8 | 9 | | ![订单](https://user-images.githubusercontent.com/19296728/188067072-fb7cad6f-806e-4275-a315-8edc87c99dd5.gif) | ![订单详情](https://user-images.githubusercontent.com/19296728/188067355-6e746e1d-e15d-4f16-9a3d-85ab5ac6b3d1.gif) | ![商品首页](https://user-images.githubusercontent.com/19296728/188067483-314fde9a-685d-4f34-bdd1-71dc3a8c4e57.gif) | ![商品编辑](https://user-images.githubusercontent.com/19296728/188067563-244bd785-db61-479e-bb16-5d8da600e4d8.gif) | 10 | | :--------------------------------: | :---------------------------------: | :-------------------------------: | :-------------------------------: | 11 | | ![统计](https://user-images.githubusercontent.com/19296728/188068070-d42da5f0-9f72-41e8-9a90-11e097bbd229.gif) | ![统计详情](https://user-images.githubusercontent.com/19296728/188068073-2abd23c4-cf7c-4281-88f2-5d1a6862f2f3.gif) | ![账户流水](https://user-images.githubusercontent.com/19296728/188068827-052cf5b9-c956-4a9a-8ae7-ba6728157470.gif) | ![提现](https://user-images.githubusercontent.com/19296728/188068994-842b987e-99d4-489d-8abc-b49215536d95.gif) | ![添加](https://user-images.githubusercontent.com/19296728/188069182-aa3850be-8ff2-4af3-bb78-7990a254e012.gif) | 12 | ![提现密码](https://user-images.githubusercontent.com/19296728/188069263-8b47cf19-ee92-4d45-9dc1-b199f5ff300b.gif) | ![店铺设置](https://user-images.githubusercontent.com/19296728/188069423-8fddebdb-6180-46e6-9b2a-fb7e1b298875.gif) | | 13 | 14 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at 17 | # https://dart-lang.github.io/linter/lints/index.html. 18 | # 19 | # Instead of disabling a lint rule for the entire project in the 20 | # section below, it can also be suppressed for a single line of code 21 | # or a specific dart file by using the `// ignore: name_of_lint` and 22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 23 | # producing the lint. 24 | rules: 25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 27 | 28 | # Additional information about this file can be found at 29 | # https://dart.dev/guides/language/analysis-options 30 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.example.flutter_ui_challenge" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 50 | minSdkVersion localProperties.getProperty('flutter.minSdkVersion').toInteger() 51 | targetSdkVersion localProperties.getProperty('flutter.targetSdkVersion').toInteger() 52 | versionCode flutterVersionCode.toInteger() 53 | versionName flutterVersionName 54 | } 55 | 56 | 57 | buildTypes { 58 | release { 59 | // TODO: Add your own signing config for the release build. 60 | // Signing with the debug keys for now, so `flutter run --release` works. 61 | signingConfig signingConfigs.debug 62 | } 63 | } 64 | } 65 | 66 | flutter { 67 | source '../..' 68 | } 69 | 70 | dependencies { 71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 72 | } 73 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/flutter_ui_challenge/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.flutter_ui_challenge 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /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-7.4-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/data/sort_0.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "1", 4 | "name": "超市便利" 5 | }, 6 | { 7 | "id": "2", 8 | "name": "生鲜果蔬" 9 | }, 10 | { 11 | "id": "3", 12 | "name": "零食小吃" 13 | }, 14 | { 15 | "id": "4", 16 | "name": "美食餐饮" 17 | }, 18 | { 19 | "id": "5", 20 | "name": "鲜花烘培" 21 | }, 22 | { 23 | "id": "6", 24 | "name": "生活服务" 25 | }, 26 | { 27 | "id": "7", 28 | "name": "其他" 29 | }, 30 | { 31 | "id": "8", 32 | "name": "综合" 33 | }, 34 | { 35 | "id": "10", 36 | "name": "美容个护" 37 | }, 38 | { 39 | "id": "11", 40 | "name": "家居生活" 41 | }, 42 | { 43 | "id": "12", 44 | "name": "服饰箱包" 45 | }, 46 | { 47 | "id": "13", 48 | "name": "母婴玩具" 49 | }, 50 | { 51 | "id": "15", 52 | "name": "海淘进口" 53 | }, 54 | { 55 | "id": "755", 56 | "name": "快递代收" 57 | }, 58 | { 59 | "id": "756", 60 | "name": "食品保健" 61 | }, 62 | { 63 | "id": "764", 64 | "name": "家居生活" 65 | }, 66 | { 67 | "id": "769", 68 | "name": "米面杂粮" 69 | }, 70 | { 71 | "id": "786", 72 | "name": "水果生鲜" 73 | }, 74 | { 75 | "id": "807", 76 | "name": "社区健身" 77 | }, 78 | { 79 | "id": "811", 80 | "name": "艺术礼品" 81 | }, 82 | { 83 | "id": "814", 84 | "name": "今日特卖" 85 | }, 86 | { 87 | "id": "816", 88 | "name": "周边旅游" 89 | }, 90 | { 91 | "id": "820", 92 | "name": "家装建材" 93 | }, 94 | { 95 | "id": "823", 96 | "name": "虚拟商品" 97 | }, 98 | { 99 | "id": "14057", 100 | "name": "生活用品" 101 | }, 102 | { 103 | "id": "14181", 104 | "name": "手机数码" 105 | } 106 | ] -------------------------------------------------------------------------------- /assets/data/sort_1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "15677", 4 | "name": "厨房用具" 5 | }, 6 | { 7 | "id": "15690", 8 | "name": "精美餐具" 9 | }, 10 | { 11 | "id": "15698", 12 | "name": "家纺" 13 | }, 14 | { 15 | "id": "15717", 16 | "name": "家具" 17 | }, 18 | { 19 | "id": "15740", 20 | "name": "灯具" 21 | }, 22 | { 23 | "id": "15755", 24 | "name": "生活日用" 25 | }, 26 | { 27 | "id": "15765", 28 | "name": "宠物用品" 29 | }, 30 | { 31 | "id": "15773", 32 | "name": "家装建材" 33 | }, 34 | { 35 | "id": "15795", 36 | "name": "赠品" 37 | }, 38 | { 39 | "id": "15797", 40 | "name": "家装软饰" 41 | }, 42 | { 43 | "id": "15814", 44 | "name": "收纳用品" 45 | }, 46 | { 47 | "id": "26541", 48 | "name": "演出票务" 49 | }, 50 | { 51 | "id": "26551", 52 | "name": "健康体检" 53 | }, 54 | { 55 | "id": "26554", 56 | "name": "教育培训" 57 | }, 58 | { 59 | "id": "26561", 60 | "name": "汽车保养" 61 | }, 62 | { 63 | "id": "26563", 64 | "name": "影视会员" 65 | }, 66 | { 67 | "id": "26565", 68 | "name": "摄影、摄像" 69 | } 70 | ] -------------------------------------------------------------------------------- /assets/data/sort_2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "15691", 4 | "name": "酒具/杯具" 5 | }, 6 | { 7 | "id": "15692", 8 | "name": "水具" 9 | }, 10 | { 11 | "id": "15693", 12 | "name": "筷勺/刀叉" 13 | }, 14 | { 15 | "id": "15694", 16 | "name": "碗碟" 17 | }, 18 | { 19 | "id": "15695", 20 | "name": "组合套装" 21 | }, 22 | { 23 | "id": "15696", 24 | "name": "美食工具" 25 | }, 26 | { 27 | "id": "15697", 28 | "name": "茶具/咖啡具" 29 | } 30 | ] -------------------------------------------------------------------------------- /assets/fonts/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/fonts/Roboto-Thin.ttf -------------------------------------------------------------------------------- /assets/images/account/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/bg.png -------------------------------------------------------------------------------- /assets/images/account/del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/del.png -------------------------------------------------------------------------------- /assets/images/account/gongshang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/gongshang.png -------------------------------------------------------------------------------- /assets/images/account/jianhang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/jianhang.png -------------------------------------------------------------------------------- /assets/images/account/jiaohang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/jiaohang.png -------------------------------------------------------------------------------- /assets/images/account/minsheng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/minsheng.png -------------------------------------------------------------------------------- /assets/images/account/nonghang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/nonghang.png -------------------------------------------------------------------------------- /assets/images/account/pufa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/pufa.png -------------------------------------------------------------------------------- /assets/images/account/rmb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/rmb.png -------------------------------------------------------------------------------- /assets/images/account/selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/selected.png -------------------------------------------------------------------------------- /assets/images/account/sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/sm.png -------------------------------------------------------------------------------- /assets/images/account/sqcg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/sqcg.png -------------------------------------------------------------------------------- /assets/images/account/sqsb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/sqsb.png -------------------------------------------------------------------------------- /assets/images/account/txwxz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/txwxz.png -------------------------------------------------------------------------------- /assets/images/account/txxz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/txxz.png -------------------------------------------------------------------------------- /assets/images/account/wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/wechat.png -------------------------------------------------------------------------------- /assets/images/account/xingye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/xingye.png -------------------------------------------------------------------------------- /assets/images/account/yhk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/yhk.png -------------------------------------------------------------------------------- /assets/images/account/zhaohang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/zhaohang.png -------------------------------------------------------------------------------- /assets/images/account/zhonghang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/zhonghang.png -------------------------------------------------------------------------------- /assets/images/account/zhongxin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/account/zhongxin.png -------------------------------------------------------------------------------- /assets/images/app_start_1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/app_start_1.webp -------------------------------------------------------------------------------- /assets/images/app_start_2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/app_start_2.webp -------------------------------------------------------------------------------- /assets/images/app_start_3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/app_start_3.webp -------------------------------------------------------------------------------- /assets/images/goods/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/add.png -------------------------------------------------------------------------------- /assets/images/goods/add2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/add2.png -------------------------------------------------------------------------------- /assets/images/goods/ellipsis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/ellipsis.png -------------------------------------------------------------------------------- /assets/images/goods/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/expand.png -------------------------------------------------------------------------------- /assets/images/goods/goods_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/goods_delete.png -------------------------------------------------------------------------------- /assets/images/goods/goods_size_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/goods_size_1.png -------------------------------------------------------------------------------- /assets/images/goods/goods_size_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/goods_size_2.png -------------------------------------------------------------------------------- /assets/images/goods/icon_dialog_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/icon_dialog_close.png -------------------------------------------------------------------------------- /assets/images/goods/icon_goods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/icon_goods.png -------------------------------------------------------------------------------- /assets/images/goods/icon_sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/icon_sm.png -------------------------------------------------------------------------------- /assets/images/goods/jt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/jt.png -------------------------------------------------------------------------------- /assets/images/goods/scanning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/scanning.png -------------------------------------------------------------------------------- /assets/images/goods/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/search.png -------------------------------------------------------------------------------- /assets/images/goods/xz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/xz.png -------------------------------------------------------------------------------- /assets/images/goods/ydss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/goods/ydss.png -------------------------------------------------------------------------------- /assets/images/home/icon_commodity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/home/icon_commodity.png -------------------------------------------------------------------------------- /assets/images/home/icon_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/home/icon_order.png -------------------------------------------------------------------------------- /assets/images/home/icon_shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/home/icon_shop.png -------------------------------------------------------------------------------- /assets/images/home/icon_statistics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/home/icon_statistics.png -------------------------------------------------------------------------------- /assets/images/ic_arrow_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/ic_arrow_right.png -------------------------------------------------------------------------------- /assets/images/ic_back_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/ic_back_black.png -------------------------------------------------------------------------------- /assets/images/login/qyg_shop_icon_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/login/qyg_shop_icon_delete.png -------------------------------------------------------------------------------- /assets/images/login/qyg_shop_icon_display.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/login/qyg_shop_icon_display.png -------------------------------------------------------------------------------- /assets/images/login/qyg_shop_icon_hide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/login/qyg_shop_icon_hide.png -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/logo.png -------------------------------------------------------------------------------- /assets/images/none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/none.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_address.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_dps_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_dps_n.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_dps_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_dps_s.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_dwc_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_dwc_n.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_dwc_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_dwc_s.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_phone.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_selected.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_xdd_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_xdd_n.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_xdd_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_xdd_s.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_yqx_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_yqx_n.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_yqx_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_yqx_s.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_ywc_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_ywc_n.png -------------------------------------------------------------------------------- /assets/images/order/dark/icon_ywc_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dark/icon_ywc_s.png -------------------------------------------------------------------------------- /assets/images/order/dps_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dps_n.png -------------------------------------------------------------------------------- /assets/images/order/dps_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dps_s.png -------------------------------------------------------------------------------- /assets/images/order/dwc_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dwc_n.png -------------------------------------------------------------------------------- /assets/images/order/dwc_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/dwc_s.png -------------------------------------------------------------------------------- /assets/images/order/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/ic_check.png -------------------------------------------------------------------------------- /assets/images/order/icon_address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/icon_address.png -------------------------------------------------------------------------------- /assets/images/order/icon_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/icon_avatar.png -------------------------------------------------------------------------------- /assets/images/order/icon_calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/icon_calendar.png -------------------------------------------------------------------------------- /assets/images/order/icon_calendar_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/icon_calendar_dark.png -------------------------------------------------------------------------------- /assets/images/order/icon_goods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/icon_goods.png -------------------------------------------------------------------------------- /assets/images/order/icon_phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/icon_phone.png -------------------------------------------------------------------------------- /assets/images/order/icon_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/icon_search.png -------------------------------------------------------------------------------- /assets/images/order/order_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/order_bg.png -------------------------------------------------------------------------------- /assets/images/order/order_bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/order_bg1.png -------------------------------------------------------------------------------- /assets/images/order/order_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/order_delete.png -------------------------------------------------------------------------------- /assets/images/order/order_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/order_search.png -------------------------------------------------------------------------------- /assets/images/order/xdd_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/xdd_n.png -------------------------------------------------------------------------------- /assets/images/order/xdd_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/xdd_s.png -------------------------------------------------------------------------------- /assets/images/order/yqx_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/yqx_n.png -------------------------------------------------------------------------------- /assets/images/order/yqx_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/yqx_s.png -------------------------------------------------------------------------------- /assets/images/order/ywc_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/ywc_n.png -------------------------------------------------------------------------------- /assets/images/order/ywc_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/order/ywc_s.png -------------------------------------------------------------------------------- /assets/images/shop/dark_dpsz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/dark_dpsz.png -------------------------------------------------------------------------------- /assets/images/shop/dark_txzh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/dark_txzh.png -------------------------------------------------------------------------------- /assets/images/shop/dark_zhls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/dark_zhls.png -------------------------------------------------------------------------------- /assets/images/shop/dark_zjgl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/dark_zjgl.png -------------------------------------------------------------------------------- /assets/images/shop/dpsz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/dpsz.png -------------------------------------------------------------------------------- /assets/images/shop/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/message.png -------------------------------------------------------------------------------- /assets/images/shop/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/setting.png -------------------------------------------------------------------------------- /assets/images/shop/tj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/tj.png -------------------------------------------------------------------------------- /assets/images/shop/tx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/tx.png -------------------------------------------------------------------------------- /assets/images/shop/txzh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/txzh.png -------------------------------------------------------------------------------- /assets/images/shop/wxzyf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/wxzyf.png -------------------------------------------------------------------------------- /assets/images/shop/xz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/xz.png -------------------------------------------------------------------------------- /assets/images/shop/xztm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/xztm.png -------------------------------------------------------------------------------- /assets/images/shop/xzyf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/xzyf.png -------------------------------------------------------------------------------- /assets/images/shop/zhls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/zhls.png -------------------------------------------------------------------------------- /assets/images/shop/zjgl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/zjgl.png -------------------------------------------------------------------------------- /assets/images/shop/zybq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/shop/zybq.png -------------------------------------------------------------------------------- /assets/images/state/zwdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/state/zwdd.png -------------------------------------------------------------------------------- /assets/images/state/zwsp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/state/zwsp.png -------------------------------------------------------------------------------- /assets/images/state/zwwl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/state/zwwl.png -------------------------------------------------------------------------------- /assets/images/state/zwxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/state/zwxx.png -------------------------------------------------------------------------------- /assets/images/state/zwzh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/state/zwzh.png -------------------------------------------------------------------------------- /assets/images/statistic/champion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/champion.png -------------------------------------------------------------------------------- /assets/images/statistic/chart_fg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/chart_fg.png -------------------------------------------------------------------------------- /assets/images/statistic/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/down.png -------------------------------------------------------------------------------- /assets/images/statistic/dps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/dps.png -------------------------------------------------------------------------------- /assets/images/statistic/icon_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/icon_selected.png -------------------------------------------------------------------------------- /assets/images/statistic/jrjye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/jrjye.png -------------------------------------------------------------------------------- /assets/images/statistic/jyetj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/jyetj.png -------------------------------------------------------------------------------- /assets/images/statistic/runnerup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/runnerup.png -------------------------------------------------------------------------------- /assets/images/statistic/sjzs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/sjzs.png -------------------------------------------------------------------------------- /assets/images/statistic/sptj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/sptj.png -------------------------------------------------------------------------------- /assets/images/statistic/statistic_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/statistic_bg.png -------------------------------------------------------------------------------- /assets/images/statistic/statistic_bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/statistic_bg1.png -------------------------------------------------------------------------------- /assets/images/statistic/thirdplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/thirdplace.png -------------------------------------------------------------------------------- /assets/images/statistic/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/up.png -------------------------------------------------------------------------------- /assets/images/statistic/xdd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/statistic/xdd.png -------------------------------------------------------------------------------- /assets/images/store/2.0x/icon_failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/2.0x/icon_failure.png -------------------------------------------------------------------------------- /assets/images/store/2.0x/icon_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/2.0x/icon_success.png -------------------------------------------------------------------------------- /assets/images/store/2.0x/icon_wait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/2.0x/icon_wait.png -------------------------------------------------------------------------------- /assets/images/store/2.0x/icon_zj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/2.0x/icon_zj.png -------------------------------------------------------------------------------- /assets/images/store/3.0x/icon_failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/3.0x/icon_failure.png -------------------------------------------------------------------------------- /assets/images/store/3.0x/icon_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/3.0x/icon_success.png -------------------------------------------------------------------------------- /assets/images/store/3.0x/icon_wait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/3.0x/icon_wait.png -------------------------------------------------------------------------------- /assets/images/store/3.0x/icon_zj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/3.0x/icon_zj.png -------------------------------------------------------------------------------- /assets/images/store/icon_failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/icon_failure.png -------------------------------------------------------------------------------- /assets/images/store/icon_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/icon_success.png -------------------------------------------------------------------------------- /assets/images/store/icon_wait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/icon_wait.png -------------------------------------------------------------------------------- /assets/images/store/icon_zj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/store/icon_zj.png -------------------------------------------------------------------------------- /assets/images/update_head.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/assets/images/update_head.jpg -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 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 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - image_picker_ios (0.0.1): 4 | - Flutter 5 | - path_provider_foundation (0.0.1): 6 | - Flutter 7 | - FlutterMacOS 8 | - shared_preferences_foundation (0.0.1): 9 | - Flutter 10 | - FlutterMacOS 11 | - webview_flutter_wkwebview (0.0.1): 12 | - Flutter 13 | 14 | DEPENDENCIES: 15 | - Flutter (from `Flutter`) 16 | - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) 17 | - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) 18 | - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) 19 | - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) 20 | 21 | EXTERNAL SOURCES: 22 | Flutter: 23 | :path: Flutter 24 | image_picker_ios: 25 | :path: ".symlinks/plugins/image_picker_ios/ios" 26 | path_provider_foundation: 27 | :path: ".symlinks/plugins/path_provider_foundation/darwin" 28 | shared_preferences_foundation: 29 | :path: ".symlinks/plugins/shared_preferences_foundation/darwin" 30 | webview_flutter_wkwebview: 31 | :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" 32 | 33 | SPEC CHECKSUMS: 34 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 35 | image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 36 | path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 37 | shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c 38 | webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a 39 | 40 | PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 41 | 42 | COCOAPODS: 1.12.1 43 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Icon-App-20x20@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "Icon-App-20x20@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "Icon-App-29x29@1x.png", 17 | "idiom" : "iphone", 18 | "scale" : "1x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "Icon-App-29x29@2x.png", 23 | "idiom" : "iphone", 24 | "scale" : "2x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "Icon-App-29x29@3x.png", 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "29x29" 32 | }, 33 | { 34 | "filename" : "Icon-App-40x40@2x.png", 35 | "idiom" : "iphone", 36 | "scale" : "2x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "Icon-App-40x40@3x.png", 41 | "idiom" : "iphone", 42 | "scale" : "3x", 43 | "size" : "40x40" 44 | }, 45 | { 46 | "filename" : "Icon-App-60x60@2x.png", 47 | "idiom" : "iphone", 48 | "scale" : "2x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "Icon-App-60x60@3x.png", 53 | "idiom" : "iphone", 54 | "scale" : "3x", 55 | "size" : "60x60" 56 | }, 57 | { 58 | "filename" : "Icon-App-1024x1024@1x.png", 59 | "idiom" : "ios-marketing", 60 | "scale" : "1x", 61 | "size" : "1024x1024" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "logo.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/logo.imageset/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/ios/Runner/Assets.xcassets/logo.imageset/logo.png -------------------------------------------------------------------------------- /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 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleDisplayName 10 | Flutter Ui Challenge 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | flutter_ui_challenge 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | $(FLUTTER_BUILD_NAME) 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSApplicationCategoryType 26 | 27 | LSRequiresIPhoneOS 28 | 29 | NSPhotoLibraryAddUsageDescription 30 | 我们需要您的照片库存储权限 31 | NSPhotoLibraryUsageDescription 32 | 我们需要您的照片库权限 33 | UILaunchStoryboardName 34 | LaunchScreen 35 | UIMainStoryboardFile 36 | Main 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | 41 | UIViewControllerBasedStatusBarAppearance 42 | 43 | UIApplicationSupportsIndirectInputEvents 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/change_app_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/deer_app.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/my_app_bar.dart'; 6 | import 'package:flutter_ui_challenge/examples/ui_chanllenge/flutter_challenge_page.dart'; 7 | import 'package:flutter_ui_challenge/main.dart'; 8 | 9 | class ChangeAppPage extends ConsumerWidget { 10 | const ChangeAppPage({Key? key}) : super(key: key); 11 | 12 | @override 13 | Widget build(BuildContext context, WidgetRef ref) { 14 | return Scaffold( 15 | appBar: const MyAppBar( 16 | title: Text('切换App'), 17 | ), 18 | body: GridView( 19 | padding: const EdgeInsets.all(10), 20 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( 21 | crossAxisCount: 2, 22 | mainAxisSpacing: 10, 23 | crossAxisSpacing: 10, 24 | ), 25 | children: [ 26 | _changleApp(ref), 27 | _deerApp(ref), 28 | ], 29 | ), 30 | ); 31 | } 32 | 33 | Widget _changleApp(WidgetRef ref) { 34 | return GestureDetector( 35 | onTap: () { 36 | ref.read(mainAppProvider.state).state = const FlutterChallengeApp(); 37 | }, 38 | child: _gridContainer( 39 | const Text('UI Chanllenge'), 40 | )); 41 | } 42 | 43 | Widget _deerApp(WidgetRef ref) { 44 | return GestureDetector( 45 | onTap: () { 46 | ref.read(mainAppProvider.state).state = DeerApp(); 47 | }, 48 | child: _gridContainer(const LoadAssetImage( 49 | 'logo', 50 | width: 80, 51 | height: 80, 52 | )), 53 | ); 54 | } 55 | 56 | Widget _gridContainer(Widget child) { 57 | return Container( 58 | alignment: Alignment.center, 59 | decoration: const BoxDecoration( 60 | color: Colors.white, 61 | boxShadow: [ 62 | BoxShadow(color: Colors.black38, blurRadius: 2, offset: Offset.zero), 63 | ], 64 | ), 65 | child: child, 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/common/config_providers.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/common/deer_storage.dart'; 5 | import 'package:shared_preferences/shared_preferences.dart'; 6 | 7 | class ConfigProviders { 8 | static final configInit = FutureProvider.autoDispose((ref) async { 9 | final result = await Future.wait( 10 | [ 11 | SharedPreferences.getInstance(), 12 | ], 13 | ); 14 | 15 | DeerStorage.sp = result[0]; 16 | 17 | return; 18 | }); 19 | 20 | static final config = 21 | StateNotifierProvider((ref) { 22 | return AppConfigStateNotifier( 23 | AppConfigState( 24 | hadShowGuide: DeerStorage.hadShowGuide, 25 | themeMode: DeerStorage.themeMode, 26 | ), 27 | ); 28 | }); 29 | 30 | static final hadShowGuide = Provider((ref) { 31 | return ref.watch(config).hadShowGuide; 32 | }); 33 | 34 | static final themeMode = Provider((ref) { 35 | return ref.watch(config).themeMode; 36 | }); 37 | } 38 | 39 | class AppConfigStateNotifier extends StateNotifier { 40 | AppConfigStateNotifier(AppConfigState config) : super(config); 41 | 42 | set hadShowGuide(bool value) { 43 | DeerStorage.hadShowGuide = value; 44 | state = state.copyWith(hadShowGuide: value); 45 | } 46 | 47 | /// 修改主题模式 48 | void changeDarkMode(ThemeMode mode) { 49 | DeerStorage.themeMode = mode; 50 | 51 | state = state.copyWith(themeMode: mode); 52 | } 53 | } 54 | 55 | @immutable 56 | class AppConfigState extends Equatable { 57 | final bool hadShowGuide; 58 | final ThemeMode themeMode; 59 | 60 | /// 调试相关 61 | 62 | const AppConfigState({ 63 | required this.hadShowGuide, 64 | required this.themeMode, 65 | }); 66 | 67 | AppConfigState copyWith({ 68 | bool? hadShowGuide, 69 | ThemeMode? themeMode, 70 | }) { 71 | return AppConfigState( 72 | hadShowGuide: hadShowGuide ?? this.hadShowGuide, 73 | themeMode: themeMode ?? this.themeMode, 74 | ); 75 | } 76 | 77 | @override 78 | List get props => [hadShowGuide, themeMode]; 79 | } 80 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/common/constant.dart: -------------------------------------------------------------------------------- 1 | class StorageKey { 2 | static const userInfo = 'deer_user_info'; 3 | 4 | static const hadShowGuide = 'deer_had_show_guide'; 5 | 6 | static const themeMode = 'deer_theme_mode'; 7 | 8 | static const phone = 'deer_user_phone'; 9 | } 10 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/common/deer_storage.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/common/constant.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/common/user_provider.dart'; 6 | import 'package:shared_preferences/shared_preferences.dart'; 7 | 8 | class DeerStorage { 9 | static late SharedPreferences sp; 10 | 11 | /// 用户信息 12 | static DeerUserInfo? get userInfo { 13 | final value = sp.get(StorageKey.userInfo); 14 | if (value != null) { 15 | final userJson = jsonDecode(value as String) as Map; 16 | 17 | return DeerUserInfo.fromJson(userJson); 18 | } 19 | return null; 20 | } 21 | 22 | static set userInfo(DeerUserInfo? value) { 23 | if (value == null) { 24 | sp.remove(StorageKey.userInfo); 25 | return; 26 | } 27 | final jsonString = jsonEncode(value.toJson()); 28 | sp.setString(StorageKey.userInfo, jsonString); 29 | } 30 | 31 | // 是否登录 32 | static bool get isLogin => userInfo != null; 33 | 34 | /// 之前登录人的手机号 - 用于下次填写使用 35 | static String get phone => sp.getString(StorageKey.phone) ?? ''; 36 | static set phone(String value) => sp.setString(StorageKey.phone, value); 37 | 38 | /// 是否展示过引导页 39 | static bool get hadShowGuide => sp.getBool(StorageKey.hadShowGuide) ?? false; 40 | static set hadShowGuide(bool value) => 41 | sp.setBool(StorageKey.hadShowGuide, value); 42 | 43 | /// 系统主题 44 | static ThemeMode get themeMode { 45 | final theme = sp.getString(StorageKey.themeMode); 46 | switch (theme) { 47 | case 'Dark': 48 | return ThemeMode.dark; 49 | case 'Light': 50 | return ThemeMode.light; 51 | default: 52 | return ThemeMode.system; 53 | } 54 | } 55 | 56 | static set themeMode(ThemeMode mode) { 57 | String themeString; 58 | switch (mode) { 59 | case ThemeMode.dark: 60 | themeString = 'Dark'; 61 | break; 62 | case ThemeMode.light: 63 | themeString = 'Light'; 64 | break; 65 | default: 66 | themeString = 'System'; 67 | } 68 | sp.setString(StorageKey.themeMode, themeString); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/common/user_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/common/deer_storage.dart'; 5 | 6 | class UserProviders { 7 | static final userInfo = 8 | StateNotifierProvider( 9 | (ref) => DeerUserInfoState(DeerStorage.userInfo)); 10 | 11 | static final isLogin = Provider.autoDispose((ref) { 12 | return ref.watch(userInfo) != null; 13 | }, dependencies: [userInfo]); 14 | } 15 | 16 | class DeerUserInfoState extends StateNotifier { 17 | DeerUserInfoState(DeerUserInfo? userInfo) : super(userInfo); 18 | 19 | void loginSuccess(DeerUserInfo userInfo) { 20 | DeerStorage.phone = userInfo.phone; 21 | DeerStorage.userInfo = userInfo; 22 | state = userInfo; 23 | } 24 | 25 | void logOut() { 26 | DeerStorage.userInfo = null; 27 | state = null; 28 | } 29 | } 30 | 31 | @immutable 32 | class DeerUserInfo extends Equatable { 33 | final String phone; 34 | 35 | final String name; 36 | 37 | final String token; 38 | 39 | const DeerUserInfo({ 40 | required this.phone, 41 | required this.name, 42 | required this.token, 43 | }); 44 | 45 | @override 46 | List get props => [phone, name, token]; 47 | 48 | factory DeerUserInfo.fromJson(Map json) { 49 | return DeerUserInfo( 50 | phone: json['phone'], 51 | name: json['name'], 52 | token: json['token'], 53 | ); 54 | } 55 | 56 | Map toJson() { 57 | return { 58 | 'phone': phone, 59 | 'name': name, 60 | 'token': token, 61 | }; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/goods/goods_route.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/goods/page/goods_edit_page.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/goods/page/goods_page.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/deer_routers.dart'; 5 | 6 | class GoodsRouter extends ModularRouterProvider { 7 | static const goods = '/goods'; 8 | static const edit = '/goods/edit'; 9 | @override 10 | void initRouter(FluroRouter router) { 11 | router.define(goods, handler: Handler(handlerFunc: (context, _) { 12 | return const GoodsPage(); 13 | })); 14 | 15 | router.define(edit, handler: Handler(handlerFunc: (context, params) { 16 | final isEdit = params['isEdit']?.first; 17 | return GoodsEditPage(isEdit: isEdit == '1'); 18 | })); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/goods/models/goods_type_model/goods_type_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'goods_type_model.freezed.dart'; 4 | part 'goods_type_model.g.dart'; 5 | 6 | @freezed 7 | class GoodsTypeModel with _$GoodsTypeModel { 8 | factory GoodsTypeModel({ 9 | String? id, 10 | String? name, 11 | }) = _GoodsTypeModel; 12 | 13 | factory GoodsTypeModel.fromJson(Map json) => 14 | _$GoodsTypeModelFromJson(json); 15 | } 16 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/goods/models/goods_type_model/goods_type_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'goods_type_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | // ignore: non_constant_identifier_names 10 | _$_GoodsTypeModel _$$_GoodsTypeModelFromJson(Map json) => 11 | _$_GoodsTypeModel( 12 | id: json['id'] as String?, 13 | name: json['name'] as String?, 14 | ); 15 | 16 | // ignore: non_constant_identifier_names 17 | Map _$$_GoodsTypeModelToJson(_$_GoodsTypeModel instance) => 18 | { 19 | 'id': instance.id, 20 | 'name': instance.name, 21 | }; 22 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/goods/providers/goods_providers.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | 4 | mixin GoodsProviders { 5 | final goodsState = StateNotifierProvider.autoDispose< 6 | GoodsTypeChooseStateNotifier, GoodsTypeChooseState>((ref) { 7 | return GoodsTypeChooseStateNotifier(); 8 | }); 9 | 10 | late final unfold = Provider.autoDispose((ref) { 11 | return ref.watch(goodsState).unfold; 12 | }); 13 | 14 | late final selectedIndex = Provider.autoDispose((ref) { 15 | return ref.watch(goodsState).selectedIndex; 16 | }); 17 | } 18 | 19 | class GoodsTypeChooseStateNotifier extends StateNotifier { 20 | GoodsTypeChooseStateNotifier() 21 | : super(const GoodsTypeChooseState(unfold: false)); 22 | 23 | void setSelectedIndex(int value) { 24 | state = state.copyWith(selectedIndex: value); 25 | } 26 | 27 | void setUnfold(bool value) { 28 | state = state.copyWith(unfold: value); 29 | } 30 | 31 | void autoUnfold() { 32 | state = state.copyWith(unfold: !state.unfold); 33 | } 34 | 35 | void setTitle(String title) { 36 | state = state.copyWith(title: title); 37 | } 38 | } 39 | 40 | class GoodsTypeChooseState extends Equatable { 41 | final bool unfold; 42 | final int selectedIndex; 43 | 44 | const GoodsTypeChooseState({ 45 | required this.unfold, 46 | this.selectedIndex = 0, 47 | }); 48 | 49 | GoodsTypeChooseState copyWith({ 50 | bool? unfold, 51 | String? title, 52 | int? selectedIndex, 53 | }) { 54 | return GoodsTypeChooseState( 55 | unfold: unfold ?? this.unfold, 56 | selectedIndex: selectedIndex ?? this.selectedIndex, 57 | ); 58 | } 59 | 60 | @override 61 | List get props => [unfold, selectedIndex]; 62 | } 63 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/goods/widgets/goods_head_title.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/text_styles.dart'; 6 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 7 | 8 | class GoodsHeadTitle extends StatefulWidget { 9 | final String title; 10 | final bool unfold; 11 | 12 | const GoodsHeadTitle({ 13 | Key? key, 14 | required this.title, 15 | required this.unfold, 16 | }) : super(key: key); 17 | 18 | @override 19 | State createState() => _GoodsHeadTitleState(); 20 | } 21 | 22 | class _GoodsHeadTitleState extends State { 23 | final Matrix4 normal = Matrix4.identity(); 24 | 25 | Matrix4 get unfold => () { 26 | var result = Matrix4.identity(); 27 | const offset = 10.0; 28 | result.translate(offset, offset); 29 | result.rotateZ(pi * 0.6); 30 | result.translate(-offset, -offset); 31 | return result; 32 | }(); 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | return Container( 37 | padding: EdgeInsets.only(left: 16, bottom: 16.fit, top: 3.fit), 38 | height: 49.fit, 39 | child: Row( 40 | children: [ 41 | Text(widget.title, style: TextStyles.textBold24), 42 | Padding( 43 | padding: EdgeInsets.only(top: 4.fit), 44 | child: AnimatedRotation( 45 | turns: widget.unfold ? 0.5 : 0, 46 | duration: const Duration(milliseconds: 300), 47 | child: const Icon(Icons.keyboard_arrow_down, color: Colours.text), 48 | ), 49 | ), 50 | ], 51 | ), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/goods/widgets/goods_page_option.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 4 | 5 | enum GoodsPageOption { 6 | scan, 7 | add, 8 | } 9 | 10 | extension GoodsPageOptionExtension on GoodsPageOption { 11 | String get title => ['扫码添加', '添加商品'][index]; 12 | 13 | String get imgae => ['goods/scanning', 'goods/add2'][index]; 14 | } 15 | 16 | class GoodsPageOptionView extends StatelessWidget { 17 | final ValueChanged onTap; 18 | 19 | const GoodsPageOptionView({ 20 | Key? key, 21 | required this.onTap, 22 | }) : super(key: key); 23 | 24 | List get values => GoodsPageOption.values; 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | return Material( 29 | color: Colors.transparent, 30 | child: SizedBox( 31 | height: 68.fit, 32 | width: 120.fit, 33 | child: ListView.separated( 34 | padding: EdgeInsets.only(left: 16.fit, right: 16.fit), 35 | itemBuilder: (context, index) { 36 | final option = values[index]; 37 | return GestureDetector( 38 | onTap: () => onTap(option), 39 | child: _OptionItemView( 40 | option: option, 41 | ), 42 | ); 43 | }, 44 | separatorBuilder: (_, __) => const Divider(), 45 | itemCount: values.length, 46 | ), 47 | ), 48 | ); 49 | } 50 | } 51 | 52 | class _OptionItemView extends StatelessWidget { 53 | final GoodsPageOption option; 54 | 55 | const _OptionItemView({ 56 | Key? key, 57 | required this.option, 58 | }) : super(key: key); 59 | 60 | @override 61 | Widget build(BuildContext context) { 62 | return SizedBox( 63 | height: 34.fit, 64 | child: Row( 65 | children: [ 66 | LoadAssetImage( 67 | option.imgae, 68 | width: 16.fit, 69 | height: 16.fit, 70 | ), 71 | SizedBox(width: 6.fit), 72 | Expanded(child: Text(option.title)), 73 | ], 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/goods/widgets/goods_spec_edit.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/navigator_utils.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/toast.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/common_dialog.dart'; 6 | 7 | class GoodsSpecEdit extends StatefulWidget { 8 | final String? spec; 9 | 10 | const GoodsSpecEdit({ 11 | Key? key, 12 | this.spec, 13 | }) : super(key: key); 14 | 15 | @override 16 | State createState() => _GoodsSpecEditState(); 17 | } 18 | 19 | class _GoodsSpecEditState extends State { 20 | TextEditingController controller = TextEditingController(); 21 | 22 | @override 23 | void initState() { 24 | super.initState(); 25 | controller.text = widget.spec ?? ''; 26 | } 27 | 28 | @override 29 | void dispose() { 30 | controller.dispose(); 31 | super.dispose(); 32 | } 33 | 34 | void ensureAction() { 35 | if (controller.text.isEmpty) { 36 | Toast.show('请输入文字'); 37 | return; 38 | } 39 | NavigatorUtils.pop(context, result: controller.text); 40 | } 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | return CommonDialog( 45 | title: '规格名称', 46 | isEdit: true, 47 | keyboardSpace: 20, 48 | onEnsure: ensureAction, 49 | children: [ 50 | const SizedBox(height: 16), 51 | Container( 52 | height: 34, 53 | alignment: Alignment.center, 54 | decoration: BoxDecoration( 55 | color: Colours.bgGray_, 56 | borderRadius: BorderRadius.circular(2.0), 57 | ), 58 | margin: const EdgeInsets.fromLTRB(16.0, 8.0, 16.0, 0.0), 59 | child: TextFormField( 60 | onEditingComplete: ensureAction, 61 | autofocus: true, 62 | controller: controller, 63 | decoration: const InputDecoration( 64 | isCollapsed: true, 65 | border: InputBorder.none, 66 | hintText: '输入文字', 67 | contentPadding: EdgeInsets.symmetric( 68 | horizontal: 16, 69 | ), 70 | ), 71 | ), 72 | ), 73 | const SizedBox(height: 8), 74 | ], 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/home/common_router.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/home/deer_main_page.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/home/web_page.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/deer_routers.dart'; 5 | 6 | class CommonRouter extends ModularRouterProvider { 7 | static String main = '/main'; 8 | 9 | static String webView = '/webView'; 10 | 11 | @override 12 | void initRouter(FluroRouter router) { 13 | router.define(main, handler: Handler(handlerFunc: (context, params) { 14 | return const DeerMainPage(); 15 | })); 16 | 17 | router.define(webView, handler: Handler(handlerFunc: (context, params) { 18 | final title = params['title']?.first as String; 19 | final url = params['url']?.first as String; 20 | return WebViewPage(title: title, url: url); 21 | })); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/home/loading_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 3 | 4 | class SplashPage extends StatelessWidget { 5 | const SplashPage({Key? key}) : super(key: key); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return const Scaffold( 10 | body: Center( 11 | child: LoadAssetImage( 12 | 'logo', 13 | width: 100, 14 | ), 15 | ), 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/home/providers/home_providers.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 2 | 3 | mixin HomeProviders { 4 | final homeIndexProvider = StateProvider.autoDispose((ref) => 0); 5 | } 6 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/home/splash_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/common/config_providers.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/image_utils.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 6 | 7 | class DeerGuidePage extends ConsumerStatefulWidget { 8 | const DeerGuidePage({Key? key}) : super(key: key); 9 | 10 | @override 11 | ConsumerState createState() => _SplashPageState(); 12 | } 13 | 14 | class _SplashPageState extends ConsumerState { 15 | final List _guideList = [ 16 | 'app_start_1', 17 | 'app_start_2', 18 | 'app_start_3', 19 | ]; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return Scaffold( 24 | body: PageView( 25 | physics: const ClampingScrollPhysics( 26 | parent: RangeMaintainingScrollPhysics()), 27 | children: [ 28 | for (int i = 0; i < _guideList.length; i++) 29 | if (i == _guideList.length - 1) 30 | GestureDetector( 31 | onTap: () { 32 | ref.read(ConfigProviders.config.notifier).hadShowGuide = true; 33 | }, 34 | child: SizedBox.expand( 35 | child: LoadAssetImage( 36 | _guideList[i], 37 | fit: BoxFit.cover, 38 | format: ImageFormat.webp, 39 | ), 40 | ), 41 | ) 42 | else 43 | SizedBox.expand( 44 | child: LoadAssetImage( 45 | _guideList[i], 46 | fit: BoxFit.cover, 47 | format: ImageFormat.webp, 48 | ), 49 | ), 50 | ], 51 | ), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/login/login_route.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/login/page/code_login_page.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/login/page/login_page.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/deer_routers.dart'; 5 | 6 | class LoginRouter extends ModularRouterProvider { 7 | static const login = '/login'; 8 | static const register = '/login/register'; 9 | static const codeLogin = '/login/code'; 10 | 11 | @override 12 | void initRouter(FluroRouter router) { 13 | router.define(login, handler: Handler(handlerFunc: (context, param) { 14 | return const LoginPage(); 15 | })); 16 | 17 | router.define(codeLogin, handler: Handler(handlerFunc: (context, param) { 18 | return const CodeLoginPage(); 19 | })); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/order/models/order_models.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/order/widgets/order_type_choose.dart'; 3 | 4 | class OrderListItemData extends Equatable { 5 | final int index; 6 | final OrderType orderType; 7 | const OrderListItemData({ 8 | required this.index, 9 | required this.orderType, 10 | }); 11 | 12 | @override 13 | List get props => [index]; 14 | } 15 | 16 | enum OrderType { 17 | // 新订单 18 | newOrder, 19 | // 待配送 20 | waiting, 21 | // 待完成 22 | pending, 23 | // 已完成 24 | completed, 25 | // 已取消 26 | cancelled, 27 | } 28 | 29 | extension OrderTypeExtension on OrderType { 30 | OrderChooseItemData get orderItemData { 31 | switch (this) { 32 | case OrderType.newOrder: 33 | return OrderChooseItemData( 34 | title: '新订单', 35 | selectImg: 'order/xdd_s', 36 | unSelectImg: 'order/xdd_n', 37 | orderType: this, 38 | ); 39 | case OrderType.waiting: 40 | return OrderChooseItemData( 41 | title: '待配送', 42 | selectImg: 'order/dps_s', 43 | unSelectImg: 'order/dps_n', 44 | orderType: this, 45 | ); 46 | case OrderType.pending: 47 | return OrderChooseItemData( 48 | title: '待完成', 49 | selectImg: 'order/dwc_s', 50 | unSelectImg: 'order/dwc_n', 51 | orderType: this, 52 | ); 53 | case OrderType.completed: 54 | return OrderChooseItemData( 55 | title: '已完成', 56 | selectImg: 'order/ywc_s', 57 | unSelectImg: 'order/ywc_n', 58 | orderType: this, 59 | ); 60 | case OrderType.cancelled: 61 | return OrderChooseItemData( 62 | title: '已取消', 63 | selectImg: 'order/yqx_s', 64 | unSelectImg: 'order/yqx_n', 65 | orderType: this, 66 | ); 67 | } 68 | } 69 | } 70 | 71 | enum PaymentType { 72 | none, 73 | alipay, 74 | wechat, 75 | cash, 76 | } 77 | 78 | extension PaymentTypeExtension on PaymentType { 79 | String get desc => ['未付款', '支付宝', '微信', '现金'][index]; 80 | } 81 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/order/provider/order_header_provider.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 2 | 3 | class HeaderProviders { 4 | static List get overrides => [ 5 | pageIndex.overrideWithValue(StateController(0)), 6 | tapIndex.overrideWithValue(StateController(0)), 7 | stopIndex.overrideWithValue(StateController(0)), 8 | ]; 9 | 10 | /// pageView切换 11 | static final pageIndex = StateProvider((ref) => 0); 12 | 13 | static final isSelected = Provider.family((ref, arg) { 14 | final index = ref.watch(pageIndex); 15 | return index == arg; 16 | }, dependencies: [pageIndex]); 17 | 18 | /// header点击 19 | static final tapIndex = StateProvider((ref) => 0); 20 | 21 | /// 滚动停止时的index 22 | static final stopIndex = StateProvider((ref) => 0); 23 | } 24 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/order/widgets/order_tag_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 3 | 4 | class OrderTagItem extends StatelessWidget { 5 | final String date; 6 | final int orderTotal; 7 | 8 | const OrderTagItem({ 9 | Key? key, 10 | required this.date, 11 | required this.orderTotal, 12 | }) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Container( 17 | margin: const EdgeInsets.only(bottom: 8), 18 | height: 34, 19 | decoration: const BoxDecoration( 20 | color: Colors.white, 21 | borderRadius: BorderRadius.all(Radius.circular(8)), 22 | boxShadow: [ 23 | BoxShadow( 24 | color: Color(0x80dce7fa), 25 | offset: Offset(0, 2), 26 | blurRadius: 8, 27 | ), 28 | ], 29 | ), 30 | child: Row( 31 | children: [ 32 | const SizedBox( 33 | width: 16, 34 | ), 35 | const LoadAssetImage( 36 | 'order/icon_calendar', 37 | width: 14, 38 | height: 13, 39 | ), 40 | const SizedBox(width: 8), 41 | Text(date), 42 | Expanded( 43 | child: Container( 44 | alignment: Alignment.centerRight, 45 | child: Text('$orderTotal单'), 46 | ), 47 | ), 48 | const SizedBox(width: 16), 49 | ], 50 | ), 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/settings/page/setting_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 3 | import 'package:flutter_ui_challenge/change_app_page.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/common/user_provider.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/settings/widgets/setting_item.dart'; 6 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/navigator_utils.dart'; 7 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/dialog_utils.dart'; 8 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/alert_view.dart'; 9 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/my_app_bar.dart'; 10 | 11 | class SettingPage extends ConsumerStatefulWidget { 12 | const SettingPage({Key? key}) : super(key: key); 13 | 14 | @override 15 | ConsumerState createState() => _SettingPageState(); 16 | } 17 | 18 | class _SettingPageState extends ConsumerState { 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | appBar: const MyAppBar( 23 | title: Text('设置'), 24 | ), 25 | body: SingleChildScrollView( 26 | physics: const AlwaysScrollableScrollPhysics(), 27 | child: Column( 28 | children: [ 29 | SettingItem(title: '退出登录', onTap: logout), 30 | SettingItem(title: '切换App', onTap: exchangeApp), 31 | SettingItem( 32 | title: 'Github', content: 'follow & star', onTap: toGithub), 33 | ], 34 | ), 35 | ), 36 | ); 37 | } 38 | 39 | void logout() => DialogUtils.show(context, builder: (context) { 40 | return AlertView( 41 | title: '提示', 42 | message: '您确定要退出登录吗?', 43 | onTap: () { 44 | ref.read(UserProviders.userInfo.notifier).logOut(); 45 | }, 46 | ); 47 | }); 48 | 49 | void exchangeApp() => 50 | Navigator.of(context).push(MaterialPageRoute(builder: (context) { 51 | return const ChangeAppPage(); 52 | })); 53 | 54 | void toGithub() => NavigatorUtils.pushToWeb( 55 | context, 'Github', 'https://www.github.com/MengLiMing'); 56 | } 57 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/settings/setting_router.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/settings/page/setting_page.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/deer_routers.dart'; 4 | 5 | class SettingRouter extends ModularRouterProvider { 6 | static const setting = '/setting'; 7 | 8 | @override 9 | void initRouter(FluroRouter router) { 10 | router.define(setting, handler: Handler(handlerFunc: (context, _) { 11 | return const SettingPage(); 12 | })); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/settings/widgets/setting_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 4 | 5 | class SettingItem extends StatelessWidget { 6 | final String title; 7 | 8 | final VoidCallback onTap; 9 | 10 | final String? content; 11 | 12 | const SettingItem({ 13 | Key? key, 14 | required this.title, 15 | required this.onTap, 16 | this.content, 17 | }) : super(key: key); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return InkWell( 22 | onTap: onTap, 23 | child: Container( 24 | height: 50, 25 | padding: const EdgeInsets.only(left: 16), 26 | child: Column( 27 | children: [ 28 | Expanded( 29 | child: Row( 30 | children: [ 31 | Text( 32 | title, 33 | style: const TextStyle(color: Colours.text, fontSize: 14), 34 | ), 35 | Expanded( 36 | child: Align( 37 | alignment: Alignment.centerRight, 38 | child: Text( 39 | content ?? '', 40 | style: const TextStyle( 41 | color: Colours.textGray, fontSize: 14), 42 | ), 43 | ), 44 | ), 45 | const SizedBox(width: 8), 46 | const LoadAssetImage( 47 | 'ic_arrow_right', 48 | width: 14, 49 | height: 14, 50 | ), 51 | const SizedBox(width: 16), 52 | ], 53 | ), 54 | ), 55 | const Divider(), 56 | ], 57 | ), 58 | ), 59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/model/bank_model/bank_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'bank_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class BankModel extends Equatable { 8 | final int id; 9 | final String bankName; 10 | final String firstLetter; 11 | 12 | const BankModel( 13 | {required this.id, required this.bankName, required this.firstLetter}); 14 | 15 | factory BankModel.fromJson(Map json) { 16 | return _$BankModelFromJson(json); 17 | } 18 | 19 | Map toJson() => _$BankModelToJson(this); 20 | 21 | @override 22 | List get props => [id, bankName, firstLetter]; 23 | } 24 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/model/bank_model/bank_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'bank_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BankModel _$BankModelFromJson(Map json) => BankModel( 10 | id: json['id'] as int, 11 | bankName: json['bankName'] as String, 12 | firstLetter: json['firstLetter'] as String, 13 | ); 14 | 15 | Map _$BankModelToJson(BankModel instance) => { 16 | 'id': instance.id, 17 | 'bankName': instance.bankName, 18 | 'firstLetter': instance.firstLetter, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/model/city_model/city_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:equatable/equatable.dart'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | part 'city_model.g.dart'; 5 | 6 | @JsonSerializable() 7 | class CityModel extends Equatable { 8 | final String name; 9 | final String cityCode; 10 | final String firstCharacter; 11 | 12 | const CityModel( 13 | {required this.name, 14 | required this.cityCode, 15 | required this.firstCharacter}); 16 | 17 | factory CityModel.fromJson(Map json) { 18 | return _$CityModelFromJson(json); 19 | } 20 | 21 | Map toJson() => _$CityModelToJson(this); 22 | 23 | @override 24 | List get props => [name, cityCode, firstCharacter]; 25 | } 26 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/model/city_model/city_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'city_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | CityModel _$CityModelFromJson(Map json) => CityModel( 10 | name: json['name'] as String, 11 | cityCode: json['cityCode'] as String, 12 | firstCharacter: json['firstCharacter'] as String, 13 | ); 14 | 15 | Map _$CityModelToJson(CityModel instance) => { 16 | 'name': instance.name, 17 | 'cityCode': instance.cityCode, 18 | 'firstCharacter': instance.firstCharacter, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/model/shop_config_model/shop_config_model.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'shop_config_model.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ShopConfigModel _$ShopConfigModelFromJson(Map json) => 10 | ShopConfigModel( 11 | isBusiness: json['isBusiness'] as bool? ?? false, 12 | desc: json['desc'] as String? ?? '', 13 | sevice: json['sevice'] as String? ?? '', 14 | payment: (json['payment'] as List?) 15 | ?.map((e) => $enumDecode(_$ShopPaymentStyleEnumMap, e)) 16 | .toList() ?? 17 | const [ShopPaymentStyle.online], 18 | freightConfig: $enumDecodeNullable( 19 | _$ShopFreightConfigEnumMap, json['freightConfig']) ?? 20 | ShopFreightConfig.breaks, 21 | freightScale: json['freightScale'] as String? ?? '', 22 | freightBreaks: json['freightBreaks'] as String? ?? '', 23 | freightCost: json['freightCost'] as String? ?? '', 24 | phone: json['phone'] as String? ?? '', 25 | address: json['address'] as String? ?? '', 26 | ); 27 | 28 | Map _$ShopConfigModelToJson(ShopConfigModel instance) => 29 | { 30 | 'isBusiness': instance.isBusiness, 31 | 'desc': instance.desc, 32 | 'sevice': instance.sevice, 33 | 'payment': 34 | instance.payment.map((e) => _$ShopPaymentStyleEnumMap[e]!).toList(), 35 | 'freightConfig': _$ShopFreightConfigEnumMap[instance.freightConfig]!, 36 | 'freightScale': instance.freightScale, 37 | 'freightBreaks': instance.freightBreaks, 38 | 'freightCost': instance.freightCost, 39 | 'phone': instance.phone, 40 | 'address': instance.address, 41 | }; 42 | 43 | const _$ShopPaymentStyleEnumMap = { 44 | ShopPaymentStyle.online: 0, 45 | ShopPaymentStyle.public: 1, 46 | ShopPaymentStyle.delivery: 2, 47 | }; 48 | 49 | const _$ShopFreightConfigEnumMap = { 50 | ShopFreightConfig.breaks: 0, 51 | ShopFreightConfig.scale: 1, 52 | }; 53 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/model/shop_record_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | 3 | // ignore_for_file: public_member_api_docs, sort_constructors_first 4 | class ShopRecordSectionModel { 5 | final String date; 6 | final List models; 7 | 8 | ShopRecordSectionModel({ 9 | required this.date, 10 | required this.models, 11 | }); 12 | 13 | ShopRecordSectionModel copyWith({ 14 | String? date, 15 | List? models, 16 | }) { 17 | return ShopRecordSectionModel( 18 | date: date ?? this.date, 19 | models: models ?? this.models, 20 | ); 21 | } 22 | 23 | @override 24 | bool operator ==(covariant ShopRecordSectionModel other) { 25 | if (identical(this, other)) return true; 26 | 27 | return other.date == date && listEquals(other.models, models); 28 | } 29 | 30 | @override 31 | int get hashCode => date.hashCode ^ models.hashCode; 32 | } 33 | 34 | class ShopRecordModel { 35 | final bool isIncome; 36 | final String price; 37 | final String time; 38 | final String balance; 39 | 40 | ShopRecordModel({ 41 | required this.isIncome, 42 | required this.price, 43 | required this.time, 44 | required this.balance, 45 | }); 46 | 47 | @override 48 | bool operator ==(covariant ShopRecordModel other) { 49 | if (identical(this, other)) return true; 50 | 51 | return other.isIncome == isIncome && 52 | other.price == price && 53 | other.time == time && 54 | other.balance == balance; 55 | } 56 | 57 | @override 58 | int get hashCode { 59 | return isIncome.hashCode ^ 60 | price.hashCode ^ 61 | time.hashCode ^ 62 | balance.hashCode; 63 | } 64 | 65 | @override 66 | String toString() { 67 | return 'ShopRecordModel(isIncome: $isIncome, price: $price, time: $time, balance: $balance)'; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/model/shop_withdraw_models.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | // ignore_for_file: public_member_api_docs, sort_constructors_first 4 | 5 | /// 提现方式 6 | enum ShopWithdrawStyle { 7 | quick, 8 | normal, 9 | } 10 | 11 | extension ShopWithdrawStyleExtension on ShopWithdrawStyle { 12 | String get title => ['快速到账', '普通到账'][index]; 13 | } 14 | 15 | /// 账户类型 16 | enum ShopAccontType { 17 | private, 18 | public, 19 | wechat, 20 | } 21 | 22 | extension ShopAccontTypeExtension on ShopAccontType { 23 | String get title => [ 24 | '银行卡(对私账号)', 25 | '银行卡(对公账号)', 26 | '微信', 27 | ][index]; 28 | 29 | bool get isBank => this != ShopAccontType.wechat; 30 | } 31 | 32 | /// 账户信息 33 | class ShopWithdrawAccountModel { 34 | bool get isBank => type.isBank; 35 | 36 | final String title; 37 | final String desc; 38 | final ShopAccontType type; 39 | 40 | const ShopWithdrawAccountModel({ 41 | required this.title, 42 | required this.desc, 43 | required this.type, 44 | }); 45 | 46 | static const List samples = [ 47 | ShopWithdrawAccountModel( 48 | title: '工商银行', 49 | desc: '尾号5306 Ming', 50 | type: ShopAccontType.public, 51 | ), 52 | ShopWithdrawAccountModel( 53 | title: '微信', 54 | desc: '刚刚好', 55 | type: ShopAccontType.wechat, 56 | ) 57 | ]; 58 | 59 | Map toMap() { 60 | return { 61 | 'title': title, 62 | 'desc': desc, 63 | 'type': type.index, 64 | }; 65 | } 66 | 67 | factory ShopWithdrawAccountModel.fromMap(Map map) { 68 | final typeIndex = map['type'] as int; 69 | return ShopWithdrawAccountModel( 70 | title: map['title'] as String, 71 | desc: map['desc'] as String, 72 | type: ShopAccontType.values[typeIndex], 73 | ); 74 | } 75 | 76 | String toJson() => json.encode(toMap()); 77 | 78 | factory ShopWithdrawAccountModel.fromJson(String source) => 79 | ShopWithdrawAccountModel.fromMap( 80 | json.decode(source) as Map); 81 | 82 | @override 83 | String toString() => 84 | 'ShopWithdrawAccountModel(title: $title, desc: $desc, type: $type)'; 85 | 86 | @override 87 | bool operator ==(covariant ShopWithdrawAccountModel other) { 88 | if (identical(this, other)) return true; 89 | 90 | return other.title == title && other.desc == desc && other.type == type; 91 | } 92 | 93 | @override 94 | int get hashCode => title.hashCode ^ desc.hashCode ^ type.hashCode; 95 | } 96 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/page/shop_withdraw_pwd_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/shop/shop_router.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/shop/widgets/shop_pwd_sms_dialog.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/navigator_utils.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/dialog_utils.dart'; 6 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/toast.dart'; 7 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/list_click_item.dart'; 8 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/my_app_bar.dart'; 9 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/my_scroll_view.dart'; 10 | 11 | class ShopWithdrawPwdPage extends StatelessWidget { 12 | const ShopWithdrawPwdPage({Key? key}) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return Scaffold( 17 | appBar: const MyAppBar( 18 | title: Text('提现密码'), 19 | ), 20 | body: MyScrollView( 21 | children: [ 22 | ListClickItem( 23 | title: '修改密码', 24 | onTap: () { 25 | NavigatorUtils.push(context, ShopRouter.changePwd); 26 | }), 27 | ListClickItem(title: '忘记密码', onTap: () => forgetPwd(context)), 28 | ], 29 | ), 30 | ); 31 | } 32 | 33 | void forgetPwd(BuildContext context) { 34 | DialogUtils.show(context, builder: (context) { 35 | return const ShopPwdSmsDialog(); 36 | }).then((code) { 37 | if (code == null) return; 38 | Toast.show('验证码:$code'); 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/provider/shop_withdraw_account_providers.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/shop/model/shop_withdraw_models.dart'; 3 | 4 | mixin ShopWithdrawAccountProviders { 5 | /// 没有人watch会autoDispose 6 | final manager = StateNotifierProvider.autoDispose< 7 | ShopWithdrawAccountStateNotifier, List>( 8 | (ref) => ShopWithdrawAccountStateNotifier(), 9 | ); 10 | } 11 | 12 | class ShopWithdrawAccountStateNotifier 13 | extends StateNotifier> { 14 | ShopWithdrawAccountStateNotifier() : super([]); 15 | 16 | void config(List accounts) { 17 | state = List.from(accounts); 18 | } 19 | 20 | void removeAt(int index) { 21 | state.removeAt(index); 22 | } 23 | 24 | void insertItem(ShopWithdrawAccountModel model) { 25 | state.insert(0, model); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/provider/shop_withdraw_choose_providers.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/shop/model/shop_withdraw_models.dart'; 5 | 6 | mixin ShopWithdrawChooseProviders { 7 | final manager = StateNotifierProvider.autoDispose< 8 | ShopWithdrawChooseStateNotifier, 9 | ShopWithdrawChooseState>((ref) => ShopWithdrawChooseStateNotifier()); 10 | 11 | late final datas = Provider.autoDispose>( 12 | (ref) => ref.watch(manager).datas); 13 | 14 | late final selectedModel = Provider.autoDispose( 15 | (ref) => ref.watch(manager).selectedModel); 16 | } 17 | 18 | class ShopWithdrawChooseStateNotifier 19 | extends StateNotifier { 20 | ShopWithdrawChooseStateNotifier() : super(ShopWithdrawChooseState()); 21 | 22 | void change({ 23 | ShopWithdrawAccountModel? selectedModel, 24 | List? datas, 25 | }) { 26 | state = state.copyWith(datas: datas, selectedModel: selectedModel); 27 | } 28 | 29 | void addAccount(ShopWithdrawAccountModel model) { 30 | state = state.copyWith(datas: [...state.datas, model]); 31 | } 32 | } 33 | 34 | class ShopWithdrawChooseState { 35 | final ShopWithdrawAccountModel? selectedModel; 36 | 37 | final List datas; 38 | ShopWithdrawChooseState({ 39 | this.selectedModel, 40 | this.datas = const [], 41 | }); 42 | 43 | @override 44 | bool operator ==(covariant ShopWithdrawChooseState other) { 45 | if (identical(this, other)) return true; 46 | 47 | return other.selectedModel == selectedModel && 48 | listEquals(other.datas, datas); 49 | } 50 | 51 | @override 52 | int get hashCode => selectedModel.hashCode ^ datas.hashCode; 53 | 54 | ShopWithdrawChooseState copyWith({ 55 | ShopWithdrawAccountModel? selectedModel, 56 | List? datas, 57 | }) { 58 | return ShopWithdrawChooseState( 59 | selectedModel: selectedModel ?? this.selectedModel, 60 | datas: datas ?? this.datas, 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/widgets/shop_actions.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 4 | 5 | class ShopAction { 6 | final String title; 7 | final String image; 8 | final VoidCallback onTap; 9 | 10 | const ShopAction({ 11 | required this.title, 12 | required this.image, 13 | required this.onTap, 14 | }); 15 | } 16 | 17 | class ShopActions extends StatelessWidget { 18 | final List actions; 19 | 20 | const ShopActions({ 21 | Key? key, 22 | required this.actions, 23 | }) : super(key: key); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return SliverPadding( 28 | padding: EdgeInsets.only( 29 | left: 8.fit, 30 | right: 8.fit, 31 | ), 32 | sliver: SliverGrid( 33 | delegate: SliverChildBuilderDelegate((context, index) { 34 | return ShopActionItem(itemData: actions[index]); 35 | }, childCount: actions.length), 36 | gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( 37 | crossAxisSpacing: 0, 38 | maxCrossAxisExtent: 80.fit, 39 | childAspectRatio: 80 / 88, 40 | ), 41 | ), 42 | ); 43 | } 44 | } 45 | 46 | class ShopActionItem extends StatelessWidget { 47 | final ShopAction itemData; 48 | const ShopActionItem({ 49 | Key? key, 50 | required this.itemData, 51 | }) : super(key: key); 52 | 53 | @override 54 | Widget build(BuildContext context) { 55 | return GestureDetector( 56 | behavior: HitTestBehavior.translucent, 57 | onTap: itemData.onTap, 58 | child: Column( 59 | children: [ 60 | SizedBox(height: 12.fit), 61 | LoadAssetImage( 62 | itemData.image, 63 | width: 32.fit, 64 | height: 32.fit, 65 | ), 66 | SizedBox(height: 4.fit), 67 | Text(itemData.title), 68 | ], 69 | ), 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/widgets/shop_header.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 3 | 4 | class ShopHeader extends StatelessWidget { 5 | const ShopHeader({Key? key}) : super(key: key); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return Container( 10 | padding: const EdgeInsets.only(right: 16, top: 12, bottom: 24, left: 16), 11 | child: Column( 12 | children: [ 13 | Row( 14 | children: [ 15 | Expanded( 16 | child: Column( 17 | crossAxisAlignment: CrossAxisAlignment.start, 18 | children: [ 19 | const Text( 20 | 'Ming - 刚刚好', 21 | style: 22 | TextStyle(fontSize: 26, fontWeight: FontWeight.bold), 23 | ), 24 | const SizedBox(height: 8), 25 | Row( 26 | children: const [ 27 | LoadAssetImage( 28 | 'shop/zybq', 29 | width: 40.0, 30 | height: 16.0, 31 | ), 32 | SizedBox(width: 8), 33 | Text( 34 | '店铺账号:15236489562', 35 | style: TextStyle(fontSize: 12), 36 | ), 37 | ], 38 | ) 39 | ], 40 | ), 41 | ), 42 | const ClipOval( 43 | child: LoadImage( 44 | 'https://avatars.githubusercontent.com/u/19296728?s=400&u=7a099a186684090f50459c87176cf4d291a27ac7&v=4', 45 | holderImg: 'shop/tx', 46 | width: 56, 47 | height: 56, 48 | ), 49 | ), 50 | ], 51 | ), 52 | ], 53 | ), 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/widgets/shop_pwd_code_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 3 | 4 | class ShopPwdCodeView extends StatelessWidget { 5 | final double radius; 6 | final double lineWidth; 7 | final List pwd; 8 | final int pwdLength; 9 | final double height; 10 | final EdgeInsetsGeometry margin; 11 | 12 | const ShopPwdCodeView({ 13 | Key? key, 14 | this.radius = 0, 15 | this.lineWidth = 1, 16 | this.pwd = const [], 17 | this.pwdLength = 6, 18 | this.height = 40, 19 | this.margin = EdgeInsets.zero, 20 | }) : super(key: key); 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return Container( 25 | margin: margin, 26 | height: height, 27 | decoration: BoxDecoration( 28 | color: Colors.white, 29 | border: Border.all(color: Colours.textGrayC, width: lineWidth), 30 | borderRadius: BorderRadius.all(Radius.circular(radius)), 31 | ), 32 | child: Row( 33 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 34 | children: [ 35 | for (int i = 0; i < pwdLength; i++) ...[ 36 | if (i != 0) 37 | Container( 38 | width: 1, 39 | height: double.infinity, 40 | color: Colours.textGrayC, 41 | ), 42 | if (pwd.length > i) 43 | Expanded( 44 | child: Center( 45 | child: Container( 46 | width: 8, 47 | height: 8, 48 | decoration: const BoxDecoration( 49 | color: Colors.black, 50 | borderRadius: BorderRadius.all( 51 | Radius.circular(4), 52 | ), 53 | ), 54 | ), 55 | ), 56 | ) 57 | else 58 | Expanded( 59 | child: Container(), 60 | ) 61 | ] 62 | ], 63 | ), 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/widgets/shop_withdraw_account.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/shop/model/shop_withdraw_models.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 6 | 7 | enum ShopWithdrawAccountStyle { 8 | normal, 9 | arrow, 10 | selected, 11 | } 12 | 13 | class ShopWithdrawAccount extends StatelessWidget { 14 | final ShopWithdrawAccountModel model; 15 | final ShopWithdrawAccountStyle style; 16 | 17 | const ShopWithdrawAccount({ 18 | Key? key, 19 | required this.model, 20 | this.style = ShopWithdrawAccountStyle.arrow, 21 | }) : super(key: key); 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | return Padding( 26 | padding: EdgeInsets.only(top: 21.fit, bottom: 16.fit), 27 | child: Row( 28 | children: [ 29 | LoadAssetImage( 30 | model.isBank ? 'account/yhk' : 'account/wechat', 31 | width: 24.fit, 32 | ), 33 | SizedBox(width: 16.fit), 34 | Expanded( 35 | child: Column( 36 | crossAxisAlignment: CrossAxisAlignment.start, 37 | children: [ 38 | Text(model.title), 39 | SizedBox(height: 8.fit), 40 | Text( 41 | model.desc, 42 | style: const TextStyle( 43 | color: Colours.textGray, 44 | fontSize: 12, 45 | ), 46 | ), 47 | ], 48 | ), 49 | ), 50 | Visibility( 51 | visible: style != ShopWithdrawAccountStyle.normal, 52 | child: style == ShopWithdrawAccountStyle.arrow 53 | ? LoadAssetImage('ic_arrow_right', 54 | height: 16.fit, width: 16.fit) 55 | : const LoadAssetImage( 56 | 'account/selected', 57 | height: 24.0, 58 | width: 24.0, 59 | ), 60 | ), 61 | ], 62 | ), 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/shop/widgets/shop_withdraw_account_type_choose.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/shop/model/shop_withdraw_models.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/text_styles.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/navigator_utils.dart'; 6 | 7 | class ShopWithdrawAccontTypeChoose extends StatelessWidget { 8 | const ShopWithdrawAccontTypeChoose({Key? key}) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Align( 13 | alignment: Alignment.center, 14 | child: Container( 15 | width: double.infinity, 16 | margin: const EdgeInsets.symmetric(horizontal: 56), 17 | decoration: const BoxDecoration( 18 | color: Colors.white, 19 | borderRadius: BorderRadius.all(Radius.circular(8))), 20 | child: Column( 21 | mainAxisSize: MainAxisSize.min, 22 | children: [ 23 | const SizedBox(height: 24), 24 | const Text( 25 | '账号类型', 26 | style: TextStyles.textBold18, 27 | ), 28 | const SizedBox(height: 16), 29 | for (final type in ShopAccontType.values) ...[ 30 | const Divider(), 31 | InkWell( 32 | onTap: () => NavigatorUtils.pop(context, result: type), 33 | child: Container( 34 | height: 42, 35 | width: double.infinity, 36 | alignment: Alignment.center, 37 | child: Text( 38 | type.title, 39 | style: const TextStyle(color: Colours.appMain), 40 | ), 41 | ), 42 | ), 43 | ], 44 | ], 45 | ), 46 | ), 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/statistics/models/statistics_goods_model.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs, sort_constructors_first 2 | import 'package:flutter/material.dart'; 3 | 4 | class StatisticsGoodsItemModel { 5 | final int number; 6 | final Color color; 7 | 8 | StatisticsGoodsItemModel({ 9 | required this.number, 10 | required this.color, 11 | }); 12 | 13 | @override 14 | bool operator ==(covariant StatisticsGoodsItemModel other) { 15 | if (identical(this, other)) return true; 16 | 17 | return other.number == number && other.color == color; 18 | } 19 | 20 | @override 21 | int get hashCode => number.hashCode ^ color.hashCode; 22 | } 23 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/statistics/statistics_router.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/statistics/page/statistics_goods_page.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/statistics/page/statistics_info_page.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/statistics/page/statistics_page.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/deer_routers.dart'; 6 | 7 | class StatisticsRouter extends ModularRouterProvider { 8 | static const statistics = '/statistics'; 9 | 10 | static const info = '/statistics/info'; 11 | 12 | static const goods = '/statistics/goods'; 13 | 14 | @override 15 | void initRouter(FluroRouter router) { 16 | router.define(statistics, handler: Handler(handlerFunc: (context, _) { 17 | return const StatisticsPage(); 18 | })); 19 | 20 | router.define(info, handler: Handler(handlerFunc: (context, params) { 21 | final style = int.tryParse(params['style']?.first as String) ?? 0; 22 | return StatisticsInfoPage( 23 | style: StatisticsInfoStyle.values[style], 24 | ); 25 | })); 26 | 27 | router.define(goods, handler: Handler(handlerFunc: (context, _) { 28 | return const StatisticsGoodsPage(); 29 | })); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/statistics/utils/calendar_utils.dart: -------------------------------------------------------------------------------- 1 | class CalendarUtils { 2 | /// 获取第一天 3 | static DateTime firstDayOfMonth(int year, int month) { 4 | return DateTime.utc(year, month); 5 | } 6 | 7 | /// 获取最后一天 8 | static DateTime lastDayOfMonth(int year, int month) { 9 | DateTime lastMonthDate; 10 | if (month < 12) { 11 | lastMonthDate = DateTime.utc(year, month + 1); 12 | } else { 13 | lastMonthDate = DateTime.utc(year + 1); 14 | } 15 | 16 | return lastMonthDate.subtract(const Duration(days: 1)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/statistics/widgets/statistics_header_content.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 5 | 6 | class StatisticsHeaderContent extends StatelessWidget { 7 | const StatisticsHeaderContent({Key? key}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return Padding( 12 | padding: const EdgeInsets.symmetric(horizontal: 6), 13 | child: Row( 14 | children: [ 15 | Expanded(child: _item('statistic/xdd', '新订单(单)', '80')), 16 | Expanded(child: _item('statistic/dps', '待配送(单)', '80')), 17 | Expanded(child: _item('statistic/jrjye', '今日交易额(元)', '8000.00')), 18 | ], 19 | ), 20 | ); 21 | } 22 | 23 | Widget _item(String image, String title, String content) { 24 | return Column( 25 | mainAxisSize: MainAxisSize.min, 26 | children: [ 27 | LoadAssetImage( 28 | image, 29 | width: 40.fit, 30 | height: 40.fit, 31 | ), 32 | SizedBox(height: 6.fit), 33 | Text( 34 | title, 35 | style: const TextStyle(color: Colours.textGray, fontSize: 12), 36 | ), 37 | SizedBox(height: 6.fit), 38 | Text( 39 | content, 40 | style: const TextStyle(fontSize: 18), 41 | ), 42 | ], 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/modules/statistics/widgets/statistics_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 4 | 5 | class StatisticsItem extends StatelessWidget { 6 | final String title; 7 | final Widget content; 8 | final VoidCallback onTap; 9 | 10 | const StatisticsItem({ 11 | Key? key, 12 | required this.title, 13 | required this.content, 14 | required this.onTap, 15 | }) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return Container( 20 | margin: EdgeInsets.only(bottom: 8.fit, left: 16.fit, right: 16.fit), 21 | padding: EdgeInsets.only(bottom: 16.fit), 22 | decoration: BoxDecoration( 23 | color: Colors.white, 24 | borderRadius: BorderRadius.all( 25 | Radius.circular(10.fit), 26 | ), 27 | boxShadow: [ 28 | BoxShadow( 29 | color: const Color(0xffDCE7FA).withOpacity(0.5), 30 | offset: Offset(0, 2.fit), 31 | blurRadius: 8.fit, 32 | spreadRadius: 2.fit, 33 | ), 34 | ], 35 | ), 36 | height: 160.fit, 37 | child: Column( 38 | mainAxisSize: MainAxisSize.min, 39 | children: [ 40 | GestureDetector( 41 | onTap: onTap, 42 | behavior: HitTestBehavior.translucent, 43 | child: Row( 44 | children: [ 45 | SizedBox(width: 16.fit), 46 | Expanded( 47 | child: Text( 48 | title, 49 | style: const TextStyle(fontWeight: FontWeight.w600), 50 | ), 51 | ), 52 | Container( 53 | width: 48.fit, 54 | height: 48.fit, 55 | padding: EdgeInsets.all(16.fit), 56 | child: LoadAssetImage( 57 | 'statistic/icon_selected', 58 | height: 16.fit, 59 | width: 16.fit, 60 | ), 61 | ), 62 | ], 63 | ), 64 | ), 65 | Expanded( 66 | child: Container( 67 | padding: EdgeInsets.only(left: 16.fit, right: 16.fit), 68 | child: content, 69 | ), 70 | ), 71 | ], 72 | ), 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/res/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Colours { 4 | static const Color appMain = Color(0xFF4688FA); 5 | static const Color darkAppMain = Color(0xFF3F7AE0); 6 | 7 | static const Color bgColor = Color(0xfff1f1f1); 8 | static const Color darkBgColor = Color(0xFF18191A); 9 | 10 | static const Color materialBg = Color(0xFFFFFFFF); 11 | static const Color darkMaterialBg = Color(0xFF303233); 12 | 13 | static const Color text = Color(0xFF333333); 14 | static const Color darkText = Color(0xFFB8B8B8); 15 | 16 | static const Color textGray = Color(0xFF999999); 17 | static const Color darkTextGray = Color(0xFF666666); 18 | 19 | static const Color textGrayC = Color(0xFFcccccc); 20 | static const Color darkButtonText = Color(0xFFF2F2F2); 21 | 22 | static const Color bgGray = Color(0xFFF6F6F6); 23 | static const Color darkBgGray = Color(0xFF1F1F1F); 24 | 25 | static const Color line = Color(0xFFEEEEEE); 26 | static const Color darkLine = Color(0xFF3A3C3D); 27 | 28 | static const Color red = Color(0xFFFF4759); 29 | static const Color darkRed = Color(0xFFE03E4E); 30 | 31 | static const Color textDisabled = Color(0xFFD4E2FA); 32 | static const Color darkTextDisabled = Color(0xFFCEDBF2); 33 | 34 | static const Color buttonDisabled = Color(0xFF96BBFA); 35 | static const Color darkButtonDisabled = Color(0xFF83A5E0); 36 | 37 | static const Color unselectedItemColor = Color(0xffbfbfbf); 38 | static const Color darkUnselectedItemColor = Color(0xFF4D4D4D); 39 | 40 | static const Color bgGray_ = Color(0xFFFAFAFA); 41 | static const Color darkBgGray_ = Color(0xFF242526); 42 | 43 | static const Color gradientBlue = Color(0xFF5793FA); 44 | static const Color shadowBlue = Color(0x805793FA); 45 | static const Color orange = Color(0xFFFF8547); 46 | } 47 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/res/text_styles.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'colors.dart'; 4 | 5 | class TextStyles { 6 | static const TextStyle textSize12 = TextStyle( 7 | fontSize: 12, 8 | ); 9 | static const TextStyle textSize16 = TextStyle( 10 | fontSize: 16, 11 | ); 12 | static const TextStyle textBold14 = 13 | TextStyle(fontSize: 14, fontWeight: FontWeight.bold); 14 | static const TextStyle textBold16 = 15 | TextStyle(fontSize: 16, fontWeight: FontWeight.bold); 16 | static const TextStyle textBold18 = 17 | TextStyle(fontSize: 18, fontWeight: FontWeight.bold); 18 | static const TextStyle textBold24 = 19 | TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold); 20 | static const TextStyle textBold26 = 21 | TextStyle(fontSize: 26.0, fontWeight: FontWeight.bold); 22 | 23 | static const TextStyle textGray14 = TextStyle( 24 | fontSize: 14, 25 | color: Colours.textGray, 26 | ); 27 | static const TextStyle textDarkGray14 = TextStyle( 28 | fontSize: 14, 29 | color: Colours.darkTextGray, 30 | ); 31 | 32 | static const TextStyle textWhite14 = TextStyle( 33 | fontSize: 14, 34 | color: Colors.white, 35 | ); 36 | 37 | static const TextStyle text = TextStyle( 38 | fontSize: 14, 39 | color: Colours.text, 40 | // https://github.com/flutter/flutter/issues/40248 41 | textBaseline: TextBaseline.alphabetic, 42 | ); 43 | static const TextStyle textDark = TextStyle( 44 | fontSize: 14, 45 | color: Colours.darkText, 46 | textBaseline: TextBaseline.alphabetic, 47 | ); 48 | 49 | static const TextStyle textGray12 = TextStyle( 50 | fontSize: 12, color: Colours.textGray, fontWeight: FontWeight.normal); 51 | static const TextStyle textDarkGray12 = TextStyle( 52 | fontSize: 12, color: Colours.darkTextGray, fontWeight: FontWeight.normal); 53 | 54 | static const TextStyle textHint14 = 55 | TextStyle(fontSize: 14, color: Colours.darkUnselectedItemColor); 56 | } 57 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/routers/deer_routers.dart: -------------------------------------------------------------------------------- 1 | import 'package:fluro/fluro.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/goods/goods_route.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/home/common_router.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/login/login_route.dart'; 5 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/order/order_router.dart'; 6 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/settings/setting_router.dart'; 7 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/shop/shop_router.dart'; 8 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/statistics/statistics_router.dart'; 9 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/not_found_page.dart'; 10 | 11 | abstract class ModularRouterProvider { 12 | void initRouter(FluroRouter router); 13 | } 14 | 15 | class DeerRouters { 16 | static final FluroRouter router = FluroRouter(); 17 | 18 | static final List _listRouters = []; 19 | 20 | static void initRoutes() { 21 | /// 配置错误页面 22 | router.notFoundHandler = Handler(handlerFunc: (context, params) { 23 | return const NotFoundPage(); 24 | }); 25 | 26 | _listRouters.clear(); 27 | 28 | /// 配置路由 29 | _listRouters.add(CommonRouter()); 30 | _listRouters.add(LoginRouter()); 31 | _listRouters.add(GoodsRouter()); 32 | _listRouters.add(OrderRouter()); 33 | _listRouters.add(StatisticsRouter()); 34 | _listRouters.add(ShopRouter()); 35 | _listRouters.add(SettingRouter()); 36 | 37 | for (final element in _listRouters) { 38 | element.initRouter(router); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/routers/navigator_interpector.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/common/deer_storage.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/modules/login/login_route.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/navigator_utils.dart'; 5 | 6 | typedef InterpectorNext = void Function(); 7 | 8 | mixin NavigatorInterpector { 9 | /// 下一个拦截器 10 | NavigatorInterpector? next; 11 | 12 | void interpector(BuildContext context, InterpectorNext handler) { 13 | if (next == null) handler(); 14 | next!.interpector(context, handler); 15 | } 16 | } 17 | 18 | class LoginInterpector with NavigatorInterpector { 19 | @override 20 | void interpector(BuildContext context, InterpectorNext handler) { 21 | /// 判断是否登录 22 | if (DeerStorage.isLogin) { 23 | handler(); 24 | return; 25 | } 26 | NavigatorUtils.push(context, LoginRouter.login, resultCallback: (value) { 27 | if (value != null && DeerStorage.isLogin) { 28 | handler(); 29 | return; 30 | } 31 | }); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/routers/not_found_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/my_app_bar.dart'; 3 | 4 | class NotFoundPage extends StatelessWidget { 5 | const NotFoundPage({Key? key}) : super(key: key); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | return const Scaffold( 10 | appBar: MyAppBar( 11 | title: Text('空页面'), 12 | ), 13 | body: Center( 14 | child: Text('错误页面'), 15 | ), 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/utils/image_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:extended_image/extended_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class ImageUtils { 5 | static ImageProvider getAssetImage( 6 | String name, { 7 | ImageFormat format = ImageFormat.png, 8 | }) { 9 | return AssetImage(getImagePath(name, format: format)); 10 | } 11 | 12 | static String getImagePath( 13 | String name, { 14 | ImageFormat format = ImageFormat.png, 15 | }) { 16 | return 'assets/images/$name.${format.value}'; 17 | } 18 | 19 | static ImageProvider getImageProvider( 20 | String? imageUrl, { 21 | String holderImg = 'none', 22 | ImageFormat format = ImageFormat.png, 23 | }) { 24 | if ((imageUrl ?? '').isEmpty) { 25 | return AssetImage(getImagePath(holderImg, format: format)); 26 | } 27 | return ExtendedNetworkImageProvider( 28 | imageUrl!, 29 | cache: true, 30 | ); 31 | } 32 | } 33 | 34 | enum ImageFormat { 35 | png, 36 | jpg, 37 | gif, 38 | webp, 39 | } 40 | 41 | extension ImageForamtExtension on ImageFormat { 42 | String get value => name; 43 | } 44 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/utils/overlay_utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class OverlayUtils { 4 | static OverlayEntry showEntry( 5 | BuildContext context, 6 | WidgetBuilder builder, 7 | ) { 8 | final entry = OverlayEntry(builder: builder); 9 | Overlay.of(context).insert(entry); 10 | return entry; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/utils/random_utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class RandomUtil { 6 | static final random = Random(); 7 | 8 | static Color get color => Color.fromRGBO( 9 | random.nextInt(256), random.nextInt(256), random.nextInt(256), 1); 10 | 11 | static int number(int max) => random.nextInt(max); 12 | } 13 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/utils/screen_untils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ScreenUtils { 4 | ScreenUtils._(); 5 | 6 | static final _instance = ScreenUtils._(); 7 | 8 | BuildContext? _context; 9 | 10 | static BuildContext get _currentContext => _instance._context!; 11 | 12 | static void config(BuildContext context) { 13 | _instance._context = context; 14 | } 15 | 16 | static MediaQueryData get mediaQuery => MediaQuery.of(_currentContext); 17 | 18 | static double get topPadding => mediaQuery.viewPadding.top; 19 | 20 | static double get bottomPadding => mediaQuery.viewPadding.bottom; 21 | 22 | static double get navBarHeight => 44; 23 | 24 | static double get width => mediaQuery.size.width; 25 | 26 | static double get height => mediaQuery.size.height; 27 | 28 | static double get keyboardHeight => 29 | MediaQueryData.fromView(WidgetsBinding.instance.window).viewInsets.bottom; 30 | 31 | static double get scale { 32 | if (width > 0) { 33 | return width / 375; 34 | } else { 35 | return 1; 36 | } 37 | } 38 | } 39 | 40 | extension ScreenUtilsFit on num { 41 | double get fit => ((ScreenUtils.scale * this) * 10).roundToDouble() / 10; 42 | } 43 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/utils/string_extension.dart: -------------------------------------------------------------------------------- 1 | extension StringExtension on String { 2 | /// 添加分隔符 3 | String get text => split('').join('\u{200B}'); 4 | } 5 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/utils/toast.dart: -------------------------------------------------------------------------------- 1 | import 'package:oktoast/oktoast.dart'; 2 | 3 | class Toast { 4 | static void show(String? msg, {int duration = 2000}) { 5 | if (msg == null) return; 6 | 7 | showToast( 8 | msg, 9 | duration: Duration(milliseconds: duration), 10 | dismissOtherToast: true, 11 | ); 12 | } 13 | 14 | static void cancelToast() { 15 | dismissAllToast(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/alert_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/text_styles.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/common_dialog.dart'; 4 | 5 | class AlertView extends StatelessWidget { 6 | final String title; 7 | final String message; 8 | final VoidCallback onTap; 9 | 10 | const AlertView({ 11 | Key? key, 12 | required this.title, 13 | required this.message, 14 | required this.onTap, 15 | }) : super(key: key); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return CommonDialog( 20 | horizontalSpace: 40, 21 | title: title, 22 | onEnsure: onTap, 23 | children: [ 24 | Container( 25 | padding: const EdgeInsets.only( 26 | left: 20, 27 | right: 20, 28 | top: 10, 29 | bottom: 14, 30 | ), 31 | child: Text( 32 | message, 33 | textAlign: TextAlign.center, 34 | style: TextStyles.textSize16, 35 | ), 36 | ), 37 | ], 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/always_keep_alive.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class AlwaysKeepAlive extends StatefulWidget { 4 | final Widget child; 5 | 6 | const AlwaysKeepAlive({ 7 | Key? key, 8 | required this.child, 9 | }) : super(key: key); 10 | 11 | @override 12 | State createState() => _AlwaysKeepAliveState(); 13 | } 14 | 15 | class _AlwaysKeepAliveState extends State 16 | with AutomaticKeepAliveClientMixin { 17 | @override 18 | Widget build(BuildContext context) { 19 | super.build(context); 20 | return widget.child; 21 | } 22 | 23 | @override 24 | bool get wantKeepAlive => true; 25 | } 26 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/custon_back_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/routers/navigator_utils.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 4 | 5 | class CustomBackButton extends StatelessWidget { 6 | final double width; 7 | final double height; 8 | 9 | final VoidCallback? onTap; 10 | 11 | const CustomBackButton({ 12 | Key? key, 13 | this.width = 44, 14 | this.height = 44, 15 | this.onTap, 16 | }) : super(key: key); 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return GestureDetector( 21 | behavior: HitTestBehavior.translucent, 22 | onTap: onTap ?? () => NavigatorUtils.pop(context), 23 | child: Container( 24 | alignment: Alignment.center, 25 | width: width, 26 | height: height, 27 | child: const LoadAssetImage( 28 | 'ic_back_black', 29 | width: 24, 30 | height: 24, 31 | ), 32 | ), 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/empty_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/res/colors.dart'; 4 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 5 | 6 | class EmptyView extends StatelessWidget { 7 | final EmptyType type; 8 | final String? hintText; 9 | 10 | const EmptyView({ 11 | Key? key, 12 | required this.type, 13 | this.hintText, 14 | }) : super(key: key); 15 | 16 | @override 17 | Widget build(BuildContext context) { 18 | return Column( 19 | mainAxisAlignment: MainAxisAlignment.center, 20 | children: [ 21 | LoadAssetImage( 22 | 'state/${type.img}', 23 | width: 120, 24 | ), 25 | const SizedBox(height: 16), 26 | Text( 27 | hintText ?? type.hintText, 28 | style: const TextStyle( 29 | fontSize: 14, 30 | color: Colours.text, 31 | ), 32 | ) 33 | ], 34 | ); 35 | } 36 | } 37 | 38 | enum EmptyType { 39 | /// 订单 40 | order, 41 | 42 | /// 商品 43 | goods, 44 | 45 | /// 无网络 46 | network, 47 | 48 | /// 消息 49 | message, 50 | 51 | /// 无提现账号 52 | account, 53 | 54 | /// 空 55 | empty 56 | } 57 | 58 | extension EmptyTypeExtension on EmptyType { 59 | String get img => 60 | ['zwdd', 'zwsp', 'zwwl', 'zwxx', 'zwzh', 'zwdd'][index]; 61 | 62 | String get hintText => 63 | ['暂无订单', '暂无商品', '无网络连接', '暂无消息', '马上添加提现账号吧', '暂无数据'][index]; 64 | } 65 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/list_click_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/load_image.dart'; 4 | 5 | class ListClickItem extends StatelessWidget { 6 | final VoidCallback onTap; 7 | final String title; 8 | const ListClickItem({ 9 | Key? key, 10 | required this.title, 11 | required this.onTap, 12 | }) : super(key: key); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return InkWell( 17 | onTap: onTap, 18 | child: Container( 19 | padding: EdgeInsets.only(left: 16.fit), 20 | child: Column( 21 | mainAxisSize: MainAxisSize.min, 22 | children: [ 23 | SizedBox( 24 | height: 52.fit, 25 | child: Row( 26 | children: [ 27 | Expanded(child: Text(title)), 28 | LoadAssetImage('ic_arrow_right', 29 | height: 16.fit, width: 16.fit), 30 | SizedBox(width: 16.fit), 31 | ], 32 | ), 33 | ), 34 | const Divider(), 35 | ], 36 | ), 37 | ), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/load_more_footer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | 3 | class LoadMoreFooter extends StatelessWidget { 4 | final bool hasMore; 5 | const LoadMoreFooter({ 6 | Key? key, 7 | required this.hasMore, 8 | }) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | if (hasMore) { 13 | return Container( 14 | height: 50, 15 | alignment: Alignment.center, 16 | child: Row( 17 | mainAxisSize: MainAxisSize.min, 18 | children: const [ 19 | Text('正在加载更多'), 20 | SizedBox( 21 | width: 10, 22 | ), 23 | SizedBox( 24 | width: 10, 25 | height: 10, 26 | child: CupertinoActivityIndicator(), 27 | ) 28 | ], 29 | ), 30 | ); 31 | } else { 32 | return Container( 33 | height: 50, 34 | alignment: Alignment.center, 35 | child: const Text('到底了 ~'), 36 | ); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/my_app_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/utils/screen_untils.dart'; 3 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/custon_back_button.dart'; 4 | 5 | class MyAppBar extends StatelessWidget implements PreferredSizeWidget { 6 | final Widget? title; 7 | final Widget? leading; 8 | final List? actions; 9 | final double? elevation; 10 | final bool automaticallyImplyLeading; 11 | final double? titleSpacing; 12 | 13 | const MyAppBar({ 14 | Key? key, 15 | this.title, 16 | this.leading, 17 | this.actions, 18 | this.elevation, 19 | this.titleSpacing, 20 | this.automaticallyImplyLeading = true, 21 | }) : super(key: key); 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | final ModalRoute? parentRoute = ModalRoute.of(context); 26 | final bool canPop = parentRoute?.canPop ?? false; 27 | 28 | Widget? backButton; 29 | if (automaticallyImplyLeading && canPop) { 30 | backButton = const CustomBackButton(); 31 | } 32 | return MediaQuery( 33 | data: MediaQuery.of(context).copyWith(textScaleFactor: 1), 34 | child: AppBar( 35 | titleSpacing: titleSpacing, 36 | automaticallyImplyLeading: automaticallyImplyLeading, 37 | elevation: elevation, 38 | title: title, 39 | leading: leading ?? backButton, 40 | actions: actions, 41 | ), 42 | ); 43 | } 44 | 45 | @override 46 | Size get preferredSize => Size.fromHeight(ScreenUtils.navBarHeight); 47 | } 48 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/my_edit_scroll_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/flutter_deer/widgets/my_scroll_view.dart'; 3 | 4 | /// 使用请关闭外部scaffold - resizeToAvoidBottomInset = false 5 | class MyEditScrollView extends StatelessWidget { 6 | final List children; 7 | 8 | final EdgeInsetsGeometry? padding; 9 | 10 | final Widget bottom; 11 | 12 | final double bottomHeight; 13 | 14 | final bool resizeToAvoidBottomInset; 15 | 16 | const MyEditScrollView({ 17 | Key? key, 18 | required this.children, 19 | this.padding, 20 | required this.bottom, 21 | required this.bottomHeight, 22 | this.resizeToAvoidBottomInset = true, 23 | }) : super(key: key); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return Stack( 28 | fit: StackFit.expand, 29 | children: [ 30 | Scaffold( 31 | resizeToAvoidBottomInset: resizeToAvoidBottomInset, 32 | body: MyScrollView( 33 | padding: padding, 34 | children: [ 35 | ...children, 36 | SizedBox( 37 | height: bottomHeight, 38 | ), 39 | ], 40 | ), 41 | ), 42 | Positioned( 43 | left: 0, 44 | bottom: 0, 45 | right: 0, 46 | height: bottomHeight, 47 | child: bottom, 48 | ) 49 | ], 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/examples/flutter_deer/widgets/my_scroll_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// 总是能滑动 4 | class MyScrollView extends StatelessWidget { 5 | final List children; 6 | 7 | final EdgeInsetsGeometry? padding; 8 | 9 | const MyScrollView({ 10 | Key? key, 11 | this.children = const [], 12 | this.padding, 13 | }) : super(key: key); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return LayoutBuilder(builder: (context, constraints) { 18 | return SingleChildScrollView( 19 | physics: const AlwaysScrollableScrollPhysics( 20 | parent: BouncingScrollPhysics()), 21 | padding: padding, 22 | child: ConstrainedBox( 23 | constraints: BoxConstraints( 24 | minHeight: constraints.maxHeight - (padding?.vertical ?? 0), 25 | minWidth: constraints.maxWidth - (padding?.horizontal ?? 0), 26 | ), 27 | child: Column( 28 | crossAxisAlignment: CrossAxisAlignment.start, 29 | children: children, 30 | ), 31 | ), 32 | ); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/examples/ui_chanllenge/curves/curves_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/ui_chanllenge/curves/curve_type.dart'; 3 | import 'package:flutter_ui_challenge/examples/ui_chanllenge/curves/curves_item.dart'; 4 | 5 | class CurvesPage extends StatelessWidget { 6 | static const route = 'Curves - 效果展示'; 7 | const CurvesPage({Key? key}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | const curves = CurveType.values; 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text('${curves.length}种Curve效果'), 15 | ), 16 | body: ListView.separated( 17 | padding: EdgeInsets.only( 18 | top: 10, 19 | left: 10, 20 | right: 10, 21 | bottom: MediaQuery.of(context).padding.bottom), 22 | itemBuilder: (context, index) { 23 | return CurveItem(curveType: curves[index]); 24 | }, 25 | separatorBuilder: (context, index) => const SizedBox(height: 10), 26 | itemCount: curves.length, 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/examples/ui_chanllenge/custom_slider/custom_slider_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/ui_chanllenge/custom_slider/custom_slider.dart'; 3 | 4 | class CustomSliderPage extends StatelessWidget { 5 | static const route = '自定义Slider: 自定义Widget+RenderObject'; 6 | CustomSliderPage({Key? key}) : super(key: key); 7 | 8 | final ValueNotifier progress = ValueNotifier(0); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: const Text('自定义Slider'), 15 | ), 16 | body: SizedBox.expand( 17 | child: Column( 18 | mainAxisAlignment: MainAxisAlignment.center, 19 | children: [ 20 | ValueListenableBuilder( 21 | valueListenable: progress, 22 | builder: (context, value, _) { 23 | return Text('$value'); 24 | }, 25 | ), 26 | Container( 27 | padding: const EdgeInsets.all(20), 28 | child: CustomSlider( 29 | barColor: Colors.blue, 30 | thumbColor: Colors.red, 31 | thumbSize: 20, 32 | barHeight: 5, 33 | progressChanged: (value) => progress.value = value, 34 | progress: progress.value, 35 | ), 36 | ), 37 | ], 38 | ), 39 | ), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/examples/ui_chanllenge/routes.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_ui_challenge/examples/ui_chanllenge/curves/curves_page.dart'; 3 | import 'package:flutter_ui_challenge/examples/ui_chanllenge/custom_slider/custom_slider_page.dart'; 4 | 5 | Map routes = { 6 | CustomSliderPage.route: (context) => CustomSliderPage(), 7 | CurvesPage.route: (context) => const CurvesPage(), 8 | }; 9 | -------------------------------------------------------------------------------- /lib/examples/ui_chanllenge/theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | class Themes { 5 | static const Map _defaultBuilders = { 6 | TargetPlatform.android: CupertinoPageTransitionsBuilder(), 7 | TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), 8 | }; 9 | 10 | static ThemeData lightTheme = ThemeData( 11 | pageTransitionsTheme: 12 | const PageTransitionsTheme(builders: _defaultBuilders), 13 | appBarTheme: const AppBarTheme( 14 | toolbarHeight: 44, 15 | foregroundColor: Colors.black, 16 | backgroundColor: Colors.white, 17 | shadowColor: Colors.black45, 18 | elevation: 0.5, 19 | centerTitle: true, 20 | titleTextStyle: TextStyle( 21 | fontSize: 18, 22 | color: Colors.black, 23 | fontWeight: FontWeight.bold, 24 | ), 25 | systemOverlayStyle: SystemUiOverlayStyle.dark, 26 | ), 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 6 | import 'package:flutter_ui_challenge/examples/flutter_deer/deer_app.dart'; 7 | 8 | final mainAppProvider = StateProvider((ref) { 9 | return DeerApp(); 10 | }); 11 | 12 | void main() { 13 | WidgetsFlutterBinding.ensureInitialized(); 14 | runApp( 15 | ProviderScope( 16 | child: Consumer( 17 | builder: (context, ref, _) { 18 | return ref.watch(mainAppProvider); 19 | }, 20 | ), 21 | ), 22 | ); 23 | if (Platform.isAndroid) { 24 | //透明沉浸式状态栏 25 | SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( 26 | statusBarColor: Colors.transparent, // transparent status bar 27 | )); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void fl_register_plugins(FlPluginRegistry* registry) { 12 | g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = 13 | fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); 14 | file_selector_plugin_register_with_registrar(file_selector_linux_registrar); 15 | } 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | file_selector_linux 7 | ) 8 | 9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 10 | ) 11 | 12 | set(PLUGIN_BUNDLED_LIBRARIES) 13 | 14 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 19 | endforeach(plugin) 20 | 21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 24 | endforeach(ffi_plugin) 25 | -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import file_selector_macos 9 | import path_provider_foundation 10 | import shared_preferences_foundation 11 | 12 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 13 | FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) 14 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 15 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 16 | } 17 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FlutterMacOS (1.0.0) 3 | - FMDB (2.7.5): 4 | - FMDB/standard (= 2.7.5) 5 | - FMDB/standard (2.7.5) 6 | - path_provider_macos (0.0.1): 7 | - FlutterMacOS 8 | - shared_preferences_macos (0.0.1): 9 | - FlutterMacOS 10 | - sqflite (0.0.2): 11 | - FlutterMacOS 12 | - FMDB (>= 2.7.5) 13 | - url_launcher_macos (0.0.1): 14 | - FlutterMacOS 15 | 16 | DEPENDENCIES: 17 | - FlutterMacOS (from `Flutter/ephemeral`) 18 | - path_provider_macos (from `Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos`) 19 | - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) 20 | - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) 21 | - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) 22 | 23 | SPEC REPOS: 24 | trunk: 25 | - FMDB 26 | 27 | EXTERNAL SOURCES: 28 | FlutterMacOS: 29 | :path: Flutter/ephemeral 30 | path_provider_macos: 31 | :path: Flutter/ephemeral/.symlinks/plugins/path_provider_macos/macos 32 | shared_preferences_macos: 33 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos 34 | sqflite: 35 | :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos 36 | url_launcher_macos: 37 | :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos 38 | 39 | SPEC CHECKSUMS: 40 | FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 41 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 42 | path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19 43 | shared_preferences_macos: a64dc611287ed6cbe28fd1297898db1336975727 44 | sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea 45 | url_launcher_macos: 597e05b8e514239626bcf4a850fcf9ef5c856ec3 46 | 47 | PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c 48 | 49 | COCOAPODS: 1.11.3 50 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = flutter_ui_challenge 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterUiChallenge 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_ui_challenge 2 | description: A new Flutter project. 3 | 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ">=3.0.5 <4.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | cupertino_icons: ^1.0.2 13 | # 状态管理 14 | flutter_riverpod: ^1.0.4 15 | # 存储 16 | shared_preferences: ^2.0.15 17 | # 路由 18 | fluro: ^2.0.3 19 | # Toast 20 | oktoast: ^3.2.0 21 | # 图片选择 22 | image_picker: ^0.8.5+3 23 | # 图片缓存 24 | extended_image: 25 | equatable: ^2.0.3 26 | # webview 27 | webview_flutter: 28 | # 使用到了DateFormat 29 | intl: ^0.17.0 30 | # json转model相关 31 | freezed_annotation: ^2.1.0 32 | json_annotation: ^4.6.0 33 | # 悬停 & 分区 & scrollToIndex 34 | flutter_table_list_view: ^0.0.1 35 | flutter_easy_segment: ^0.0.3 36 | 37 | dev_dependencies: 38 | flutter_test: 39 | sdk: flutter 40 | flutter_lints: ^2.0.0 41 | build_runner: ^2.2.0 42 | freezed: ^2.1.0+1 43 | json_serializable: ^6.3.1 44 | 45 | # For information on the generic Dart part of this file, see the 46 | # following page: https://dart.dev/tools/pub/pubspec 47 | 48 | # The following section is specific to Flutter packages. 49 | flutter: 50 | uses-material-design: true 51 | 52 | assets: 53 | - assets/data/ 54 | - assets/images/ 55 | - assets/images/home/ 56 | - assets/images/store/ 57 | - assets/images/state/ 58 | - assets/images/order/ 59 | - assets/images/order/dark/ 60 | - assets/images/login/ 61 | - assets/images/goods/ 62 | - assets/images/shop/ 63 | - assets/images/account/ 64 | - assets/images/statistic/ 65 | - assets/lottie/ 66 | 67 | fonts: 68 | - family: RobotoThin 69 | fonts: 70 | - asset: assets/fonts/Roboto-Thin.ttf 71 | # 72 | # For details regarding fonts from package dependencies, 73 | # see https://flutter.dev/custom-fonts/#from-packages 74 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | flutter_ui_challenge 33 | 34 | 35 | 39 | 40 | 41 | 42 | 43 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_ui_challenge", 3 | "short_name": "flutter_ui_challenge", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void RegisterPlugins(flutter::PluginRegistry* registry) { 12 | FileSelectorWindowsRegisterWithRegistrar( 13 | registry->GetRegistrarForPlugin("FileSelectorWindows")); 14 | } 15 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | file_selector_windows 7 | ) 8 | 9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 10 | ) 11 | 12 | set(PLUGIN_BUNDLED_LIBRARIES) 13 | 14 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 19 | endforeach(plugin) 20 | 21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 24 | endforeach(ffi_plugin) 25 | -------------------------------------------------------------------------------- /windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Disable Windows macros that collide with C++ standard library functions. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 25 | 26 | # Add dependency libraries and include directories. Add any application-specific 27 | # dependencies here. 28 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 29 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 30 | 31 | # Run the Flutter tool portions of the build. This must not be removed. 32 | add_dependencies(${BINARY_NAME} flutter_assemble) 33 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | return true; 30 | } 31 | 32 | void FlutterWindow::OnDestroy() { 33 | if (flutter_controller_) { 34 | flutter_controller_ = nullptr; 35 | } 36 | 37 | Win32Window::OnDestroy(); 38 | } 39 | 40 | LRESULT 41 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 42 | WPARAM const wparam, 43 | LPARAM const lparam) noexcept { 44 | // Give Flutter, including plugins, an opportunity to handle window messages. 45 | if (flutter_controller_) { 46 | std::optional result = 47 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 48 | lparam); 49 | if (result) { 50 | return *result; 51 | } 52 | } 53 | 54 | switch (message) { 55 | case WM_FONTCHANGE: 56 | flutter_controller_->engine()->ReloadSystemFonts(); 57 | break; 58 | } 59 | 60 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 61 | } 62 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.CreateAndShow(L"flutter_ui_challenge", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MengLiMing/flutter_ui_challenge/6f775061bd7ffd9525f84499a3f2590e71e7b91f/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | std::string utf8_string; 52 | if (target_length == 0 || target_length > utf8_string.max_size()) { 53 | return utf8_string; 54 | } 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | --------------------------------------------------------------------------------