├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcworkspace │ └── contents.xcworkspacedata └── Runner.xcodeproj │ └── project.xcworkspace │ └── contents.xcworkspacedata ├── lib ├── agor │ └── utils │ │ └── settings.dart ├── constants │ ├── index.dart │ ├── length.dart │ ├── string.dart │ ├── font.dart │ ├── color.dart │ └── filter_menu.dart ├── model │ ├── state_model │ │ ├── base_state_model.dart │ │ ├── tab_state_model.dart │ │ └── theme_state_model.dart │ ├── beautyimage.dart │ ├── buy_model.dart │ ├── pood │ │ ├── Index_tab_model.dart │ │ └── video_detail_model.dart │ ├── banner.dart │ ├── kingkong.dart │ ├── msg_model.dart │ ├── sub_category.dart │ ├── model_cell.dart │ ├── cart.dart │ ├── paylog_model.dart │ ├── crowdfund.dart │ ├── oder_model.dart │ ├── product.dart │ ├── search.dart │ ├── song.dart │ └── userinfo.dart ├── components │ ├── keyboard │ │ ├── pay_password.dart │ │ ├── custom_keyboard_button.dart │ │ └── CustomJPasswordFieldWidget.dart │ ├── empty_component.dart │ ├── in_text_dot.dart │ ├── SliveTabbarDelege.dart │ ├── load_more.dart │ ├── tag_component.dart │ ├── sliver_appbar_delegate.dart │ ├── video_detail_item_component.dart │ ├── ToastDialog.dart │ ├── fiexdAppbar.dart │ ├── dropdown.dart │ ├── loginButton.dart │ ├── icon_with_text.dart │ ├── LoadingDialog.dart │ ├── animation_text_component.dart │ ├── wxshare.dart │ ├── wxPay.dart │ ├── index_model_list.dart │ └── topbar.dart ├── model.dart ├── widgets │ ├── index.dart │ ├── divideline.dart │ ├── CustomIcon.dart │ ├── CustomInactiveIcon.dart │ ├── topbar.dart │ ├── category │ │ ├── search_bar.dart │ │ └── right_list_view.dart │ ├── search │ │ ├── listtopbar.dart │ │ ├── recomend.dart │ │ ├── hotSug.dart │ │ └── topbar.dart │ ├── NavigationIconView.dart │ └── bottombar.dart ├── views │ ├── details │ │ ├── details_top_area.dart │ │ ├── details_web.dart │ │ ├── details_tabar.dart │ │ ├── details_explain.dart │ │ └── Details_bottom.dart │ ├── player │ │ ├── opacity_tap_widget.dart │ │ └── audio_tool.dart │ ├── search │ │ ├── listtopbar.dart │ │ ├── searchserver.dart │ │ ├── search.dart │ │ └── searchlist.dart │ ├── cart │ │ ├── cart.dart │ │ └── cart_list.dart │ ├── secendpage.dart │ ├── person │ │ ├── myfavera.dart │ │ └── tempdemo_list.dart │ ├── category_Page.dart │ ├── noticeMessgeList.dart │ ├── webView.dart │ └── message_page.dart ├── api │ └── movie.dart ├── video │ ├── video_web.dart │ ├── videoplayer.dart │ ├── anims │ │ ├── record_anim.dart │ │ └── needle_anim.dart │ ├── chewie_list_item.dart │ ├── demo_video_player.dart │ └── player.dart ├── main_provide.dart ├── data │ ├── base2.dart │ ├── base.dart │ └── cart.dart ├── utils │ ├── fiexdAppbar.dart │ ├── utils.dart │ ├── cacheUtil.dart │ └── screen_util.dart ├── globleConfig.dart ├── routers │ ├── routes.dart │ └── router_handler.dart ├── movie │ └── moviedetail.dart └── SplashScreen.dart ├── images ├── x.png ├── 签到.png ├── 1199.png ├── 1200.png ├── about.png ├── bill.png ├── czzy.png ├── disc.png ├── gift.png ├── help.png ├── level.png ├── logo.png ├── order.png ├── quota.png ├── share.png ├── vip-白.png ├── vip.png ├── address.png ├── balance.png ├── bg_img.png ├── express.png ├── locking.png ├── logo_b.png ├── reward.png ├── thehorn.png ├── zhuanru.png ├── 2.0x │ ├── logo.png │ └── logo_b.png ├── 3.0x │ ├── logo.png │ └── logo_b.png ├── IMG_1198.PNG ├── IMG_1199.PNG ├── changehen.png ├── detailed.png ├── exchange.png ├── exchangetb.png ├── headerlogo.png ├── mustread.png ├── walletico.png ├── icon │ ├── img_png.png │ ├── icon_ann.png │ ├── icon_apply.png │ ├── icon_helpt.png │ ├── icon_jilu.png │ ├── icon_my_n.png │ ├── icon_my_s.png │ ├── icon_myimg.png │ ├── icon_order.png │ ├── icon_plan.png │ ├── icon_purse.png │ ├── icon_setup.png │ ├── img_visa.png │ ├── icon_card_n.png │ ├── icon_card_s.png │ ├── icon_home_n.png │ ├── icon_home_s.png │ ├── icon_pingan.png │ ├── icon_wechat.png │ └── icon_administer.png ├── icon_wechat.png ├── play_needle.png ├── play_needle2.png ├── placehoder_img.png ├── icon_placeholder.png └── icon_default_avatar.png ├── assets ├── icon │ └── icon.png ├── fonts │ ├── Lobster-1.4.otf │ └── FZLanTingHeiS-DB1-GB-Regular.TTF └── images │ ├── icon_empty.webp │ ├── icon_home_tab.png │ ├── icon_mine_tab.png │ ├── icon_load_error.png │ ├── icon_movie_tab.png │ ├── icon_feature_tab.png │ ├── icon_placeholder.png │ ├── icon_popular_tab.png │ ├── icon_default_avatar.png │ ├── icon_videodetail_num.png │ ├── icon_home_tab_pressed.png │ ├── icon_mine_tab_pressed.png │ ├── icon_movie_tab_pressed.png │ ├── icon_videodetail_desc.png │ ├── icon_videodetail_jishu.png │ ├── icon_videodetail_name.png │ ├── icon_feature_tab_pressed.png │ ├── icon_popular_tab_pressed.png │ ├── icon_videodetail_director.png │ ├── icon_videodetail_playlist.png │ └── icon_videodetail_starring.png ├── android ├── key.properties ├── app │ ├── english_key.jks │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── logo_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── logo_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── logo_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── logo_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── logo_launcher.png │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── drawable │ │ │ │ │ └── launch_background.xml │ │ │ └── kotlin │ │ │ │ └── be │ │ │ │ └── goodgood │ │ │ │ └── flutter_english │ │ │ │ └── MainActivity.kt │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── todo ├── .metadata ├── test └── widget_test.dart ├── .gitignore └── README.md /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" -------------------------------------------------------------------------------- /lib/agor/utils/settings.dart: -------------------------------------------------------------------------------- 1 | // Agora AppId 2 | const APP_ID = ''; 3 | -------------------------------------------------------------------------------- /images/x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/x.png -------------------------------------------------------------------------------- /images/签到.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/签到.png -------------------------------------------------------------------------------- /images/1199.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/1199.png -------------------------------------------------------------------------------- /images/1200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/1200.png -------------------------------------------------------------------------------- /images/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/about.png -------------------------------------------------------------------------------- /images/bill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/bill.png -------------------------------------------------------------------------------- /images/czzy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/czzy.png -------------------------------------------------------------------------------- /images/disc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/disc.png -------------------------------------------------------------------------------- /images/gift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/gift.png -------------------------------------------------------------------------------- /images/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/help.png -------------------------------------------------------------------------------- /images/level.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/level.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/logo.png -------------------------------------------------------------------------------- /images/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/order.png -------------------------------------------------------------------------------- /images/quota.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/quota.png -------------------------------------------------------------------------------- /images/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/share.png -------------------------------------------------------------------------------- /images/vip-白.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/vip-白.png -------------------------------------------------------------------------------- /images/vip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/vip.png -------------------------------------------------------------------------------- /images/address.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/address.png -------------------------------------------------------------------------------- /images/balance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/balance.png -------------------------------------------------------------------------------- /images/bg_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/bg_img.png -------------------------------------------------------------------------------- /images/express.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/express.png -------------------------------------------------------------------------------- /images/locking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/locking.png -------------------------------------------------------------------------------- /images/logo_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/logo_b.png -------------------------------------------------------------------------------- /images/reward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/reward.png -------------------------------------------------------------------------------- /images/thehorn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/thehorn.png -------------------------------------------------------------------------------- /images/zhuanru.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/zhuanru.png -------------------------------------------------------------------------------- /assets/icon/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/icon/icon.png -------------------------------------------------------------------------------- /images/2.0x/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/2.0x/logo.png -------------------------------------------------------------------------------- /images/3.0x/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/3.0x/logo.png -------------------------------------------------------------------------------- /images/IMG_1198.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/IMG_1198.PNG -------------------------------------------------------------------------------- /images/IMG_1199.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/IMG_1199.PNG -------------------------------------------------------------------------------- /images/changehen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/changehen.png -------------------------------------------------------------------------------- /images/detailed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/detailed.png -------------------------------------------------------------------------------- /images/exchange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/exchange.png -------------------------------------------------------------------------------- /images/exchangetb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/exchangetb.png -------------------------------------------------------------------------------- /images/headerlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/headerlogo.png -------------------------------------------------------------------------------- /images/mustread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/mustread.png -------------------------------------------------------------------------------- /images/walletico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/walletico.png -------------------------------------------------------------------------------- /android/key.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/key.properties -------------------------------------------------------------------------------- /images/2.0x/logo_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/2.0x/logo_b.png -------------------------------------------------------------------------------- /images/3.0x/logo_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/3.0x/logo_b.png -------------------------------------------------------------------------------- /images/icon/img_png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/img_png.png -------------------------------------------------------------------------------- /images/icon_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon_wechat.png -------------------------------------------------------------------------------- /images/play_needle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/play_needle.png -------------------------------------------------------------------------------- /images/play_needle2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/play_needle2.png -------------------------------------------------------------------------------- /images/icon/icon_ann.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_ann.png -------------------------------------------------------------------------------- /images/icon/icon_apply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_apply.png -------------------------------------------------------------------------------- /images/icon/icon_helpt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_helpt.png -------------------------------------------------------------------------------- /images/icon/icon_jilu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_jilu.png -------------------------------------------------------------------------------- /images/icon/icon_my_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_my_n.png -------------------------------------------------------------------------------- /images/icon/icon_my_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_my_s.png -------------------------------------------------------------------------------- /images/icon/icon_myimg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_myimg.png -------------------------------------------------------------------------------- /images/icon/icon_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_order.png -------------------------------------------------------------------------------- /images/icon/icon_plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_plan.png -------------------------------------------------------------------------------- /images/icon/icon_purse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_purse.png -------------------------------------------------------------------------------- /images/icon/icon_setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_setup.png -------------------------------------------------------------------------------- /images/icon/img_visa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/img_visa.png -------------------------------------------------------------------------------- /images/placehoder_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/placehoder_img.png -------------------------------------------------------------------------------- /android/app/english_key.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/english_key.jks -------------------------------------------------------------------------------- /assets/fonts/Lobster-1.4.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/fonts/Lobster-1.4.otf -------------------------------------------------------------------------------- /images/icon/icon_card_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_card_n.png -------------------------------------------------------------------------------- /images/icon/icon_card_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_card_s.png -------------------------------------------------------------------------------- /images/icon/icon_home_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_home_n.png -------------------------------------------------------------------------------- /images/icon/icon_home_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_home_s.png -------------------------------------------------------------------------------- /images/icon/icon_pingan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_pingan.png -------------------------------------------------------------------------------- /images/icon/icon_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_wechat.png -------------------------------------------------------------------------------- /images/icon_placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon_placeholder.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableJetifier=true 3 | android.useAndroidX=true 4 | -------------------------------------------------------------------------------- /assets/images/icon_empty.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_empty.webp -------------------------------------------------------------------------------- /assets/images/icon_home_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_home_tab.png -------------------------------------------------------------------------------- /assets/images/icon_mine_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_mine_tab.png -------------------------------------------------------------------------------- /images/icon/icon_administer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon/icon_administer.png -------------------------------------------------------------------------------- /images/icon_default_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/images/icon_default_avatar.png -------------------------------------------------------------------------------- /lib/constants/index.dart: -------------------------------------------------------------------------------- 1 | export 'color.dart'; 2 | export 'font.dart'; 3 | export 'string.dart'; 4 | export 'length.dart'; -------------------------------------------------------------------------------- /assets/images/icon_load_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_load_error.png -------------------------------------------------------------------------------- /assets/images/icon_movie_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_movie_tab.png -------------------------------------------------------------------------------- /todo: -------------------------------------------------------------------------------- 1 | 1,自动下一首 判断是否购买,购买了才能继续播放 2 | 2,退出再重新进入,字幕条滚动到位问题----。 3 | 3,音乐和字幕文件缓存 4 | 4,弹---- 5 | 5,往上拉 6 | 6,最后一行 7 | 7,第一行可能翻页超过视线范围 -------------------------------------------------------------------------------- /assets/images/icon_feature_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_feature_tab.png -------------------------------------------------------------------------------- /assets/images/icon_placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_placeholder.png -------------------------------------------------------------------------------- /assets/images/icon_popular_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_popular_tab.png -------------------------------------------------------------------------------- /assets/images/icon_default_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_default_avatar.png -------------------------------------------------------------------------------- /assets/images/icon_videodetail_num.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_videodetail_num.png -------------------------------------------------------------------------------- /assets/images/icon_home_tab_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_home_tab_pressed.png -------------------------------------------------------------------------------- /assets/images/icon_mine_tab_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_mine_tab_pressed.png -------------------------------------------------------------------------------- /assets/images/icon_movie_tab_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_movie_tab_pressed.png -------------------------------------------------------------------------------- /assets/images/icon_videodetail_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_videodetail_desc.png -------------------------------------------------------------------------------- /assets/images/icon_videodetail_jishu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_videodetail_jishu.png -------------------------------------------------------------------------------- /assets/images/icon_videodetail_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_videodetail_name.png -------------------------------------------------------------------------------- /assets/images/icon_feature_tab_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_feature_tab_pressed.png -------------------------------------------------------------------------------- /assets/images/icon_popular_tab_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_popular_tab_pressed.png -------------------------------------------------------------------------------- /assets/images/icon_videodetail_director.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_videodetail_director.png -------------------------------------------------------------------------------- /assets/images/icon_videodetail_playlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_videodetail_playlist.png -------------------------------------------------------------------------------- /assets/images/icon_videodetail_starring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/images/icon_videodetail_starring.png -------------------------------------------------------------------------------- /assets/fonts/FZLanTingHeiS-DB1-GB-Regular.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/assets/fonts/FZLanTingHeiS-DB1-GB-Regular.TTF -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/logo_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-hdpi/logo_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/logo_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-mdpi/logo_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/logo_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-xhdpi/logo_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/logo_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-xxhdpi/logo_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/logo_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/android/app/src/main/res/mipmap-xxxhdpi/logo_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiebaoxin/flutter_english/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /lib/model/state_model/base_state_model.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * Model基类 3 | * Create by Songlcy 4 | */ 5 | import 'package:scoped_model/scoped_model.dart'; 6 | 7 | class BaseStateModel extends Model { 8 | 9 | } -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/components/keyboard/pay_password.dart: -------------------------------------------------------------------------------- 1 | /// 支符密码 用于 密码输入框和键盘之间进行通信 2 | class KeyEvent { 3 | String key; 4 | 5 | KeyEvent(this.key); 6 | 7 | bool isDelete() => this.key == "del"; 8 | bool isCommit() => this.key == "commit"; 9 | } 10 | -------------------------------------------------------------------------------- /lib/model.dart: -------------------------------------------------------------------------------- 1 | 2 | export 'model/banner.dart'; 3 | export 'model/kingkong.dart'; 4 | export 'model/product.dart'; 5 | export 'model/crowdfund.dart'; 6 | export 'model/sub_category.dart'; 7 | export 'model/cart.dart'; 8 | export 'model/search.dart'; 9 | export 'model/beautyimage.dart'; -------------------------------------------------------------------------------- /lib/model/beautyimage.dart: -------------------------------------------------------------------------------- 1 | class BeautyImageModal{ 2 | int width; 3 | int height; 4 | String thumb; 5 | BeautyImageModal({this.height,this.width,this.thumb}); 6 | BeautyImageModal.fromJSON(dynamic json):width= int.parse(json['width']),height=int.parse(json['height']),thumb=json['thumb']; 7 | } -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /lib/model/buy_model.dart: -------------------------------------------------------------------------------- 1 | import 'goods.dart'; 2 | class BuyModel{ 3 | String goods_id; 4 | String goods_num; 5 | String item_id; 6 | String action; 7 | String imgurl; 8 | GoodInfo goodsinfo; 9 | double goods_price; 10 | BuyModel({this.goods_id,this.goods_num,this.item_id,this.goods_price,this.goodsinfo,this.imgurl,this.action="buy_now"}); 11 | 12 | } -------------------------------------------------------------------------------- /lib/constants/length.dart: -------------------------------------------------------------------------------- 1 | class Klength{ 2 | static const double topBarHeight = 45;//Dp 3 | static const double bottomBarHeight = 54; 4 | // ///设置适配尺寸 (填入设计稿中设备的屏幕尺寸) 假如设计稿是按iPhone6的尺寸设计的(iPhone6 750*1334) 5 | static const double designWidth = 500; //设计稿想像素宽度 6 | static const double designHeight = 900; //设计稿像素宽度 7 | static const double searchTxtFieldHeight=34; 8 | } -------------------------------------------------------------------------------- /lib/components/empty_component.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 空视图组件 3 | * Create by Songlcy 4 | */ 5 | import 'package:flutter/material.dart'; 6 | 7 | class EmptyComponent extends StatelessWidget { 8 | 9 | const EmptyComponent(); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | width: 0, 15 | height: 0, 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /lib/model/pood/Index_tab_model.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 首页Tab分类实体类 3 | * Create by Songlcy 4 | */ 5 | 6 | class IndexTabModel { 7 | 8 | String id; 9 | String name; 10 | 11 | IndexTabModel({ this.id, this.name }); 12 | 13 | factory IndexTabModel.fromJson(Map jsonObj) { 14 | return new IndexTabModel( 15 | id: jsonObj["_id"], 16 | name: jsonObj["name"] 17 | ); 18 | } 19 | } -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /lib/model/state_model/tab_state_model.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 首页Tab切换Model 3 | */ 4 | import './base_state_model.dart'; 5 | 6 | class TabBarStateModel extends BaseStateModel { 7 | 8 | int _tabBarCurrentIndex = 0; 9 | 10 | get tabBarCurrentIndex => _tabBarCurrentIndex; 11 | 12 | void changeTabBarCurrentIndex(int currentIndex) { 13 | _tabBarCurrentIndex = currentIndex; 14 | notifyListeners(); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /android/app/src/main/kotlin/be/goodgood/flutter_english/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package be.goodgood.flutter_english 2 | 3 | import android.os.Bundle 4 | 5 | import io.flutter.app.FlutterActivity 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | GeneratedPluginRegistrant.registerWith(this) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/components/in_text_dot.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class InTextDot extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Container( 7 | width: 3.0, 8 | height: 3.0, 9 | margin: const EdgeInsets.symmetric(horizontal: 6.0), 10 | decoration: BoxDecoration( 11 | color: Color(0xFFB2BAC2), 12 | borderRadius: BorderRadius.all(Radius.circular(3.0))), 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /lib/widgets/index.dart: -------------------------------------------------------------------------------- 1 | 2 | export 'category/list_view_item.dart'; 3 | export 'category/menue.dart'; 4 | export 'category/right_list_view.dart'; 5 | export 'category/search_bar.dart'; 6 | 7 | export 'bottombar.dart'; 8 | export 'divideline.dart'; 9 | export 'topbar.dart'; 10 | 11 | export '../components/banner.dart'; 12 | 13 | export 'search/hotSug.dart'; 14 | export 'search/recomend.dart'; 15 | export 'search/topbar.dart'; 16 | export 'search/listtopbar.dart'; 17 | export 'search/searchresult.dart'; -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/widgets/divideline.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../constants/index.dart'; 3 | import '../utils/screen_util.dart'; 4 | 5 | class DivideLineWidget extends StatelessWidget{ 6 | final double width; 7 | DivideLineWidget({Key key,this.width}):super(key:key); 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | // height: ScreenUtil().H(width), 12 | alignment: Alignment.center, 13 | color: KColorConstant.divideLineColor, 14 | ); 15 | } 16 | } -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /lib/widgets/CustomIcon.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @Description TODO 3 | * @Author zhibuyu 4 | * @Date 2018/10/26 14:10 5 | * @Version 1.0 6 | */ 7 | import 'package:flutter/material.dart'; 8 | class CustomIcon extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | final IconThemeData iconTheme = IconTheme.of(context); 12 | return Container( 13 | margin: const EdgeInsets.all(4.0), 14 | width: iconTheme.size - 8.0, 15 | height: iconTheme.size - 8.0, 16 | color: iconTheme.color, 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/model/banner.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | class BannerItemModel { 4 | String href; 5 | String picUrl; 6 | BannerItemModel({this.href, this.picUrl}); 7 | BannerItemModel.fromJson(Map json) 8 | : href = json['href'], 9 | picUrl = json['pic_url']; 10 | } 11 | 12 | 13 | class BannerListModel { 14 | List items; 15 | BannerListModel({this.items}); 16 | factory BannerListModel.fromJson(dynamic json) { 17 | List list = (json as List).map((i) { 18 | return BannerItemModel.fromJson(i); 19 | }).toList(); 20 | return BannerListModel(items: list); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /lib/constants/string.dart: -------------------------------------------------------------------------------- 1 | 2 | class KString{ 3 | static const String homeSearchBarHint = '搜一搜'; 4 | static const String categorySearchBarHint = '专区两件九折,三件八折'; 5 | static const String pinweiTitle = '发现'; 6 | static const String pinweigoFindTxt = '去发现'; 7 | static const String cartTitle='购物车'; 8 | static const String allSelectedTxt = '全选'; 9 | static const String goPayTxt = '去结算'; 10 | static const String totalSumTxt = "合计"; 11 | 12 | static const String searchBtTxt ='搜索'; 13 | static const String searchHotTxt = '热门搜索'; 14 | static const List tabs=['首页','性感美女','制服','清新美女','校园','古装','动漫','壁纸','苍老师']; 15 | 16 | } -------------------------------------------------------------------------------- /lib/model/kingkong.dart: -------------------------------------------------------------------------------- 1 | class KingKongItem { 2 | String href; 3 | String picUrl; 4 | String title; 5 | KingKongItem({this.href, this.picUrl,this.title}); 6 | KingKongItem.fromJson(Map json) 7 | : href = json['href'], 8 | title=json['title'], 9 | picUrl = json['pic_url']; 10 | } 11 | 12 | class KingKongList { 13 | List items; 14 | KingKongList({this.items}); 15 | factory KingKongList.fromJson( dynamic json) { 16 | List list = (json as List).map((i) { 17 | return KingKongItem.fromJson(i); 18 | }).toList(); 19 | return KingKongList(items: list); 20 | } 21 | } -------------------------------------------------------------------------------- /lib/views/details/details_top_area.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../components/banner.dart'; 3 | import '../../utils/screen_util.dart'; 4 | import '../../model/goods.dart'; 5 | import '../../model/globle_model.dart'; 6 | 7 | class DetailsTopArea extends StatelessWidget { 8 | GoodInfo goodsInfo = null; 9 | double _width=ScreenUtil.screenWidth; 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | final model = globleModel().of(context); 14 | goodsInfo=model.goodsinfo; 15 | // print(goodsInfo.images); 16 | return SwipperBanner(banners:goodsInfo.images,nheight: _width); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/views/details/details_web.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_html/flutter_html.dart'; 3 | import '../../model/goods.dart'; 4 | 5 | class DetailsWeb extends StatelessWidget { 6 | final GoodInfo goodsinfo; 7 | DetailsWeb(this.goodsinfo); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | var goodsDetails = this.goodsinfo.content; 12 | // print(goodsDetails); 13 | bool isLeft =true; 14 | if (isLeft) { 15 | return Html(data: goodsDetails); 16 | } else { 17 | return Container( 18 | child: Text('暂时没有数据'), 19 | ); 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/widgets/CustomInactiveIcon.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @Description TODO 3 | * @Author zhibuyu 4 | * @Date 2018/10/26 14:11 5 | * @Version 1.0 6 | */ 7 | import 'package:flutter/material.dart'; 8 | 9 | class CustomInactiveIcon extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | final IconThemeData iconTheme = IconTheme.of(context); 13 | return Container( 14 | margin: const EdgeInsets.all(4.0), 15 | width: iconTheme.size - 8.0, 16 | height: iconTheme.size - 8.0, 17 | decoration: BoxDecoration( 18 | border: Border.all(color: iconTheme.color, width: 2.0), 19 | )); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/model/msg_model.dart: -------------------------------------------------------------------------------- 1 | class MyMsgCell { 2 | String id; 3 | String title; 4 | String content; 5 | String createtime; 6 | String status; //状态,订单状态(0=进行中,1=已完成,2=已取消,3=已停止) 7 | 8 | MyMsgCell({ 9 | this.id, 10 | this.title, 11 | this.content, 12 | this.createtime, 13 | this.status, 14 | }); 15 | 16 | factory MyMsgCell.fromJson(Map json) { 17 | var statlist={'0':'未读','1':'已读','2':'已过期'}; 18 | return MyMsgCell( 19 | id: json['id'] ?? '', 20 | title: json['title'] ?? '', 21 | content: json['content'] ?? '', 22 | createtime: json['create_time'] ?? '', 23 | status:statlist[json['status']]??'未知' 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/api/movie.dart: -------------------------------------------------------------------------------- 1 | import 'package:dio/dio.dart'; 2 | 3 | Dio dio = new Dio(); 4 | 5 | class MovieApi { 6 | // 获取电影列表 7 | getMovieList(String mt, int page, int pagesize) async { 8 | int offset = (page - 1) * pagesize; 9 | var result = await dio.get( 10 | 'http://www.liulongbin.top:3005/api/v2/movie/$mt?start=$offset&count=$pagesize'); 11 | return result.data; 12 | } 13 | 14 | // 获取电影详情 15 | getMovieDetail(String id) async { 16 | var result = await dio 17 | .get('http://www.liulongbin.top:3005/api/v2/movie/subject/$id'); 18 | return result.data; 19 | } 20 | 21 | int add(int n) { 22 | return ++n; 23 | } 24 | 25 | int sub(int n) { 26 | return --n; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.30' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.3.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 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 | -------------------------------------------------------------------------------- /lib/video/video_web.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_html/flutter_html.dart'; 3 | class VideoWebPlayer extends StatelessWidget { 4 | final String content; 5 | VideoWebPlayer(this.content); 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | if (content!='') { 10 | return Html(data: content); 11 | } else { 12 | return Container( 13 | child: Text('暂时没有数据'), 14 | ); 15 | }; 16 | } 17 | } 18 | /* 19 | * 22 | */ -------------------------------------------------------------------------------- /lib/video/videoplayer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:video_player/video_player.dart'; 3 | import 'chewie_list_item.dart'; 4 | import 'tx_video_player.dart'; 5 | 6 | class MyVideoPlayer extends StatelessWidget { 7 | final String url; 8 | MyVideoPlayer({this.url="http://200024424.vod.myqcloud.com/200024424_709ae516bdf811e6ad39991f76a4df69.f20.mp4"}); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Scaffold( 13 | appBar: AppBar( 14 | title: Text('视频播放'), 15 | ), 16 | body: ListView( 17 | children: [ 18 | ChewieListItem( 19 | videoPlayerController: VideoPlayerController.network(url, 20 | ), 21 | ), 22 | TxVideoPlayer(url), 23 | 24 | ], 25 | ), 26 | ); 27 | } 28 | } -------------------------------------------------------------------------------- /lib/widgets/topbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../constants/index.dart'; 3 | class TopBarWidget extends StatelessWidget { 4 | final String title; 5 | TopBarWidget(this.title); 6 | @override 7 | Widget build(BuildContext context) { 8 | final double statusBarHeight = MediaQuery.of(context).padding.top; 9 | return Container( 10 | padding: EdgeInsets.only(top: statusBarHeight), 11 | alignment: Alignment.center, 12 | height: statusBarHeight + Klength.topBarHeight, 13 | decoration: BoxDecoration( 14 | border: 15 | Border(bottom: BorderSide(color: Color(0xFFe1e1e1), width: 1))), 16 | child: 17 | Text(title, style: TextStyle(color: Color(0xFF313131), fontSize: 18)), 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lib/components/SliveTabbarDelege.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | class SliverTabBarDelegate extends SliverPersistentHeaderDelegate { 3 | final TabBar widget; 4 | final Color color; 5 | 6 | const SliverTabBarDelegate(this.widget, {this.color}) 7 | : assert(widget != null); 8 | 9 | @override 10 | Widget build( 11 | BuildContext context, double shrinkOffset, bool overlapsContent) { 12 | return new Container( 13 | child: widget, 14 | color: color, 15 | ); 16 | } 17 | 18 | @override 19 | bool shouldRebuild(SliverTabBarDelegate oldDelegate) { 20 | return false; 21 | } 22 | 23 | @override 24 | double get maxExtent => widget.preferredSize.height; 25 | 26 | @override 27 | double get minExtent => widget.preferredSize.height; 28 | } -------------------------------------------------------------------------------- /lib/components/load_more.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class LoadMore extends StatelessWidget { 4 | final bool hasMore; 5 | 6 | LoadMore(this.hasMore); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | if (hasMore) { 11 | return Container( 12 | height: 70.0, 13 | child: Center( 14 | child: Opacity( 15 | opacity: 1.0, 16 | child: CircularProgressIndicator( 17 | strokeWidth: 3.0, 18 | ), 19 | ), 20 | ), 21 | ); 22 | } 23 | return Container( 24 | height: 70.0, 25 | child: Center( 26 | child: Text('亲,我也是有底线的', 27 | style: TextStyle(color: Theme.of(context).accentColor)), 28 | ), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/model/state_model/theme_state_model.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 主题Model 3 | * Create by Songlcy 4 | */ 5 | import 'package:scoped_model/scoped_model.dart'; 6 | import 'package:shared_preferences/shared_preferences.dart'; 7 | 8 | abstract class ThemeStateModel extends Model { 9 | int _themeIndex; 10 | 11 | get themeIndex => _themeIndex; 12 | 13 | void changeTheme(int themeIndex) async { 14 | _themeIndex = themeIndex; 15 | notifyListeners(); 16 | SharedPreferences sp = await SharedPreferences.getInstance(); 17 | sp.setInt("themeIndex", themeIndex); 18 | } 19 | 20 | Future getTheme() async { 21 | SharedPreferences sp = await SharedPreferences.getInstance(); 22 | int themeIndex = sp.getInt("themeIndex"); 23 | if (themeIndex != null) { 24 | return themeIndex; 25 | } 26 | return 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lib/components/tag_component.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 标签组件 3 | * Create by Songlcy 4 | */ 5 | import 'package:flutter/material.dart'; 6 | 7 | class TagComponent extends StatelessWidget { 8 | 9 | final String title; 10 | 11 | const TagComponent({ 12 | this.title = "tag" 13 | }); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return Container( 18 | margin: EdgeInsets.symmetric(horizontal: 6.0), 19 | padding: EdgeInsets.fromLTRB(6.0, 3.0, 6.0, 3.0), 20 | child: Center( 21 | child: Text( 22 | title, 23 | style: TextStyle(color: Colors.white, fontSize: 10.0), 24 | ), 25 | ), 26 | decoration: BoxDecoration( 27 | color: Theme.of(context).primaryColor, 28 | borderRadius: BorderRadius.all(Radius.circular(3.0)) 29 | ), 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/model/sub_category.dart: -------------------------------------------------------------------------------- 1 | class SubCategoryItemModel { 2 | String name; 3 | String icon; 4 | int ucid; 5 | SubCategoryItemModel({this.name, this.icon, this.ucid}); 6 | SubCategoryItemModel.fromJson(Map json) 7 | : name = json['name'], 8 | icon = json['icon'], 9 | ucid = json['ucid']; 10 | } 11 | 12 | class SubCategoryListModel { 13 | List list; 14 | int ucid; 15 | String uname; 16 | String banner; 17 | SubCategoryListModel({this.list,this.banner,this.ucid,this.uname}); 18 | factory SubCategoryListModel.fromJson(dynamic json) { 19 | var items = json['list'] as List; 20 | var itemModals = items.map((item) { 21 | return SubCategoryItemModel.fromJson(item); 22 | }).toList(); 23 | return SubCategoryListModel(list: itemModals,banner:json['banner'],ucid: json['ucid'],uname: json['name']); 24 | } 25 | } -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/main_provide.dart: -------------------------------------------------------------------------------- 1 | 2 | import './data/base.dart'; 3 | class MainProvide extends BaseProvide { 4 | 5 | // 工厂模式 6 | factory MainProvide() =>_getInstance(); 7 | static MainProvide get instance => _getInstance(); 8 | static MainProvide _instance; 9 | static MainProvide _getInstance() { 10 | if (_instance == null) { 11 | _instance = new MainProvide._internal(); 12 | } 13 | return _instance; 14 | } 15 | 16 | MainProvide._internal() { 17 | // 初始化 18 | } 19 | 20 | int _currentIndex = 0; 21 | int get currentIndex => _currentIndex; 22 | set currentIndex(int currentIndex) { 23 | _currentIndex = currentIndex; 24 | notify(); 25 | } 26 | 27 | bool _showMini = false; 28 | bool get showMini => _showMini; 29 | set showMini(bool showMini) { 30 | _showMini = showMini; 31 | notify(); 32 | } 33 | 34 | notify() { 35 | notifyListeners(); 36 | } 37 | } -------------------------------------------------------------------------------- /lib/model/model_cell.dart: -------------------------------------------------------------------------------- 1 | class ModelCell { 2 | String id; 3 | String modAddr; 4 | String modName; 5 | String modtype; 6 | String url; 7 | String fluUrl; 8 | String sortId; // 9 | String stat; 10 | String icon; // 11 | String iconname; 12 | 13 | ModelCell({ 14 | this.id, 15 | this.modAddr, 16 | this.modName, 17 | this.modtype, 18 | this.url, 19 | this.fluUrl, 20 | this.sortId, 21 | this.stat, 22 | this.icon, 23 | this.iconname, 24 | }); 25 | 26 | factory ModelCell.fromJson(Map json) { 27 | return ModelCell( 28 | id: json['_id'], 29 | modAddr: json['modAddr'], 30 | modName: json['modName'], 31 | modtype: json['modtype'], 32 | sortId: json['sortId'], 33 | url: json['url'], 34 | fluUrl: json['iosUrl'], 35 | stat: json['stat'], 36 | icon: json['icon'], 37 | iconname: json['iconname'], 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/video/anims/record_anim.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/animation.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | class RotateRecord extends AnimatedWidget { 5 | RotateRecord({Key key, Animation animation}) 6 | : super(key: key, listenable: animation); 7 | 8 | Widget build(BuildContext context) { 9 | final Animation animation = listenable; 10 | return new Container( 11 | margin: new EdgeInsets.symmetric(vertical: 10.0), 12 | height: 250.0, 13 | width: 250.0, 14 | child: new RotationTransition( 15 | turns: animation, 16 | child: new Container( 17 | decoration: BoxDecoration( 18 | shape: BoxShape.circle, 19 | image: DecorationImage( 20 | image: NetworkImage( 21 | "https://images-na.ssl-images-amazon.com/images/I/51inO4DBH0L._SS500.jpg"), 22 | ), 23 | ), 24 | )), 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/components/sliver_appbar_delegate.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * SliverPersistentHeader 委托类 3 | */ 4 | import 'package:flutter/material.dart'; 5 | 6 | class SliverAppBarDelegate extends SliverPersistentHeaderDelegate { 7 | 8 | final TabBar _tabBar; 9 | SliverAppBarDelegate(this._tabBar); 10 | 11 | /** 12 | * minExtent 与 maxExtent 相同, Header不会有收缩效果,类似普通Header。 13 | */ 14 | @override 15 | double get minExtent => _tabBar.preferredSize.height; 16 | 17 | @override 18 | double get maxExtent => _tabBar.preferredSize.height; 19 | 20 | @override 21 | Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) { 22 | return Container( 23 | color: Colors.white, 24 | child: _tabBar 25 | ); 26 | } 27 | 28 | @override 29 | bool shouldRebuild(SliverAppBarDelegate oldDelegate) { 30 | return false; 31 | // return maxHeight != oldDelegate.maxHeight || 32 | // minHeight != oldDelegate.minHeight || 33 | // child != oldDelegate.child; 34 | } 35 | } -------------------------------------------------------------------------------- /lib/model/cart.dart: -------------------------------------------------------------------------------- 1 | class CartItemModel { 2 | int cartId; 3 | String productName; 4 | int goodsId; 5 | int itemId; 6 | int buyLimit; 7 | int count; 8 | String imageUrl; 9 | bool isSelected; 10 | bool isDeleted; 11 | double price; 12 | CartItemModel( 13 | {this.productName, 14 | this.count, 15 | this.cartId, 16 | this.goodsId, 17 | this.itemId, 18 | this.buyLimit, 19 | this.imageUrl, 20 | this.price, 21 | this.isDeleted, 22 | this.isSelected}); 23 | CartItemModel.fromJson(dynamic json) 24 | : productName = json['goods_name'], 25 | goodsId = json['goods_id'], 26 | itemId = json['item_id'], 27 | cartId = json['id'], 28 | price = num.parse(json['goods_price']), 29 | isDeleted = false, 30 | count = json['goods_num'], 31 | isSelected = (json['selected'] as int) == 1 ? true : false, 32 | imageUrl = json['original_img'] ?? '', 33 | buyLimit = json['store_count']; 34 | } 35 | -------------------------------------------------------------------------------- /lib/components/video_detail_item_component.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 视频详情描述Item 3 | * Create by Songlcy 4 | */ 5 | import 'package:flutter/material.dart'; 6 | import './empty_component.dart'; 7 | 8 | class VideoDetailItemComponent extends StatelessWidget { 9 | 10 | final String icon; 11 | final String content; 12 | final Widget child; 13 | 14 | const VideoDetailItemComponent({ 15 | this.icon, 16 | this.content, 17 | this.child = const EmptyComponent() 18 | }); 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return Padding( 23 | padding: EdgeInsets.symmetric(horizontal: 10.0), 24 | child: Row( 25 | crossAxisAlignment: CrossAxisAlignment.center, 26 | children: [ 27 | Image.asset( 28 | icon, 29 | width: 20.0, 30 | height: 20.0, 31 | fit: BoxFit.cover, 32 | ), 33 | SizedBox(width: 6.0), 34 | Text(content), 35 | child 36 | ], 37 | ) 38 | ); 39 | } 40 | } -------------------------------------------------------------------------------- /lib/components/ToastDialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | // ignore: must_be_immutable 4 | class ToastDialog extends Dialog { 5 | String text; 6 | 7 | ToastDialog({Key key, @required this.text}) : super(key: key); 8 | 9 | @override 10 | Widget build (BuildContext context) { 11 | return new Material( 12 | type: MaterialType.transparency, 13 | child: Align( 14 | alignment: Alignment(0.0, 0.8), 15 | child: Container( 16 | decoration: ShapeDecoration( 17 | color: Color(0xffffffff), 18 | shape: RoundedRectangleBorder( 19 | borderRadius: BorderRadius.all( 20 | Radius.circular(8.0), 21 | ), 22 | ), 23 | ), 24 | child: Padding( 25 | padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), 26 | child: new Text( 27 | text, 28 | style: new TextStyle(fontSize: 12.0), 29 | ), 30 | ), 31 | ), 32 | ), 33 | ); 34 | } 35 | } -------------------------------------------------------------------------------- /lib/data/base2.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'dart:async'; 3 | 4 | import 'package:provider/provider.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:rxdart/rxdart.dart'; 7 | 8 | abstract class PageProvideNode2 extends StatelessWidget { 9 | /// The values made available to the [child]. 10 | BaseProvide2 mProviders = BaseProvide2(); 11 | 12 | Widget buildContent(BuildContext context); 13 | 14 | @override 15 | Widget build(BuildContext context) { 16 | return ChangeNotifierProvider.value( 17 | value: mProviders, 18 | child: buildContent(context), 19 | ); 20 | } 21 | } 22 | 23 | /// BaseProvide 24 | class BaseProvide2 with ChangeNotifier { 25 | 26 | CompositeSubscription compositeSubscription = CompositeSubscription(); 27 | 28 | 29 | /// add [StreamSubscription] to [compositeSubscription] 30 | /// 31 | /// 在 [dispose]的时候能进行取消 32 | addSubscription(StreamSubscription subscription){ 33 | compositeSubscription.add(subscription); 34 | } 35 | 36 | @override 37 | void dispose() { 38 | super.dispose(); 39 | compositeSubscription.dispose(); 40 | } 41 | } -------------------------------------------------------------------------------- /lib/views/player/opacity_tap_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class OpacityTapWidget extends StatefulWidget { 4 | final Widget child; 5 | final Function onTap; 6 | 7 | const OpacityTapWidget({Key key, this.child, this.onTap}) : super(key: key); 8 | 9 | @override 10 | OpacityTapWidgetState createState() { 11 | return new OpacityTapWidgetState(); 12 | } 13 | } 14 | 15 | class OpacityTapWidgetState extends State { 16 | var isDown = false; 17 | @override 18 | Widget build(BuildContext context) { 19 | return GestureDetector( 20 | behavior: HitTestBehavior.opaque, 21 | child: AnimatedContainer( 22 | duration: Duration(milliseconds: 500), 23 | padding: EdgeInsets.fromLTRB(8, 8, 8, 8), 24 | child: new Opacity( 25 | opacity: isDown ? 0.5 : 1, 26 | child: widget.child, 27 | ), 28 | ), 29 | onTap: widget.onTap, 30 | onTapDown: (d) => setState(() => this.isDown = true), 31 | onTapUp: (d) => setState(() => this.isDown = false), 32 | onTapCancel: () => setState(() => this.isDown = false), 33 | ); 34 | } 35 | } -------------------------------------------------------------------------------- /lib/widgets/category/search_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | class SearchBar extends StatelessWidget { 4 | @override 5 | Widget build(BuildContext context) { 6 | return Container( 7 | height: 45, 8 | margin: EdgeInsets.only(top:MediaQuery.of(context).padding.top), 9 | decoration: BoxDecoration(border: Border(bottom: BorderSide(color:KColorConstant.searchBarBgColor,width: 1.0))), 10 | padding: EdgeInsets.symmetric(horizontal: 12), 11 | alignment: Alignment.center, 12 | child: Container( 13 | height: 27, 14 | padding: EdgeInsets.symmetric(horizontal: 6), 15 | alignment: Alignment.center, 16 | color: KColorConstant.searchBarBgColor, 17 | child: Row( 18 | children: [ 19 | Icon(Icons.search,size: 17,), 20 | Container( 21 | margin: EdgeInsets.only(left: 5) , 22 | child: Text(KString.categorySearchBarHint,style: TextStyle(color: KColorConstant.searchBarTxtColor),), 23 | ) 24 | ], 25 | ), 26 | ), 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_english/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | // await tester.pumpWidget(Kukabao()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /lib/model/paylog_model.dart: -------------------------------------------------------------------------------- 1 | 2 | class PayLogCell { 3 | String id; 4 | String orderNo; 5 | String orderName; 6 | String orderMoney; 7 | String orderBond;//入账金额 8 | String orderCharge;//手续费 9 | String orderCard; 10 | String orderTime; 11 | String status; //状态,0=处理中,1=出账成功 12 | 13 | PayLogCell( 14 | {this.id, 15 | this.orderNo, 16 | this.orderMoney, 17 | 18 | this.orderName, 19 | this.orderBond, 20 | this.orderCharge, 21 | 22 | this.orderCard, 23 | this.orderTime, 24 | this.status,}); 25 | 26 | factory PayLogCell.fromJson(Map json) { 27 | var statlist={'0':'不成功','1':'入账','2':'消费','3':'入账','4':'消费'}; 28 | return PayLogCell( 29 | id: json['id']??'', 30 | orderNo: json['orderNo']??'', 31 | orderMoney: json['orderMoney']??'', 32 | 33 | orderName: json['orderName']??'', 34 | orderBond: json['orderBond']??'', 35 | orderCharge: json['orderCharge']??'', 36 | orderCard: json['orderNo']??'', 37 | orderTime: json['create_time']??'', 38 | // status: json['status']=='1' ? "出账成功":"已处理", 39 | status:statlist[json['status']]??'处理' 40 | ); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /lib/components/fiexdAppbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class FiexdAppbar extends StatefulWidget implements PreferredSizeWidget { 4 | 5 | final double contentHeight; //从外部指定高度 6 | final Widget contentChild; //从外部指定内容 7 | final Color statusBarColor; //设置statusbar的颜色 8 | 9 | FiexdAppbar({this.contentChild, this.contentHeight, this.statusBarColor}): super(); 10 | 11 | @override 12 | State createState() { 13 | return new _XFileAppbarState(); 14 | } 15 | 16 | @override 17 | Size get preferredSize => new Size.fromHeight(contentHeight); 18 | 19 | } 20 | /* 21 | * 这是一个可以指定SafeArea区域背景色的AppBar 22 | * PreferredSizeWidget提供指定高度的方法 23 | * 如果没有约束其高度,则会使用PreferredSizeWidget指定的高度 24 | */ 25 | 26 | /* 27 | * 这里没有直接用SafeArea,而是用Container包装了一层 28 | * 因为直接用SafeArea,会把顶部的statusBar区域留出空白 29 | * 外层Container会填充SafeArea,指定外层Container背景色也会覆盖原来SafeArea的颜色 30 | */ 31 | class _XFileAppbarState extends State { 32 | @override 33 | Widget build(BuildContext context) { 34 | return new Container( 35 | color: widget.statusBarColor, 36 | child: new SafeArea( 37 | top: true, 38 | child: widget.contentChild, 39 | ), 40 | ); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /lib/utils/fiexdAppbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /** 4 | * 这是一个可以指定SafeArea区域背景色的AppBar 5 | * PreferredSizeWidget提供指定高度的方法 6 | * 如果没有约束其高度,则会使用PreferredSizeWidget指定的高度 7 | */ 8 | class FiexdAppbar extends StatefulWidget implements PreferredSizeWidget { 9 | 10 | final double contentHeight; //从外部指定高度 11 | final Widget contentChild; //从外部指定内容 12 | final Color statusBarColor; //设置statusbar的颜色 13 | 14 | FiexdAppbar({this.contentChild, this.contentHeight, this.statusBarColor}): super(); 15 | 16 | @override 17 | State createState() { 18 | return new _XFileAppbarState(); 19 | } 20 | 21 | @override 22 | Size get preferredSize => new Size.fromHeight(contentHeight); 23 | 24 | } 25 | 26 | 27 | /** 28 | * 这里没有直接用SafeArea,而是用Container包装了一层 29 | * 因为直接用SafeArea,会把顶部的statusBar区域留出空白 30 | * 外层Container会填充SafeArea,指定外层Container背景色也会覆盖原来SafeArea的颜色 31 | */ 32 | class _XFileAppbarState extends State { 33 | @override 34 | Widget build(BuildContext context) { 35 | return new Container( 36 | color: widget.statusBarColor, 37 | child: new SafeArea( 38 | top: true, 39 | child: widget.contentChild, 40 | ), 41 | ); 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /lib/views/search/listtopbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | 4 | class SearchListTopBarTitleWidget extends StatelessWidget { 5 | final String keyworld; 6 | SearchListTopBarTitleWidget({Key key, this.keyworld}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | height: Klength.searchTxtFieldHeight, 12 | padding: EdgeInsets.only(left: 10), 13 | margin: EdgeInsets.only(right: 30), 14 | alignment: Alignment.centerLeft, 15 | decoration: BoxDecoration( 16 | color: KColorConstant.divideLineColor, 17 | borderRadius: BorderRadius.all(Radius.circular(5))), 18 | child: GestureDetector( 19 | onTap: () => Navigator.pop(context), 20 | child: Row( 21 | children: [ 22 | Icon( 23 | Icons.search, 24 | color: KColorConstant.floorTitleColor, 25 | size: 20, 26 | ), 27 | Text( 28 | keyworld, 29 | style: KfontConstant.defaultStyle, 30 | ), 31 | ], 32 | ))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/widgets/search/listtopbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | 4 | class SearchListTopBarTitleWidget extends StatelessWidget { 5 | final String keyworld; 6 | SearchListTopBarTitleWidget({Key key, this.keyworld}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | height: Klength.searchTxtFieldHeight, 12 | padding: EdgeInsets.only(left: 10), 13 | margin: EdgeInsets.only(right: 30), 14 | alignment: Alignment.centerLeft, 15 | decoration: BoxDecoration( 16 | color: KColorConstant.divideLineColor, 17 | borderRadius: BorderRadius.all(Radius.circular(5))), 18 | child: GestureDetector( 19 | onTap: () => Navigator.pop(context), 20 | child: Row( 21 | children: [ 22 | Icon( 23 | Icons.search, 24 | color: KColorConstant.floorTitleColor, 25 | size: 20, 26 | ), 27 | Text( 28 | keyworld, 29 | style: KfontConstant.defaultStyle, 30 | ), 31 | ], 32 | ))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/model/crowdfund.dart: -------------------------------------------------------------------------------- 1 | class CrowdFundItemModel { 2 | String name; 3 | String summary; 4 | String picUrl; 5 | int marketPrice; 6 | int progress; 7 | int saledCount; 8 | String jumpUrl; 9 | CrowdFundItemModel( 10 | {this.name, 11 | this.marketPrice, 12 | this.progress, 13 | this.saledCount, 14 | this.jumpUrl, 15 | this.picUrl, 16 | this.summary}); 17 | factory CrowdFundItemModel.fromJson(dynamic json) { 18 | return CrowdFundItemModel( 19 | name: json['name'], 20 | summary: json['summary'], 21 | picUrl: json['pic_url'], 22 | marketPrice: json['market_price'], 23 | progress: json['progress'], 24 | saledCount: json['saled_count'], 25 | jumpUrl: json['jump_url']); 26 | } 27 | } 28 | 29 | class CrowdFundingListModel { 30 | List items; 31 | String title; 32 | 33 | CrowdFundingListModel({this.items, this.title}); 34 | factory CrowdFundingListModel.fromJson(Map json) { 35 | var itemsList = json['items'] as List; 36 | var items = itemsList.map((i) { 37 | return CrowdFundItemModel.fromJson(i); 38 | }).toList(); 39 | 40 | return CrowdFundingListModel(items: items, title: json['title']); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/utils/utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:quiver/strings.dart'; 3 | import 'dart:math' as math; 4 | 5 | Color string2Color(String colorString) { 6 | int value = 0x00000000; 7 | 8 | if (isNotEmpty(colorString)) { 9 | if (colorString[0] == '#') { 10 | colorString = colorString.substring(1); 11 | } 12 | value = int.tryParse(colorString, radix: 16); 13 | if (value != null) { 14 | if (value < 0xFF000000) { 15 | value += 0xFF000000; 16 | } 17 | } 18 | } 19 | return Color(value); 20 | } 21 | 22 | 23 | Map url2query(String url){ 24 | var search = new RegExp('([^&=]+)=?([^&]*)'); 25 | var result = new Map(); 26 | 27 | // Get rid off the beginning ? in query strings. 28 | if (url.startsWith('?')) url = url.substring(1); 29 | 30 | // A custom decoder. 31 | decode(String s) => Uri.decodeComponent(s.replaceAll('+', ' ')); 32 | 33 | // Go through all the matches and build the result map. 34 | for (Match match in search.allMatches(url)) { 35 | result[decode(match.group(1))] = decode(match.group(2)); 36 | } 37 | 38 | return result; 39 | } 40 | 41 | Color randomColor(){ 42 | return Color((math.Random().nextDouble() * 0xFFFFFF).toInt() << 0).withOpacity(1.0); 43 | } -------------------------------------------------------------------------------- /lib/widgets/search/recomend.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | 4 | class RecomendListWidget extends StatelessWidget { 5 | final List items; 6 | final ValueChanged onItemTap; 7 | RecomendListWidget(this.items, {this.onItemTap}); 8 | @override 9 | Widget build(BuildContext context) { 10 | return ListView.separated( 11 | padding: EdgeInsets.symmetric(horizontal: 10), 12 | itemCount: items.length, 13 | itemBuilder: (BuildContext context, int i) { 14 | return InkWell( 15 | onTap: () => onItemTap(items[i]), 16 | child: Container( 17 | height: 42, 18 | width: double.infinity, 19 | // color: Colors.red, 20 | alignment: Alignment.centerLeft, 21 | // constraints: BoxConstraints(minWidth: double.infinity), 22 | child: Text( 23 | items[i], 24 | style: TextStyle(fontSize: 15), 25 | ), 26 | ), 27 | ); 28 | }, 29 | separatorBuilder: (BuildContext context, int i) { 30 | return Container( 31 | height: 1, 32 | color: KColorConstant.searchRecomendDividerColor, 33 | ); 34 | }, 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lib/globleConfig.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import './utils/screen_util.dart'; 3 | export './constants/index.dart'; 4 | 5 | class GlobalConfig { 6 | static final String appName = '护卡宝'; 7 | static final String agentid='0'; 8 | static final bool dark = true; 9 | // static ThemeData themeData = new ThemeData.dark(); 10 | static final Color mainColor = Colors.red; 11 | static Color searchBackgroundColor = Colors.white10; 12 | static Color cardBackgroundColor = new Color(0xFF222222); 13 | static Color fontColor = Colors.white30; 14 | 15 | static final String server='http://bixue.goodgood.be/'; 16 | static final String base='http://bixue.goodgood.be/Appi/'; 17 | static final String wxAppId='wxbe64b7b2cd18c128';//'wxb85ad5c66ae2efb2'; 18 | 19 | static final double cardWidth =ScreenUtil().L(650);//卡片统一宽度 20 | static final double cardCircularWidth = 8;//卡片圆角高度 21 | 22 | static final ShapeBorder cardBorderRadius = const RoundedRectangleBorder( 23 | side: BorderSide(color: Colors.white12), 24 | borderRadius: BorderRadius.only( 25 | topLeft: Radius.circular(8.0), 26 | topRight: Radius.circular(8.0), 27 | bottomLeft: Radius.circular(8.0), 28 | bottomRight: Radius.circular(8.0), 29 | ), 30 | ); 31 | 32 | static final bool ios_show=true; 33 | } -------------------------------------------------------------------------------- /lib/components/keyboard/custom_keyboard_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | 4 | /// 自定义 键盘 按钮 5 | 6 | class CustomKbBtn extends StatefulWidget { 7 | String text; 8 | 9 | CustomKbBtn({Key key, this.text, this.callback}) : super(key: key); 10 | final callback; 11 | 12 | @override 13 | State createState() { 14 | return ButtonState(); 15 | } 16 | } 17 | 18 | class ButtonState extends State { 19 | ///回调函数执行体 20 | var backMethod; 21 | 22 | void back() { 23 | widget.callback('$backMethod'); 24 | } 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | 29 | MediaQueryData mediaQuery = MediaQuery.of(context); 30 | var _screenWidth = mediaQuery.size.width; 31 | 32 | return new Container( 33 | height:50.0, 34 | width: _screenWidth / 3, 35 | child: new OutlineButton( 36 | // 直角 37 | shape: new RoundedRectangleBorder( 38 | borderRadius: new BorderRadius.circular(0.0)), 39 | // 边框颜色 40 | borderSide: new BorderSide(color: Color(0x10333333)), 41 | child: new Text( 42 | widget.text, 43 | style: new TextStyle(color: Color(0xff333333), fontSize: 20.0), 44 | ), 45 | onPressed: back, 46 | )); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/data/base.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'dart:async'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:provide/provide.dart'; 5 | import 'package:rxdart/rxdart.dart'; 6 | 7 | /// BaseProvide 8 | class BaseProvide with ChangeNotifier { 9 | 10 | CompositeSubscription compositeSubscription = CompositeSubscription(); 11 | 12 | 13 | /// add [StreamSubscription] to [compositeSubscription] 14 | /// 15 | /// 在 [dispose]的时候能进行取消 16 | addSubscription(StreamSubscription subscription){ 17 | compositeSubscription.add(subscription); 18 | } 19 | 20 | @override 21 | void dispose() { 22 | super.dispose(); 23 | compositeSubscription.dispose(); 24 | } 25 | } 26 | 27 | 28 | /// page的基类 [PageProvideNode] 29 | /// 30 | /// 隐藏了 [ProviderNode] 的调用 31 | abstract class PageProvideNode extends StatelessWidget { 32 | /// The values made available to the [child]. 33 | final Providers mProviders = Providers(); 34 | 35 | Widget buildContent(BuildContext context); 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return ProviderNode( 40 | providers: mProviders, 41 | child: buildContent(context), 42 | ); 43 | } 44 | } 45 | 46 | 47 | abstract class BaseState extends State { 48 | 49 | @override 50 | void initState() { 51 | super.initState(); 52 | } 53 | 54 | @override 55 | void dispose() { 56 | super.dispose(); 57 | } 58 | } -------------------------------------------------------------------------------- /lib/components/dropdown.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_picker/flutter_picker.dart'; 3 | import '../utils/HttpUtils.dart'; 4 | 5 | class citySelector { 6 | int pid; 7 | citySelector({this.pid = 0}); 8 | 9 | List _bankPickerData = new List(); 10 | Map _bankCodeMap = {}; // 11 | String _bankName; 12 | String _bankId; 13 | 14 | Future showBankPicker(BuildContext context,Function callback) async { 15 | await HttpUtils.dioappi( 16 | 'Api/getregion/pid/${this.pid}', 17 | {}, 18 | ).then((response) { 19 | response['data'].forEach((ele) { 20 | if (ele.isNotEmpty) { 21 | _bankPickerData.add(ele['name'].toString()); 22 | _bankCodeMap[ele['name']] = ele['id'].toString(); 23 | } 24 | }); 25 | }).then((_){ 26 | Picker( 27 | adapter: PickerDataAdapter(pickerdata: _bankPickerData), 28 | hideHeader: true, 29 | title: new Text("城市列表"), 30 | cancelText: '取消', 31 | confirmText: '确定', 32 | onConfirm: (Picker picker, List value) { 33 | _bankName = picker.getSelectedValues()[0].toString(); 34 | _bankId = _bankCodeMap[_bankName]; 35 | print("bankId:$_bankId"); 36 | callback(_bankId,_bankName); 37 | }).showDialog(context); 38 | }); 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /lib/constants/font.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../utils/screen_util.dart'; 3 | import 'color.dart'; 4 | class KfontConstant { 5 | static TextStyle bigfontSize = TextStyle( 6 | fontSize: 14, 7 | color: KColorConstant.categoryDefaultColor, 8 | decoration: TextDecoration.none, 9 | ); 10 | 11 | static TextStyle defaultStyle = TextStyle( 12 | fontSize: 14, 13 | color: KColorConstant.categoryDefaultColor, 14 | decoration: TextDecoration.none, 15 | ); 16 | 17 | static TextStyle defaultSubStyle = TextStyle( 18 | fontSize:12, 19 | color: Colors.black45, 20 | decoration: TextDecoration.none, 21 | ); 22 | 23 | static TextStyle defaultPriceStyle = TextStyle( 24 | fontSize:10, 25 | color: KColorConstant.priceColor, 26 | decoration: TextDecoration.none, 27 | ); 28 | 29 | 30 | static TextStyle fLoorTitleStyle = TextStyle( 31 | fontSize:14, 32 | color: KColorConstant.floorTitleColor, 33 | ); 34 | static TextStyle pinweiCorverSubtitleStyle = TextStyle( 35 | fontSize: 10, 36 | color: KColorConstant.pinweicorverSubtitleColor, 37 | ); 38 | 39 | static TextStyle cartBottomTotalPriceStyle = TextStyle(fontSize: 12,color: KColorConstant.priceColor); 40 | 41 | 42 | static TextStyle searchResultItemCommentCountStyle = TextStyle( 43 | fontSize: 12, color: Color(0xFF999999)); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /lib/components/loginButton.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../routers/application.dart'; 3 | import 'package:fluro/fluro.dart'; 4 | 5 | class LoginButton extends StatelessWidget { 6 | final String userName; 7 | final String userPic; 8 | 9 | LoginButton({Key key, this.userPic, this.userName}) : super(key: key); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | if (userName != '') { 14 | return FlatButton( 15 | onPressed: () { 16 | print('click loggout'); 17 | Application.router.navigateTo(context, "/login", 18 | transition: TransitionType.fadeIn); 19 | /* Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute( 20 | builder: (BuildContext context) => LoginScreen()), (//跳转到主页 21 | Route route) => route == null); 22 | */ 23 | }, 24 | child: Text( 25 | '登陆 . 注册', 26 | style: TextStyle( 27 | color: Theme.of(context).primaryColor, 28 | fontSize: 16.0, 29 | fontWeight: FontWeight.w200, 30 | ), 31 | )); 32 | } 33 | return Container( 34 | child: Row( 35 | children: [ 36 | CircleAvatar( 37 | backgroundImage: NetworkImage(userPic), 38 | child: Text(userName), 39 | ), 40 | ], 41 | ), 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/routers/routes.dart: -------------------------------------------------------------------------------- 1 | import './router_handler.dart'; 2 | import 'package:fluro/fluro.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class Routes { 6 | static String root = '/'; 7 | static String swipPage = '/swip'; 8 | static String flashPage = "/flash"; 9 | static String webViewPage = '/web'; 10 | static String homePage = '/home';// 11 | static String loginPage = '/login'; 12 | static String userCenterPage = '/user'; 13 | 14 | static String sharePage = '/share'; 15 | static String payLogPage = '/paylog'; 16 | static String addCardPage = '/addcard'; 17 | static String omyMsgistPage = '/myMsg'; 18 | 19 | 20 | static void configureRoutes(Router router) { 21 | router.notFoundHandler = new Handler( 22 | handlerFunc: (BuildContext context, Map> params) { 23 | print("ROUTE WAS NOT FOUND !!!"); 24 | }); 25 | router.define(root,handler: homePageHandler); 26 | router.define(flashPage, handler: flashPageHandler); 27 | router.define(webViewPage, handler: webPageHandler); 28 | router.define(homePage, handler: homePageHandler); 29 | router.define(loginPage,handler: loginPageHandler); 30 | 31 | router.define(userCenterPage, handler:userPageHandler); 32 | 33 | router.define(sharePage, handler:sharePageHandler); 34 | router.define(payLogPage, handler: payLogPageHandler); 35 | router.define(omyMsgistPage, handler: myMsgListPageHandler); 36 | 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/views/search/searchserver.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'dart:convert'; 3 | import 'dart:async'; 4 | import '../../utils/HttpUtils.dart'; 5 | /** 6 | * 获取热刺列表 7 | */ 8 | Future getHotSugs(context) async { 9 | var response =await HttpUtils.dioappi( 10 | "Shop/getHotKeys", {}, context: context); 11 | return jsonDecode(response)['result'] as List; 12 | 13 | /* return []; 14 | var url = 'https://suggest.taobao.com/sug?area=sug_hot&wireless=2'; 15 | var res = await http.get(url); 16 | if (res.statusCode == 200) { 17 | List querys = jsonDecode(res.body)['querys'] as List; 18 | return querys; 19 | }else{ 20 | return []; 21 | }*/ 22 | } 23 | /** 24 | * 添加到搜索热刺 25 | */ 26 | Future getSuggest(String q) async { 27 | return []; 28 | } 29 | 30 | 31 | /* 32 | 33 | getSearchResult(String keyworld,[int page=0]) async{ 34 | String url = 'https://so.m.jd.com/ware/search._m2wq_list?keyword=$keyworld&datatype=1&callback=C&page=$page&pagesize=10&ext_attr=no&brand_col=no&price_col=no&color_col=no&size_col=no&ext_attr_sort=no&merge_sku=yes&multi_suppliers=yes&area_ids=1,72,2818&qp_disable=no&fdesc=%E5%8C%97%E4%BA%AC'; 35 | var res = await http.get(url); 36 | String body = res.body; 37 | String jsonString = body.substring(2,body.length-2); 38 | 39 | // debugPrint(jsonString.replaceAll('\\x2F', '/')); 40 | var json = jsonDecode(jsonString.replaceAll( RegExp(r'\\x..') ,'/')); 41 | return json['data']['searchm']['Paragraph'] as List; 42 | }*/ 43 | -------------------------------------------------------------------------------- /lib/components/icon_with_text.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class IconWidthText extends StatelessWidget { 4 | final Image icon; 5 | final String text; 6 | final Color color; 7 | 8 | IconWidthText({Key key, this.color, this.icon, this.text}) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return new Container( 13 | child: GestureDetector( 14 | child: new Column( 15 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 16 | mainAxisSize: MainAxisSize.max, 17 | crossAxisAlignment: CrossAxisAlignment.center, 18 | verticalDirection: VerticalDirection.down, 19 | children: [ 20 | Expanded( 21 | child: new Container( 22 | constraints: new BoxConstraints.expand(), 23 | decoration: new BoxDecoration( 24 | image: new DecorationImage( 25 | // image: icon, 26 | // image: new NetworkImage('http://h.hiphotos.baidu.com/zhi6e06f06c.jpg'), 27 | image: AssetImage('images/sysicon/icon_jilu.png'), 28 | ), 29 | ), 30 | ), 31 | ), 32 | Expanded(child: Text(text)) 33 | ], 34 | ), 35 | /* onTap: () { 36 | print(11); 37 | Application.router.navigateTo(context, url); 38 | },*/ 39 | ), 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/constants/color.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | class KColorConstant { 4 | static const Color themeColor = Color.fromRGBO(240, 100, 90, 1.0); 5 | static const Color floorTitleColor = Color.fromRGBO(51, 51, 51, 1); 6 | static const Color searchBarBgColor = Color.fromRGBO(240, 240, 240, 1.0); 7 | static const Color searchBarTxtColor = Color(0xFFCDCDCD); 8 | static const Color divideLineColor = Color.fromRGBO(245, 245, 245, 1.0); 9 | static const Color categoryDefaultColor = Color(0xFF666666); 10 | static const Color priceColor = Color.fromRGBO(182, 9, 9, 1.0); 11 | static const Color pinweicorverSubtitleColor = Color.fromRGBO(153, 153, 153, 1.0); 12 | static const Color pinweicorverBtbgColor = themeColor; 13 | static const Color pinweicorverBtTxtColor = Color(0xFFFFFFFF); 14 | static const Color tabtxtColor = Color.fromRGBO(88, 88, 88, 1.0); 15 | static const Color cartDisableColor = Color.fromRGBO(221, 221,221,1.0); 16 | static const Color cartItemChangenumBtColor = Color.fromRGBO(153, 153, 153, 1.0); 17 | static const Color cartItemCountTxtColor = Color.fromRGBO(102, 102, 102, 0.8); 18 | static const Color cartBottomBgColor = Color(0xFFFFFFFF); 19 | static const Color goPayBtBgColor = themeColor; 20 | static const Color goPayBtTxtColor = Color(0xFFFFFFFF); 21 | static const Color searchAppBarBgColor = Color(0xFFFFFFFF); 22 | 23 | static const Color bottomBarbgColor = Color.fromRGBO(250, 250, 250, 1.0); 24 | 25 | 26 | static const Color searchRecomendDividerColor = Color(0xFFdedede); 27 | } -------------------------------------------------------------------------------- /lib/model/oder_model.dart: -------------------------------------------------------------------------------- 1 | class OrderCell { 2 | String id; 3 | String orderNo; 4 | String orderName; 5 | String orderMoney; 6 | String orderBond; //保证金 7 | String orderCharge; //手续费 8 | 9 | String orderBondPer; 10 | String content; 11 | String createtime; 12 | String planText; 13 | 14 | String orderCard; 15 | String orderTime; 16 | String status; //状态,订单状态(0=进行中,1=已完成,2=已取消,3=已停止) 17 | 18 | OrderCell({ 19 | this.id, 20 | this.orderNo, 21 | this.orderMoney, 22 | this.orderName, 23 | this.orderBond, 24 | this.orderCharge, 25 | this.orderBondPer, 26 | this.content, 27 | this.createtime, 28 | this.planText, 29 | this.orderCard, 30 | this.orderTime, 31 | this.status, 32 | }); 33 | 34 | factory OrderCell.fromJson(Map json) { 35 | var statlist={'0':'进行中','1':'已完成','2':'已取消','3':'已停止'}; 36 | return OrderCell( 37 | id: json['id'] ?? '', 38 | orderNo: json['orderNo'] ?? '', 39 | orderMoney: json['orderMoney'] ?? '', 40 | orderName: json['orderName'] ?? '', 41 | orderBond: json['orderBond'] ?? '', 42 | orderCharge: json['orderCharge'] ?? '', 43 | orderCard: json['orderNo'] ?? '', 44 | orderBondPer: json['orderBondPer'] ?? '', 45 | content: json['content'] ?? '', 46 | planText: json['planText'] ?? '', 47 | createtime: json['create_time'] ?? '', 48 | orderTime: json['planPayTime'] ?? '', 49 | 50 | status:statlist[json['status']]??'异常' 51 | ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/model/product.dart: -------------------------------------------------------------------------------- 1 | class ProductItemModel { 2 | String goods_id; 3 | String shop_price; 4 | String market_price; 5 | String bgColor; 6 | String picurl; 7 | String title; 8 | String titleColor; 9 | String subtitle; 10 | String subtitleColor; 11 | ProductItemModel( 12 | {this.goods_id, 13 | this.bgColor, 14 | this.market_price, 15 | this.shop_price, 16 | this.picurl, 17 | this.title, 18 | this.titleColor, 19 | this.subtitle, 20 | this.subtitleColor}); 21 | factory ProductItemModel.fromJson(Map json) { 22 | return ProductItemModel( 23 | bgColor: json['bg_color'], 24 | goods_id: json['goods_id'].toString() ?? "0", 25 | market_price: json['market_price'] ?? "0", 26 | shop_price: json['shop_price'] ?? "0", 27 | picurl: json['pic_url'], 28 | subtitle: json['subtitle'].toString()??"", 29 | titleColor: json['title_color'], 30 | subtitleColor: json['subtitle_color'], 31 | title: json['title']); 32 | } 33 | } 34 | 35 | class ProductListModel { 36 | List items; 37 | String title; 38 | 39 | ProductListModel({this.items, this.title}); 40 | factory ProductListModel.fromJson(Map json) { 41 | var itemsList = json['items'] as List; 42 | var menueItems = itemsList.map((i) { 43 | return ProductItemModel.fromJson(i); 44 | }).toList(); 45 | 46 | return ProductListModel(items: menueItems, title: json['title']); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/components/LoadingDialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | // ignore: must_be_immutable 4 | class LoadingDialog extends Dialog { 5 | String text; 6 | 7 | LoadingDialog({Key key, @required this.text}) : super(key: key); 8 | 9 | @override 10 | Widget build(BuildContext context) { 11 | return new Material( //创建透明层 12 | type: MaterialType.transparency, //透明类型 13 | child: new Center( //保证控件居中效果 14 | child: new SizedBox( 15 | width: 120.0, 16 | height: 120.0, 17 | child: new Container( 18 | decoration: ShapeDecoration( 19 | color: Color(0xffffffff), 20 | shape: RoundedRectangleBorder( 21 | borderRadius: BorderRadius.all( 22 | Radius.circular(8.0), 23 | ), 24 | ), 25 | ), 26 | child: new Column( 27 | mainAxisAlignment: MainAxisAlignment.center, 28 | crossAxisAlignment: CrossAxisAlignment.center, 29 | children: [ 30 | new CircularProgressIndicator(), 31 | new Padding( 32 | padding: const EdgeInsets.only( 33 | top: 20.0, 34 | ), 35 | child: new Text( 36 | text, 37 | style: new TextStyle(fontSize: 12.0), 38 | ), 39 | ), 40 | ], 41 | ), 42 | ), 43 | ), 44 | ), 45 | ); 46 | } 47 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /lib/widgets/search/hotSug.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | import '../../utils/utils.dart'; 4 | 5 | class HotSugWidget extends StatelessWidget { 6 | final List hotWords; 7 | final ValueChanged goSearchList; 8 | HotSugWidget( {Key key,this.hotWords,this.goSearchList}):super(key:key); 9 | @override 10 | Widget build(BuildContext context) { 11 | return Column( 12 | children: [ 13 | Container( 14 | height: 40, 15 | padding: EdgeInsets.only(left: 20), 16 | alignment: Alignment.centerLeft, 17 | color: KColorConstant.divideLineColor, 18 | child: Text(KString.searchHotTxt), 19 | margin: EdgeInsets.only(bottom: 10), 20 | ), 21 | Wrap( 22 | spacing: 10, 23 | runSpacing: 10, 24 | children: hotWords 25 | .map((i) => GestureDetector( 26 | onTap: ()=>goSearchList(i), 27 | child: Container( 28 | decoration: BoxDecoration( 29 | color: randomColor(), 30 | borderRadius: BorderRadius.circular(5)), 31 | padding: 32 | EdgeInsets.symmetric(vertical: 5, horizontal: 7), 33 | child: Text( 34 | i, 35 | style: TextStyle(color: Color(0xFFFFFFFF)), 36 | )), 37 | )) 38 | .toList(), 39 | ) 40 | ], 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/model/search.dart: -------------------------------------------------------------------------------- 1 | class SearchResultItemModal { 2 | String shopName; 3 | String wareName; 4 | String price; 5 | String coupon; 6 | String imageUrl; 7 | String commentcount; 8 | String good; //好评率 9 | String shopId; 10 | String disCount; 11 | SearchResultItemModal( 12 | {this.shopId, 13 | this.shopName, 14 | this.commentcount, 15 | this.coupon, 16 | this.price, 17 | this.good, 18 | this.disCount, 19 | this.imageUrl, 20 | this.wareName}); 21 | factory SearchResultItemModal.fromJson(dynamic json) { 22 | String picurl = 'http://img10.360buyimg.com/mobilecms/s270x270_' + 23 | json['Content']['imageurl']; 24 | String coupon; 25 | if(json['coupon']!=null){ 26 | if(json['coupon']['m']!='0'){ 27 | coupon='满${json['coupon']['m']}减${json['coupon']['j']}'; 28 | } 29 | } 30 | String disCount; 31 | if(json['pfdt']!=null){ 32 | if(json['pfdt']['m']!=''){ 33 | disCount='${json['pfdt']['m']}件${json['pfdt']['j']}折'; 34 | } 35 | } 36 | 37 | return SearchResultItemModal( 38 | shopId: json['shop_id'], 39 | shopName: json['shop_name'], 40 | imageUrl: picurl, 41 | good: json['good'], 42 | commentcount: json['commentcount'], 43 | price: json['dredisprice'], 44 | coupon: coupon, 45 | disCount: disCount, 46 | wareName: json['Content']['warename']); 47 | } 48 | } 49 | 50 | class SearchResultListModal { 51 | List data; 52 | SearchResultListModal(this.data); 53 | factory SearchResultListModal.fromJson(List json){ 54 | return SearchResultListModal( 55 | json.map((i)=>SearchResultItemModal.fromJson(i)).toList() 56 | ); 57 | } 58 | } -------------------------------------------------------------------------------- /lib/model/song.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | @JsonSerializable() 4 | class Song { 5 | int id; 6 | String url; 7 | Map video;//当前 8 | Map info;//简介 9 | List> vdlist = List();//列表集合 10 | List> txtlist;//字幕文件 11 | int preid; 12 | int nextid; 13 | 14 | // String get id => _id; 15 | 16 | /// 自定义属性 17 | bool isExpaned = false; 18 | 19 | Song( 20 | { 21 | this.id, 22 | this.url, 23 | this.video, 24 | this.info, 25 | this.txtlist, 26 | this.preid, 27 | this.nextid, 28 | this.vdlist 29 | }); 30 | /* 31 | factory Song.fromJson(Map json) => 32 | Song() 33 | ..imgUrl = json['imgUrl'] as String 34 | ..lrcUrl = json['lrcUrl'] as String 35 | ..size = json['size'] as String 36 | ..singer = json['singer'] as String 37 | ..songUrl = json['songUrl'] as String 38 | ..title = json['title'] as String 39 | ..duration = json['duration'] as String 40 | ..imgUrl_s = json['imgUrl_s'] as String 41 | ..desc = json['desc'] as String 42 | ..isFav = json['isFav'] as bool 43 | .._id = json['_id']; 44 | 45 | static Map toJson(Song instance) => 46 | { 47 | 'imgUrl': instance.imgUrl, 48 | 'lrcUrl': instance.lrcUrl, 49 | 'size': instance.size, 50 | 'singer': instance.singer, 51 | 'songUrl': instance.songUrl, 52 | 'title': instance.title, 53 | 'duration': instance.duration, 54 | 'imgUrl_s': instance.imgUrl_s, 55 | 'desc': instance.desc, 56 | 'isFav': instance.isFav, 57 | '_id': instance._id 58 | };*/ 59 | } 60 | -------------------------------------------------------------------------------- /lib/views/cart/cart.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | import 'cart_list.dart'; 4 | import 'cartbottom.dart'; 5 | import '../../model/globle_model.dart'; 6 | 7 | class Cart extends StatefulWidget { 8 | @override 9 | State createState() => CartState(); 10 | } 11 | 12 | class CartState extends State { 13 | @override 14 | void initState() { 15 | super.initState(); 16 | } 17 | @override 18 | void dispose() { 19 | //重新整理更新购物车 20 | final model = globleModel().of(context); 21 | model.freshCartItem(context); 22 | super.dispose(); 23 | } 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: new AppBar( 29 | title: new Text('购物车'), 30 | centerTitle: true, 31 | leading: SizedBox(width: 5,), 32 | ), 33 | // backgroundColor: Color(0xFF5FB419), 34 | body: Column( 35 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 36 | crossAxisAlignment: CrossAxisAlignment.center, 37 | children: [ 38 | CartListWidget(), 39 | CartBottomWidget() 40 | ], 41 | )); 42 | } 43 | 44 | 45 | Widget buildtopbar(String title) { 46 | final double statusBarHeight = MediaQuery.of(context).padding.top; 47 | return Container( 48 | padding: EdgeInsets.only(top: statusBarHeight), 49 | alignment: Alignment.center, 50 | height: statusBarHeight + Klength.topBarHeight, 51 | decoration: BoxDecoration( 52 | border: 53 | Border(bottom: BorderSide(color: Color(0xFFe1e1e1), width: 1))), 54 | child: 55 | Text(title, style: TextStyle(color: Color(0xFF313131), fontSize: 18)), 56 | ); 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_english 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | 30 | NSAppTransportSecurity 31 | 32 | NSAllowsArbitraryLoads 33 | 34 | 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | UIViewControllerBasedStatusBarAppearance 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /lib/views/secendpage.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:scoped_model/scoped_model.dart'; 3 | import '../model/globle_model.dart'; 4 | import '../video/audioPlayerXbx.dart'; 5 | import '../views/category.dart'; 6 | import '../utils/screen_util.dart'; 7 | import '../globleConfig.dart'; 8 | 9 | class SecondPage extends StatefulWidget { 10 | @override 11 | SecondPageState createState() => new SecondPageState(); 12 | } 13 | 14 | class SecondPageState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return ScopedModelDescendant(builder: (context, child, model) 18 | { 19 | if (model.url != '' && model.url != null) { 20 | print("99999999999999999999444444444444444444449999999999999999999"); 21 | return AudioPlayerXbx(url: model.url, video: model.video, info: model.info,); 22 | } 23 | else{ 24 | double extralHeight = Klength.topBarHeight + //顶部标题栏高度 25 | Klength.bottomBarHeight + //底部tab栏高度 26 | ScreenUtil.statusBarHeight + //状态栏高度 27 | ScreenUtil.bottomBarHeight; //IPhoneX底部状态栏 28 | return Category( 29 | rightListViewHeight: ScreenUtil.screenHeight - extralHeight, 30 | ); 31 | } 32 | 33 | }); 34 | } 35 | @override 36 | void initState() { 37 | // TODO: implement initState 38 | super.initState(); 39 | } 40 | 41 | @override 42 | void dispose() { 43 | // TODO: implement dispose 44 | super.dispose(); 45 | } 46 | 47 | @override 48 | void didUpdateWidget(SecondPage oldWidget) { 49 | // TODO: implement didUpdateWidget 50 | super.didUpdateWidget(oldWidget); 51 | } 52 | 53 | @override 54 | void didChangeDependencies() { 55 | // TODO: implement didChangeDependencies 56 | super.didChangeDependencies(); 57 | } 58 | } -------------------------------------------------------------------------------- /lib/views/person/myfavera.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | import '../../model/globle_model.dart'; 4 | import '../../views/goodsList.dart'; 5 | import '../../utils/HttpUtils.dart'; 6 | import '../../utils/DialogUtils.dart'; 7 | 8 | class MyfaveratePage extends StatefulWidget { 9 | 10 | @override 11 | State createState() => MyfaveratePageState(); 12 | } 13 | 14 | class MyfaveratePageState extends State { 15 | @override 16 | Widget build(BuildContext context) { 17 | return Scaffold( 18 | appBar: AppBar( 19 | leading: SizedBox(width: 10,), 20 | elevation: 0, 21 | titleSpacing: 0, 22 | centerTitle: true, 23 | title:Text('收藏')), 24 | body: 25 | GoodsListWidget( 26 | _listData, 27 | getNextPage: () => getSearchList(), 28 | ) 29 | ); 30 | } 31 | 32 | int _page = 1; 33 | List> _listData = List(); 34 | void getSearchList() async { 35 | final model = globleModel().of(context); 36 | if( model.token!=''){ 37 | await HttpUtils.dioappi("User/collect_list/p/${_page.toString()}/", {}, withToken:true,context: context).then ( (response) { 38 | if (response['list']!=null && response['list'].isNotEmpty ) { 39 | setState(() { 40 | _page += 1; 41 | response['list'].forEach((ele) { 42 | if (ele.isNotEmpty) { 43 | _listData.add(ele); 44 | } 45 | }); 46 | }); 47 | } 48 | }); 49 | } 50 | } 51 | 52 | 53 | 54 | @override 55 | void initState() { 56 | super.initState(); 57 | getSearchList(); 58 | } 59 | @override 60 | void dispose() { 61 | // TODO: implement dispose 62 | _listData = null; 63 | super.dispose(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/constants/filter_menu.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 过滤菜单项 3 | * Create by Songlcy 4 | */ 5 | final List> FILTER_ITEM = [ 6 | [ 7 | {"title": "不限年代", "key": "year", "value": ""}, 8 | {"title": "2019", "key": "year", "value": "2018"}, 9 | {"title": "2018", "key": "year", "value": "2018"}, 10 | {"title": "2017", "key": "year", "value": "2017"}, 11 | {"title": "2016", "key": "year", "value": "2016"}, 12 | {"title": "2015", "key": "year", "value": "2015"}, 13 | {"title": "2014", "key": "year", "value": "2014"}, 14 | {"title": "2013", "key": "year", "value": "2013"}, 15 | {"title": "2012", "key": "year", "value": "2012"}, 16 | {"title": "2011", "key": "year", "value": "2011"}, 17 | {"title": "2010", "key": "year", "value": "2010"}, 18 | {"title": "00年代", "key": "year", "value": "00"}, 19 | {"title": "更早", "key": "year", "value": "更早"}, 20 | ], 21 | [ 22 | {"title": "不限地区", "key": "area", "value": ""}, 23 | {"title": "大陆", "key": "area", "value": "大陆"}, 24 | {"title": "香港", "key": "area", "value": "香港"}, 25 | {"title": "台湾", "key": "area", "value": "台湾"}, 26 | {"title": "日本", "key": "area", "value": "日本"}, 27 | {"title": "韩国", "key": "area", "value": "韩国"}, 28 | {"title": "美国", "key": "area", "value": "美国"}, 29 | {"title": "法国", "key": "area", "value": "法国"}, 30 | {"title": "德国", "key": "area", "value": "德国"}, 31 | {"title": "英国", "key": "area", "value": "英国"}, 32 | {"title": "其他", "key": "area", "value": "其他"}, 33 | ], 34 | [ 35 | {"title": "不限来源", "key": "source", "value": ""}, 36 | {"title": "最大资源网", "key": "source", "value": "zuidazy"}, 37 | {"title": "酷云资源网", "key": "source", "value": "kuyunzy"} 38 | ], 39 | [ 40 | {"title": "最新收录", "key": "sort", "value": "1"}, 41 | {"title": "最新上映", "key": "sort", "value": "2"}, 42 | {"title": "最多播放", "key": "sort", "value": "3"}, 43 | ], 44 | ]; -------------------------------------------------------------------------------- /lib/movie/moviedetail.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../api/movie.dart'; 3 | 4 | MovieApi movieApi = new MovieApi(); 5 | 6 | class MovieDetail extends StatefulWidget { 7 | MovieDetail({Key key, @required this.id, @required this.title}) 8 | : super(key: key); 9 | // 电影 Id 10 | final String id; 11 | // 电影 标题 12 | final String title; 13 | 14 | _MovieDetailState createState() => new _MovieDetailState(); 15 | } 16 | 17 | class _MovieDetailState extends State { 18 | // 电影详情 19 | var _minfo = {}; 20 | bool _isloading = true; 21 | 22 | @override 23 | void initState() { 24 | super.initState(); 25 | _getMovieInfo(); 26 | } 27 | 28 | _getMovieInfo() async { 29 | var temp = await movieApi.getMovieDetail(widget.id); 30 | setState(() { 31 | _minfo = temp; 32 | _isloading = false; 33 | }); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | return Scaffold( 39 | appBar: AppBar( 40 | title: Text( 41 | widget.title, 42 | style: TextStyle(fontSize: 14), 43 | ), 44 | centerTitle: true, 45 | ), 46 | body: _renderInfo(), 47 | ); 48 | } 49 | 50 | Widget _renderInfo() { 51 | if (_isloading) { 52 | return Center( 53 | child: CircularProgressIndicator(), 54 | ); 55 | } else { 56 | return ListView( 57 | children: [ 58 | Padding( 59 | child: Image.network(_minfo['images']['large'], height: 350), 60 | padding: EdgeInsets.symmetric(vertical: 15), 61 | ), 62 | Container( 63 | padding: EdgeInsets.symmetric(horizontal: 4), 64 | child: Text( 65 | _minfo['summary'], 66 | style: TextStyle(height: 1.5), 67 | ), 68 | ) 69 | ], 70 | ); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /lib/video/chewie_list_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:chewie/chewie.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:video_player/video_player.dart'; 4 | 5 | class ChewieListItem extends StatefulWidget { 6 | // This will contain the URL/asset path which we want to play 7 | final VideoPlayerController videoPlayerController; 8 | final bool looping; 9 | 10 | ChewieListItem({ 11 | @required this.videoPlayerController, 12 | this.looping, 13 | Key key, 14 | }) : super(key: key); 15 | 16 | @override 17 | _ChewieListItemState createState() => _ChewieListItemState(); 18 | } 19 | 20 | class _ChewieListItemState extends State { 21 | ChewieController _chewieController; 22 | 23 | @override 24 | void initState() { 25 | super.initState(); 26 | // Wrapper on top of the videoPlayerController 27 | _chewieController = ChewieController( 28 | videoPlayerController: widget.videoPlayerController, 29 | aspectRatio: 16 / 9, 30 | // Prepare the video to be played and display the first frame 31 | autoInitialize: true, 32 | looping: widget.looping, 33 | // Errors can occur for example when trying to play a video 34 | // from a non-existent URL 35 | errorBuilder: (context, errorMessage) { 36 | return Center( 37 | child: Text( 38 | errorMessage, 39 | style: TextStyle(color: Colors.white), 40 | ), 41 | ); 42 | }, 43 | ); 44 | } 45 | 46 | @override 47 | Widget build(BuildContext context) { 48 | return Padding( 49 | padding: const EdgeInsets.all(8.0), 50 | child:Chewie( 51 | controller: _chewieController, 52 | ), 53 | ); 54 | } 55 | 56 | @override 57 | void dispose() { 58 | super.dispose(); 59 | // IMPORTANT to dispose of all the used resources 60 | widget.videoPlayerController.dispose(); 61 | _chewieController.dispose(); 62 | } 63 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_english 2 | 3 | A new Flutter english application. 4 | 5 | ## Getting Started 6 | ### 本app主要演示的是关于音频播放和字幕同步的功能。 7 | ### 基于商城首页布局, 8 | #### 播放时自动同步字幕,支持中英文字幕, 9 | #### *点击字幕自动同步到指定音频位置, 10 | #### *拖动音频位置自动定位到字幕位置, 11 | #### 播放音频时自动加入缓存, 12 | #### 退出音频时记住状态,可以随时重新进入播放页面。 13 | #### 支持微信分享、微信支付。 14 | #### 其他涉及简单商品列表布局。 15 | 16 | ![github](https://github.com/xiebaoxin/flutter_english/blob/master/images/1200.png "github") 17 | ![github](https://github.com/xiebaoxin/flutter_english/blob/master/images/IMG_1198.PNG "github") 18 | ![github](https://github.com/xiebaoxin/flutter_english/blob/master/images/1199.png "github") 19 | 20 | 21 | # 使用到的插件 22 | url_launcher: any 23 | 24 | video_player: any 25 | 26 | chewie: any 27 | 28 | shimmer: ^0.0.6 29 | 30 | audioplayers: any 31 | 32 | http: any 33 | 34 | shared_preferences: any 35 | 36 | dio: ^2.1.13 37 | 38 | json_serializable: ^2.0.2 39 | 40 | flutter_picker: ^1.0.11 41 | 42 | flutter_webview_plugin: any 43 | 44 | flutter_swiper: ^1.1.4 45 | 46 | flutter_cupertino_date_picker: ^0.3.0 47 | 48 | qr_flutter: any 49 | 50 | fluro: ^1.4.0 51 | 52 | scoped_model: any 53 | 54 | rxdart: ^0.21.0 55 | 56 | provide: ^1.0.2 57 | 58 | provider: ^3.0.0+1 59 | 60 | image_crop: ^0.3.0 61 | 62 | image_picker: ^0.6.1 63 | 64 | flutter_native_image: 65 | git: https://github.com/btastic/flutter_native_image 66 | 67 | fluwx: any 68 | 69 | connectivity: ^0.4.2 70 | 71 | path_provider: ^0.5.0+1 72 | 73 | permission_handler: any 74 | 75 | package_info: any 76 | 77 | flutter_cache_manager: any 78 | 79 | cached_network_image: ^2.0.0-rc 80 | 81 | flutter_easyrefresh: any 82 | 83 | flutter_screenutil: any 84 | 85 | marquee_flutter: any 86 | 87 | intro_slider: 2.2.5 88 | 89 | flutter_html: any 90 | 91 | flt_video_player: ^0.0.2 92 | 93 | ## 本源码实际可以正常运行,需要更多了解到请联系我。 94 | ### QQ:94156520 95 | ### 微信:13531703369 96 | -------------------------------------------------------------------------------- /lib/video/anims/needle_anim.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/animation.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'dart:math'; 4 | 5 | class PivotTransition extends AnimatedWidget { 6 | /// 创建旋转变换 7 | /// turns不能为空. 8 | PivotTransition({ 9 | Key key, 10 | this.alignment: FractionalOffset.topCenter, 11 | @required Animation turns, 12 | this.child, 13 | }) : super(key: key, listenable: turns); 14 | 15 | /// The animation that controls the rotation of the child. 16 | /// If the current value of the turns animation is v, the child will be 17 | /// rotated v * 2 * pi radians before being painted. 18 | Animation get turns => listenable; 19 | 20 | /// The pivot point to rotate around. 21 | final FractionalOffset alignment; 22 | 23 | /// The widget below this widget in the tree. 24 | final Widget child; 25 | 26 | @override 27 | Widget build(BuildContext context) { 28 | final double turnsValue = turns.value; 29 | final Matrix4 transform = new Matrix4.rotationZ(turnsValue * pi * 2.0); 30 | return new Transform( 31 | transform: transform, 32 | alignment: alignment, 33 | child: child, 34 | ); 35 | } 36 | } 37 | 38 | class AnimatedNeedle extends AnimatedWidget { 39 | AnimatedNeedle({Key key, Animation animation}) 40 | : super(key: key, listenable: animation); 41 | 42 | Widget build(BuildContext context) { 43 | final Animation animation = listenable; 44 | return new Container( 45 | height: 300.0, 46 | width: 100.0, 47 | child: new PivotTransition( 48 | turns: animation, 49 | alignment: FractionalOffset.topCenter, 50 | child: new Container( 51 | decoration: BoxDecoration( 52 | shape: BoxShape.circle, 53 | image: DecorationImage( 54 | image: AssetImage("images/play_needle.png"), 55 | ), 56 | ), 57 | )), 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/components/animation_text_component.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 动画Text组件 3 | * Create by Songlcy 4 | */ 5 | import 'package:flutter/material.dart'; 6 | 7 | class AnimationTextComponent extends StatefulWidget { 8 | final String text; 9 | final TextStyle textStyle; 10 | 11 | final int duration; 12 | final int delayTime; 13 | 14 | const AnimationTextComponent({ 15 | this.text = "", 16 | this.textStyle = const TextStyle(color: Colors.black), 17 | this.duration = 1000, 18 | this.delayTime = 0 19 | }); 20 | 21 | @override 22 | State createState() => _AnimationTextComponentState(); 23 | } 24 | 25 | class _AnimationTextComponentState extends State with SingleTickerProviderStateMixin { 26 | 27 | String showText; 28 | String hideText; 29 | Animation animation; 30 | AnimationController animationContainer; 31 | 32 | @override 33 | void initState() { 34 | super.initState(); 35 | 36 | animationContainer = AnimationController( 37 | vsync: this, 38 | duration: Duration(microseconds: widget.duration) 39 | ); 40 | 41 | animation = IntTween( 42 | begin: 0, 43 | end: widget.text.length 44 | ).animate(CurvedAnimation(parent: animationContainer, curve: Curves.easeIn)); 45 | 46 | animation.addListener((){ 47 | // 刷新text 48 | setState(() { 49 | showText = widget.text.substring(0, animation.value); 50 | hideText = widget.text.substring(animation.value, widget.text.length); 51 | }); 52 | }); 53 | 54 | Future.delayed(Duration(microseconds: widget.delayTime), (){ 55 | animationContainer.forward(from: 0.0); 56 | }); 57 | } 58 | 59 | @override 60 | Widget build(BuildContext context) { 61 | return RichText( 62 | maxLines: 10, 63 | overflow: TextOverflow.ellipsis, 64 | text: TextSpan( 65 | children: [ 66 | TextSpan(text: showText, style: widget.textStyle), 67 | TextSpan(text: hideText, style: widget.textStyle.copyWith(color: Colors.transparent)) 68 | ] 69 | ), 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lib/components/keyboard/CustomJPasswordFieldWidget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'dart:math'; 5 | 6 | 7 | /// 自定义 密码输入框 8 | 9 | class CustomJPasswordField extends StatelessWidget { 10 | 11 | /// 传入当前密码 12 | String data; 13 | CustomJPasswordField(this.data); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return CustomPaint( 18 | painter: MyCustom(data), 19 | ); 20 | } 21 | } 22 | 23 | class MyCustom extends CustomPainter { 24 | 25 | 26 | String pwdLength; 27 | MyCustom(this.pwdLength); 28 | 29 | 30 | @override 31 | void paint(Canvas canvas, Size size) { 32 | 33 | int PWD_SPACING = 5; 34 | int PWD_SIZE = 5; 35 | int mWidth; 36 | 37 | // 密码长度 38 | int PWD_LENGTH = 6; 39 | 40 | // 密码画笔 41 | Paint mPwdPaint; 42 | Paint mRectPaint; 43 | Rect mRect; 44 | int mInputLength; 45 | 46 | 47 | // 初始化密码画笔   48 | mPwdPaint = new Paint(); 49 | mPwdPaint..color = Colors.black; 50 | 51 | // mPwdPaint.setAntiAlias(true); 52 | // 初始化密码框   53 | mRectPaint = new Paint(); 54 | mRectPaint..color = Color(0xff707070); 55 | 56 | 57 | RRect r = new RRect.fromLTRBR( 58 | 0.0, 0.0, size.width, size.height, new Radius.circular(size.height / 12)); 59 | mRectPaint.style = PaintingStyle.stroke; 60 | canvas.drawRRect(r, mRectPaint); 61 | 62 | 63 | var per = size.width / 6.0; 64 | var offsetX = per; 65 | while (offsetX < size.width) { 66 | canvas.drawLine( 67 | new Offset(offsetX, 0.0), new Offset(offsetX, size.height), mRectPaint); 68 | offsetX += per; 69 | } 70 | 71 | var half = per/2; 72 | var radio = per/8; 73 | 74 | mPwdPaint.style = PaintingStyle.fill; 75 | for(int i =0; i< pwdLength.length && i< 6; i++){ 76 | canvas.drawArc(new Rect.fromLTRB(i*per+half-radio, size.height/2-radio, i*per+half+radio, size.height/2+radio), 0.0, 2*pi, true, mPwdPaint); 77 | } 78 | } 79 | 80 | @override 81 | bool shouldRepaint(CustomPainter oldDelegate) { 82 | return true; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /lib/widgets/NavigationIconView.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * @Description 底部导航 3 | * @Author zhibuyu 4 | * @Date 2018/10/26 14:09 5 | * @Version 1.0 6 | */ 7 | import 'package:flutter/material.dart'; 8 | 9 | class NavigationIconView { 10 | NavigationIconView({ 11 | Widget icon, 12 | Widget activeIcon, 13 | String title, 14 | Color color, 15 | TickerProvider vsync, 16 | }) : icon = icon, 17 | color = color, 18 | title = title, 19 | item = BottomNavigationBarItem( 20 | icon: icon, 21 | activeIcon: activeIcon, 22 | title: Text(title), 23 | backgroundColor: color, 24 | ), 25 | controller = AnimationController( 26 | duration: kThemeAnimationDuration, 27 | vsync: vsync, 28 | ) { 29 | animation = controller.drive(CurveTween( 30 | curve: const Interval(0.5, 1.0, curve: Curves.fastOutSlowIn), 31 | )); 32 | } 33 | 34 | final Widget icon; 35 | final Color color; 36 | final String title; 37 | final BottomNavigationBarItem item; 38 | final AnimationController controller; 39 | Animation animation; 40 | 41 | FadeTransition transition( 42 | BottomNavigationBarType type, BuildContext context) { 43 | Color iconColor; 44 | if (type == BottomNavigationBarType.shifting) { 45 | iconColor = color; 46 | } else { 47 | final ThemeData themeData = Theme.of(context); 48 | iconColor = themeData.brightness == Brightness.light 49 | ? themeData.primaryColor 50 | : themeData.accentColor; 51 | } 52 | 53 | return FadeTransition( 54 | opacity: animation, 55 | child: SlideTransition( 56 | position: animation.drive( 57 | Tween( 58 | begin: const Offset(0.0, 0.02), // Slightly down. 59 | end: Offset.zero, 60 | ), 61 | ), 62 | child: IconTheme( 63 | data: IconThemeData( 64 | color: iconColor, 65 | size: 120.0, 66 | ), 67 | child: Semantics( 68 | label: 'Placeholder for $title tab', 69 | child: icon, 70 | ), 71 | ), 72 | ), 73 | ); 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /lib/views/category_Page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' as math; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | import '../utils/dataUtils.dart'; 5 | import 'goodsList.dart'; 6 | 7 | class CategoryPage extends StatefulWidget { 8 | final int catid; 9 | final String catname; 10 | CategoryPage(Key key, this.catid,{this.catname=""}) : super(key: key); 11 | @override 12 | CategoryPageState createState() => new CategoryPageState(); 13 | } 14 | 15 | class CategoryPageState extends State { 16 | int _page = 1; 17 | List> _goodsList = List(); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return new Scaffold( 22 | appBar: new AppBar( 23 | title: new Text(widget.catname), 24 | ), 25 | body: GoodsListWidget(_goodsList, getNextPage: () => getGoodsList()) 26 | ); 27 | } 28 | @override 29 | void initState() { 30 | getGoodsList(); 31 | // TODO: implement initState 32 | super.initState(); 33 | } 34 | 35 | @override 36 | void dispose() { 37 | // TODO: implement dispose 38 | super.dispose(); 39 | } 40 | 41 | void getGoodsList() async { 42 | _goodsList= await DataUtils.getIndexGoodsList(_page,_goodsList, context,catid:widget.catid ); 43 | if(_goodsList.isNotEmpty) 44 | setState(() { 45 | _page += 1; 46 | }); 47 | /* await HttpUtils.dioappi( 48 | "Shop/ajaxGoodsList/p/${_page.toString()}/id/${widget.catid}", {}, context: context).then ((response) { 49 | print(response); 50 | setState(() { 51 | if (response['list'].isNotEmpty) { 52 | _page += 1; 53 | response['list'].forEach((ele) { 54 | if (ele.isNotEmpty) { 55 | Map itemmap = ele; 56 | _goodsList.add(itemmap); 57 | } 58 | }); 59 | } 60 | }); 61 | });*/ 62 | } 63 | 64 | @override 65 | void didUpdateWidget(CategoryPage oldWidget) { 66 | // TODO: implement didUpdateWidget 67 | super.didUpdateWidget(oldWidget); 68 | } 69 | 70 | @override 71 | void didChangeDependencies() { 72 | // TODO: implement didChangeDependencies 73 | super.didChangeDependencies(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/components/wxshare.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:fluwx/fluwx.dart'; 4 | import 'package:fluwx/fluwx.dart' as fluwx; 5 | 6 | class wxShareDialog extends StatelessWidget { 7 | const wxShareDialog( 8 | {Key key, this.title, this.content, this.img, this.imgid, this.url}) 9 | : super(key: key); 10 | 11 | final Widget title; 12 | final Widget content; 13 | final String img; 14 | final String url; 15 | final String imgid; 16 | /* 17 | 18 | _initFluwx() async{ 19 | await fluwx.register(appId: GlobalConfig.wxAppId, doOnAndroid: true, doOnIOS: true, enableMTA: false); 20 | var result = await fluwx.isWeChatInstalled(); 21 | print("is installed $result"); 22 | } 23 | */ 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return CupertinoAlertDialog( 28 | title: title, 29 | content: content, 30 | actions: [ 31 | 32 | CupertinoDialogAction( 33 | child: const Text('微信好友'), 34 | onPressed: () { 35 | fluwx 36 | .share(WeChatShareImageModel( 37 | image: img, // "assets://images/down_qrcode.png", 38 | thumbnail: "assets://logo.png", 39 | transaction: url, 40 | scene: WeChatScene.SESSION, 41 | description: "image")) 42 | .then((rv) { 43 | print(rv); 44 | // Navigator.pop(context, 'Cancel'); 45 | }); 46 | }, 47 | ), 48 | CupertinoDialogAction( 49 | child: const Text('微信朋友圈'), 50 | onPressed: () { 51 | fluwx.share(WeChatShareImageModel( 52 | image: img, //"assets://images/down_qrcode.png", 53 | thumbnail: "", 54 | transaction: url, //, 55 | scene: WeChatScene.TIMELINE, 56 | description: "护卡宝邀请您")); 57 | }, 58 | ), 59 | 60 | CupertinoDialogAction( 61 | child: const Text('取消'), 62 | isDestructiveAction: true, 63 | onPressed: () { 64 | Navigator.pop(context, 'Cancel'); 65 | }, 66 | ), 67 | ], 68 | ); 69 | } 70 | } -------------------------------------------------------------------------------- /lib/data/cart.dart: -------------------------------------------------------------------------------- 1 | var cartInitData = [ 2 | { 3 | "goods_id":118, 4 | "buy_limit": 5, 5 | "count": 1, 6 | "image_url": 7 | "http://img11.360buyimg.com/n1/jfs/t1/9657/6/11570/80442/5c2d6628Ebe4cc5a3/92c0b2cf99e824e4.jpg", 8 | "goods_price": "25.00", 9 | "product_name": "DEZONE立体塑形眉笔 M01深棕", 10 | "select_status": 1, 11 | }, 12 | { 13 | "goods_id":79, 14 | "buy_limit": 20, 15 | "count": 2, 16 | "image_url": 17 | "http://img10.360buyimg.com/n1/jfs/t1/26858/10/448/356042/5c09eceaEab5ae51b/cef5db356f91e40e.jpg", 18 | "goods_price": "69.00", 19 | "product_name": "水肌美百搭魅腮红", 20 | "select_status": 1, 21 | }, 22 | { 23 | "goods_id":110, 24 | "buy_limit": 20, 25 | "count": 1, 26 | "image_url": 27 | "http://img10.360buyimg.com/n5/s450x450_jfs/t16234/63/1866674088/94769/ee402c21/5a66dd60Nae2d8b8e.jpg", 28 | "goods_price": "69.00", 29 | "product_name": "水肌美大地四色眼影", 30 | "select_status": 0 31 | }, 32 | { 33 | "goods_id":1, 34 | "buy_limit": 10, 35 | "count": 1, 36 | "image_url": 37 | "https://img11.360buyimg.com/n5/s450x450_jfs/t6010/318/1703207806/120270/bd4b107/59363ec5N80eacbbb.jpg", 38 | "goods_price": "79.00", 39 | "product_name": "水肌美定妆蜜粉饼", 40 | "select_status": 1, 41 | }, 42 | { 43 | "goods_id":15, 44 | "buy_limit": 20, 45 | "count": 1, 46 | "image_url": 47 | "https://img14.360buyimg.com/n5/s450x450_jfs/t17254/153/2063966328/98492/9c4b79d9/5ae4277cN31c1c917.jpg", 48 | "goods_price": "199.00", 49 | "product_name": "Dior迪奥香水女士香水30ml", 50 | "select_status": 1, 51 | }, 52 | { 53 | "goods_id":18, 54 | "buy_limit": 20, 55 | "count": 1, 56 | "image_url": 57 | "https://img13.360buyimg.com/n5/s450x450_jfs/t27082/149/1083201661/158502/14e988db/5bc0ce0aN5dd7e960.jpg", 58 | "goods_price": "279.00", 59 | "minus_reduce": "0", 60 | "product_name": "迪奥口红女士唇膏圣诞年货礼盒套装礼物", 61 | "select_status": 0, 62 | }, 63 | { 64 | "goods_id":13, 65 | "buy_limit": 20, 66 | "count": 1, 67 | "image_url": 68 | "http://img11.360buyimg.com/n5/s450x450_jfs/t1/21271/25/920/226453/5c0e254dE10634863/308bfd31489acaea.jpg", 69 | "goods_price": "358.00", 70 | "product_name": "兰蔻气垫CC霜气垫BB霜", 71 | "select_status": 1 72 | } 73 | ]; 74 | -------------------------------------------------------------------------------- /lib/routers/router_handler.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:fluro/fluro.dart'; 3 | import '../views/webView.dart'; 4 | import '../views/login.dart'; 5 | import '../views/MyInfoPage.dart'; 6 | import '../homePage.dart'; 7 | import '../splashPage.dart'; 8 | import '../views/sharePage.dart'; 9 | import '../views/payLog.dart'; 10 | import '../views/myMsgList.dart'; 11 | 12 | // /web?url=${Uri.encodeComponent(linkUrl)}&title=${Uri.encodeComponent('掘金沸点')} 13 | //'/swip?pics=${Uri.encodeComponent(_buildPicsStr())}¤tIndex=${i.toString()}' 14 | Handler webPageHandler = Handler( 15 | handlerFunc: (BuildContext context, Map> params) { 16 | String articleUrl = params['url']?.first; 17 | String title = params['title']?.first; 18 | print('$articleUrl and $title'); 19 | return WebView(title, articleUrl); 20 | } 21 | ); 22 | 23 | Handler loginPageHandler = Handler( 24 | handlerFunc: (BuildContext context, Map> params) { 25 | return LoginPage(); 26 | }); 27 | 28 | Handler homePageHandler = Handler( 29 | handlerFunc: (BuildContext context, Map> params) { 30 | return App(); 31 | }); 32 | 33 | 34 | Handler flashPageHandler = Handler( 35 | handlerFunc: (BuildContext context, Map> params) { 36 | return SplashPage(); 37 | }); 38 | 39 | 40 | Handler sharePageHandler = Handler( 41 | handlerFunc: (BuildContext context, Map> params) { 42 | return sharePage(); 43 | // return MyInfoPage(); 44 | }); 45 | 46 | Handler userPageHandler = Handler( 47 | handlerFunc: (BuildContext context, Map> params) { 48 | /* String user_id = params['id']?.first; 49 | String status=params['status']?.first; 50 | String phone = params['phone']?.first; 51 | String name = params['username']?.first; 52 | String avatar= params['avatar']?.first;*/ 53 | return MyInfoPage();//user_id,status,phone,name,avatar 54 | }); 55 | 56 | 57 | Handler myMsgListPageHandler = Handler( 58 | handlerFunc: (BuildContext context, Map> params) { 59 | return myMsgListPage(); 60 | }); 61 | 62 | Handler payLogPageHandler = Handler( 63 | handlerFunc: (BuildContext context, Map> params) { 64 | return payLogPage(); 65 | }); 66 | 67 | 68 | -------------------------------------------------------------------------------- /lib/views/details/details_tabar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../utils/screen_util.dart'; 3 | 4 | class DetailsTabBar extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | var isLeft = true; 8 | var isRight = false; 9 | return Container( 10 | margin: EdgeInsets.only(top: 15.0), 11 | child: Row( 12 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 13 | children: [ 14 | Expanded(child: _myTabBarLeft(context, isLeft),flex: 1,), 15 | Expanded(child: _myTabBarRight(context, isRight),flex: 1,) 16 | 17 | ], 18 | ), 19 | ); 20 | 21 | } 22 | 23 | Widget _myTabBarLeft(BuildContext context, bool isLeft) { 24 | return InkWell( 25 | onTap: () { 26 | // Provide.value(context).changeLeftAndRight(0); 27 | }, 28 | child: Container( 29 | padding: EdgeInsets.all(10.0), 30 | alignment: Alignment.center, 31 | decoration: BoxDecoration( 32 | color: Colors.white, 33 | border: Border( 34 | bottom: BorderSide( 35 | width: 1.0, 36 | color: isLeft ? Colors.deepOrangeAccent : Colors.black12, 37 | ), 38 | ), 39 | ), 40 | child: Text( 41 | '详情', 42 | style: TextStyle( 43 | color: isLeft ? Colors.deepOrangeAccent : Colors.black, 44 | ), 45 | ), 46 | ), 47 | ); 48 | } 49 | 50 | /// 右边的tabar 51 | Widget _myTabBarRight(BuildContext context, bool isRight) { 52 | return InkWell( 53 | onTap: () { 54 | // Provide.value(context).changeLeftAndRight(1); 55 | }, 56 | child: Container( 57 | padding: EdgeInsets.all(10.0), 58 | alignment: Alignment.center, 59 | decoration: BoxDecoration( 60 | color: Colors.white, 61 | border: Border( 62 | bottom: BorderSide( 63 | width: 1.0, 64 | color: isRight ? Colors.deepOrangeAccent : Colors.black12, 65 | ), 66 | ), 67 | ), 68 | child: Text( 69 | '评论', 70 | style: TextStyle( 71 | color: isRight ? Colors.deepOrangeAccent : Colors.black, 72 | ), 73 | ), 74 | ), 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lib/views/cart/cart_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | import '../../model.dart'; 4 | import 'package:scoped_model/scoped_model.dart'; 5 | import '../../model/globle_model.dart'; 6 | import '../../constants/color.dart'; 7 | import 'cartItem.dart'; 8 | 9 | class CartListWidget extends StatelessWidget { 10 | globleModel model; 11 | @override 12 | Widget build(BuildContext context) { 13 | return ScopedModelDescendant( 14 | builder: (context, child, model) { 15 | this.model = model; 16 | if(model.items.isEmpty) 17 | return Text("空空如也"); 18 | else 19 | return Expanded( 20 | child: ListView.builder( 21 | padding: EdgeInsets.all(0), 22 | itemCount: model.itemsCount, 23 | itemExtent: 93, 24 | itemBuilder: (BuildContext context, int index) { 25 | CartItemModel item = model.items[index]; 26 | return Dismissible( 27 | resizeDuration: Duration(milliseconds: 100), 28 | key: Key(item.productName), 29 | onDismissed: (direction) { 30 | model.removeItem(index); 31 | Scaffold.of(context).showSnackBar(SnackBar( 32 | content: Text("${item.productName} 成功移除"), 33 | backgroundColor: KColorConstant.themeColor, 34 | duration: Duration(seconds: 1), 35 | )); 36 | }, 37 | background: Container(color: KColorConstant.themeColor), 38 | child: CartItemWidget(model.items[index], 39 | /* addCount: (int i) { 40 | model.addCount(i); 41 | }, 42 | downCount: (int i) { 43 | model.downCount(i); 44 | }, 45 | index: index, 46 | switchChaned: (i){ model.switchSelect(i);}*/ 47 | addCount: _addCount, 48 | downCount: _downCount, 49 | index: index, 50 | switchChaned: _switchChanged 51 | ), 52 | ); 53 | }, 54 | 55 | )); 56 | }) ; 57 | } 58 | 59 | _switchChanged(int i) { 60 | model.switchSelect(i); 61 | } 62 | 63 | _addCount(int i) { 64 | model.addCount(i); 65 | } 66 | 67 | _downCount(int i) { 68 | model.downCount(i); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | // 签名 8f9db55385d2baa9936d336c43268e27 42 | applicationId "com.bixue.english" 43 | minSdkVersion 16 44 | targetSdkVersion 28 45 | versionCode 6 46 | versionName '1.0.6' 47 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 48 | } 49 | 50 | buildTypes { 51 | release { 52 | // TODO: Add your own signing config for the release build. 53 | // Signing with the debug keys for now, so `flutter run --release` works. 54 | signingConfig signingConfigs.debug 55 | } 56 | } 57 | } 58 | 59 | flutter { 60 | source '../..' 61 | } 62 | 63 | dependencies { 64 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 65 | testImplementation 'junit:junit:4.12' 66 | // androidTestImplementation 'com.android.support.test:runner:1.0.2' 67 | // androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 68 | 69 | implementation 'androidx.core:core-ktx:1.0.0-alpha1' 70 | implementation 'androidx.annotation:annotation:1.1.0-alpha02' 71 | } 72 | -------------------------------------------------------------------------------- /lib/views/search/search.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | import '../../widgets/index.dart'; 4 | import 'searchserver.dart'; 5 | import 'package:flutter/cupertino.dart'; 6 | import 'searchlist.dart'; 7 | import '../../globleConfig.dart'; 8 | 9 | class SearchPage extends StatefulWidget { 10 | @override 11 | State createState() => SearchPageState(); 12 | } 13 | 14 | class SearchPageState extends State { 15 | List hotWords = []; 16 | List recomendWords = []; 17 | TextEditingController controller = new TextEditingController(); 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | // brightness: Brightness.light, 23 | // backgroundColor: KColorConstant.searchAppBarBgColor, 24 | leading: SearchTopBarLeadingWidget(), 25 | actions: [ 26 | SearchTopBarActionWidget( 27 | onActionTap: () => goSearchList(controller.text), 28 | ) 29 | ], 30 | elevation: 0, 31 | titleSpacing: 0, 32 | title: SearchTopBarTitleWidget( 33 | seachTxtChanged: seachTxtChanged, 34 | controller: controller, 35 | )), 36 | body: recomendWords.length == 0 37 | ? HotSugWidget(hotWords:hotWords,goSearchList: goSearchList,) 38 | : RecomendListWidget(recomendWords, onItemTap: goSearchList), 39 | ); 40 | } 41 | 42 | void initData() async { 43 | List querys = await getHotSugs(context); 44 | if(querys!=null) 45 | setState(() { 46 | hotWords = querys; 47 | }); 48 | } 49 | 50 | onSearchBtTap() { 51 | if (controller.text.trim().isNotEmpty) { 52 | goSearchList(controller.text); 53 | } 54 | } 55 | 56 | void seachTxtChanged(String q) async { 57 | var result = await getSuggest(q) as List; 58 | recomendWords = result.map((dynamic i) { 59 | List item = i as List; 60 | return item[0] as String; 61 | }).toList(); 62 | setState(() {}); 63 | } 64 | 65 | goSearchList(String keyWord) { 66 | if (keyWord.trim().isNotEmpty) { 67 | Navigator.push(context, 68 | CupertinoPageRoute(builder: (BuildContext context) { 69 | return SearchResultListPage(keyWord); 70 | })); 71 | } 72 | } 73 | 74 | @override 75 | void initState() { 76 | initData(); 77 | super.initState(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lib/views/noticeMessgeList.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:cached_network_image/cached_network_image.dart'; 3 | import '../components/loading_gif.dart'; 4 | import '../model/globle_model.dart'; 5 | import '../globleConfig.dart'; 6 | import '../routers/application.dart'; 7 | import '../utils/screen_util.dart'; 8 | import '../utils/comUtil.dart'; 9 | 10 | class noticeMessgeList extends StatelessWidget { 11 | final List> list; 12 | final String txt; 13 | final VoidCallback getNextPage; 14 | noticeMessgeList(this.txt,this.list, { this.getNextPage}); 15 | @override 16 | Widget build(BuildContext context) { 17 | Widget imgtop; 18 | Widget maindd= 19 | list.length == 0 20 | ? Center( 21 | child: Padding( 22 | padding: const EdgeInsets.all(18.0), 23 | child: Text("空空如也"), 24 | ), 25 | ) 26 | : ListView.builder( 27 | padding: EdgeInsets.symmetric(horizontal: 5), 28 | itemCount: list.length, 29 | itemExtent: 75, 30 | itemBuilder: (BuildContext context, int i) { 31 | Map item = list[i]['message']; 32 | if ((i + 3) == list.length) { 33 | getNextPage(); 34 | } 35 | String titile=item['message_title'].toString(); 36 | titile= titile.length<=12 ? titile : titile.substring(0,16)+"…"; 37 | return Padding( 38 | padding: const EdgeInsets.all(2.0), 39 | child: Container( 40 | color: KColorConstant.searchAppBarBgColor, 41 | padding: EdgeInsets.all(5), 42 | child: 43 | InkWell( 44 | onTap: (){ComFunUtil().alertMsg(context, item);}, 45 | child: ListTile( 46 | title: Text(item['message_title'],style: KfontConstant.bigfontSize,), 47 | trailing: new Text( 48 | ComFunUtil.getTimeDuration(item['send_time'].toString()), 49 | style: KfontConstant.defaultStyle, 50 | ), 51 | ) 52 | , 53 | ), 54 | ), 55 | ); 56 | }, 57 | ); 58 | 59 | return Scaffold( 60 | appBar: AppBar( 61 | title: Text(txt), 62 | ), 63 | body: Center( 64 | child: maindd, 65 | ), 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/widgets/category/right_list_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../model.dart'; 3 | import 'list_view_item.dart'; 4 | 5 | class RightListView extends StatefulWidget { 6 | final double height; 7 | final List dataItems; 8 | final ValueChanged listViewChanged; 9 | RightListView({Key key, this.height, this.dataItems, this.listViewChanged}) 10 | : super(key: key); 11 | @override 12 | State createState() => RightListViewState(); 13 | } 14 | 15 | class RightListViewState extends State { 16 | int currentPage = 0; 17 | bool isAnimating = false; 18 | int itemCount = 0; 19 | ScrollController controller = ScrollController(); 20 | 21 | 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | itemCount = widget.dataItems.length; 26 | return Expanded( 27 | // child: NotificationListener( 28 | // onNotification: (a){ 29 | // if(a.depth==0){ 30 | // //判断一下是否是滑动的整块,纠正一下 31 | // } 32 | // }, 33 | child: ListView.builder( 34 | physics: NeverScrollableScrollPhysics(), //禁用手动滑动,于是有了上面的注释 35 | padding: EdgeInsets.all(0), 36 | controller: controller, 37 | itemBuilder: _itembuilder, 38 | itemCount: itemCount, 39 | itemExtent: widget.height, 40 | ), 41 | // ), 42 | ); 43 | } 44 | 45 | Widget _itembuilder(BuildContext context, int index) { 46 | var data = widget.dataItems[index]; 47 | return SubCategoryList(data: data, height: widget.height, goPage: goPage); 48 | } 49 | 50 | void goPage(String tag) { 51 | if (this.isAnimating) return; 52 | if (tag == 'pre') { 53 | if (currentPage == 0) { 54 | return; 55 | } else { 56 | currentPage--; 57 | } 58 | } else { 59 | if (currentPage == itemCount - 1) { 60 | return; 61 | } else { 62 | currentPage++; 63 | } 64 | } 65 | widget.listViewChanged(currentPage); 66 | animateTopage(currentPage); 67 | } 68 | 69 | jumpTopage(int i) { 70 | currentPage = i; 71 | double offset = widget.height * i; 72 | this.controller.jumpTo(offset); 73 | } 74 | 75 | animateTopage(int i) { 76 | if (this.isAnimating) return; 77 | currentPage = i; 78 | this.isAnimating = true; 79 | double offset = widget.height * i; 80 | this 81 | .controller 82 | .animateTo(offset, 83 | duration: Duration(milliseconds: 300), curve: Curves.easeOut) 84 | .then((onValue) => this.isAnimating = false); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lib/components/wxPay.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io' as H; 3 | 4 | import 'package:flutter/material.dart'; 5 | import 'package:fluwx/fluwx.dart' as fluwx; 6 | 7 | class PayPage extends StatefulWidget { 8 | @override 9 | _PayPageState createState() => _PayPageState(); 10 | } 11 | 12 | class _PayPageState extends State { 13 | String _url = "https://wxpay.wxutil.com/pub_v2/app/app_pay.php"; 14 | 15 | String _result = "无"; 16 | 17 | @override 18 | void initState() { 19 | super.initState(); 20 | 21 | fluwx.responseFromPayment.listen((data) { 22 | setState(() { 23 | _result = "${data.errCode}"; 24 | }); 25 | }); 26 | } 27 | /* fluwx.pay(WeChatPayModel( 28 | appId: 'wxd930ea5d5a258f4f', 29 | partnerId: '1900000109', 30 | prepayId: '1101000000140415649af9fc314aa427', 31 | packageValue: 'Sign=WXPay', 32 | nonceStr: '1101000000140429eb40476f8896f4c9', 33 | timeStamp: '1398746574', 34 | sign: '7FFECB600D7157C5AA49810D2D8F28BC2811827B', 35 | signType: '选填', 36 | extData: '选填' 37 | )); 38 | */ 39 | @override 40 | Widget build(BuildContext context) { 41 | return Scaffold( 42 | appBar: AppBar( 43 | title: const Text("pay"), 44 | ), 45 | body: Column( 46 | children: [ 47 | OutlineButton( 48 | onPressed: () async { 49 | var h = H.HttpClient(); 50 | h.badCertificateCallback = (cert, String host, int port) { 51 | return true; 52 | }; 53 | var request = await h.getUrl(Uri.parse(_url)); 54 | var response = await request.close(); 55 | var data = await response.transform(Utf8Decoder()).join(); 56 | Map result = json.decode(data); 57 | print(result['appid']); 58 | print(result["timestamp"]); 59 | fluwx 60 | .pay( 61 | appId: result['appid'].toString(), 62 | partnerId: result['partnerid'].toString(), 63 | prepayId: result['prepayid'].toString(), 64 | packageValue: result['package'].toString(), 65 | nonceStr: result['noncestr'].toString(), 66 | timeStamp: result['timestamp'], 67 | sign: result['sign'].toString(), 68 | ) 69 | .then((data) { 70 | print("---》$data"); 71 | }); 72 | }, 73 | child: const Text("pay"), 74 | ), 75 | const Text("响应结果;"), 76 | Text(_result) 77 | ], 78 | ), 79 | ); 80 | } 81 | } -------------------------------------------------------------------------------- /lib/views/search/searchlist.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | import '../../widgets/index.dart'; 4 | import '../../views/goodsList.dart'; 5 | import '../../utils/HttpUtils.dart'; 6 | import '../../utils/DialogUtils.dart'; 7 | 8 | class SearchResultListPage extends StatefulWidget { 9 | final String keyword; 10 | final String catname; 11 | final int catid; 12 | SearchResultListPage(this.keyword,{this.catid=0,this.catname=''}); 13 | 14 | @override 15 | State createState() => SearchResultListState(); 16 | } 17 | 18 | class SearchResultListState extends State { 19 | @override 20 | Widget build(BuildContext context) { 21 | return Scaffold( 22 | appBar: AppBar( 23 | // brightness: Brightness.light, 24 | // backgroundColor: KColorConstant.searchAppBarBgColor, 25 | // leading: SearchTopBarLeadingWidget(), 26 | // actions: [SearchTopBarActionWidget()], 27 | centerTitle: true, 28 | elevation: 0, 29 | titleSpacing: 0, 30 | title:widget.keyword!=''? SearchListTopBarTitleWidget(keyworld: widget.keyword):Text(widget.catname)), 31 | body: 32 | GoodsListWidget( 33 | _listData, 34 | getNextPage: () => getSearchList(), 35 | ) 36 | ); 37 | } 38 | 39 | 40 | 41 | int _page = 1; 42 | List> _listData = List(); 43 | String _keyword; 44 | int _catid; 45 | 46 | 47 | 48 | void getSearchList() async { 49 | Map params = {}; 50 | String url=""; 51 | if(_catid>0) 52 | url="Shop/ajaxGoodsList/id/${_catid.toString()}/p/${_page.toString()}/"; 53 | 54 | if(_keyword!=''){ 55 | url="Shop/search/p/${_page.toString()}/"; 56 | params = { 57 | "q": _keyword 58 | }; 59 | } 60 | 61 | await HttpUtils.dioappi(url, params, context: context).then ( (response) { 62 | if (response['list']!=null && response['list'].isNotEmpty ) { 63 | setState(() { 64 | _page += 1; 65 | response['list'].forEach((ele) { 66 | if (ele.isNotEmpty) { 67 | _listData.add(ele); 68 | } 69 | }); 70 | }); 71 | } 72 | }); 73 | } 74 | 75 | 76 | 77 | @override 78 | void initState() { 79 | _keyword=widget.keyword; 80 | _catid=widget.catid; 81 | super.initState(); 82 | getSearchList(); 83 | } 84 | @override 85 | void dispose() { 86 | // TODO: implement dispose 87 | _listData = null; 88 | super.dispose(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lib/widgets/search/topbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../constants/index.dart'; 3 | 4 | class SearchTopBarLeadingWidget extends StatelessWidget { 5 | @override 6 | Widget build(BuildContext context) { 7 | return GestureDetector( 8 | onTap: () => Navigator.pop(context), 9 | child: 10 | Icon(Icons.keyboard_arrow_left, color: Color(0xFFFFFFFF), size: 26), 11 | ); 12 | } 13 | } 14 | 15 | class SearchTopBarActionWidget extends StatelessWidget { 16 | final VoidCallback onActionTap; 17 | SearchTopBarActionWidget({this.onActionTap}); 18 | 19 | @override 20 | Widget build(BuildContext context) { 21 | return InkWell( 22 | onTap: onActionTap, 23 | child: Container( 24 | alignment: Alignment.center, 25 | padding: EdgeInsets.symmetric(horizontal: 5), 26 | child: Text( 27 | KString.searchBtTxt, 28 | style: TextStyle( 29 | color: Color(0xFFFFFFFF),//KColorConstant.goPayBtBgColor, 30 | fontWeight: FontWeight.bold), 31 | ), 32 | ), 33 | ); 34 | } 35 | } 36 | 37 | class SearchTopBarTitleWidget extends StatelessWidget { 38 | final ValueChanged seachTxtChanged; 39 | final TextEditingController controller; 40 | SearchTopBarTitleWidget({Key key, this.seachTxtChanged,this.controller}) : super(key: key); 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | return Container( 45 | height: Klength.searchTxtFieldHeight, 46 | padding: EdgeInsets.only(left: 10), 47 | alignment: Alignment.center, 48 | decoration: BoxDecoration( 49 | color: KColorConstant.divideLineColor, 50 | borderRadius: BorderRadius.all(Radius.circular(5))), 51 | child: Row( 52 | crossAxisAlignment: CrossAxisAlignment.center, 53 | children: [ 54 | Icon(Icons.search,color: KColorConstant.floorTitleColor,size: 20,), 55 | Expanded( 56 | child: TextField( 57 | controller: controller , 58 | onSubmitted: (s) { 59 | print(s); 60 | }, // 键盘回车键 61 | onChanged: seachTxtChanged, 62 | cursorWidth: 1.5, 63 | autofocus: true, 64 | cursorColor: KColorConstant.floorTitleColor, 65 | decoration: InputDecoration( 66 | contentPadding: EdgeInsets.all(0), 67 | hintText: KString.homeSearchBarHint, 68 | hintStyle: TextStyle(fontSize: 14), 69 | border: InputBorder.none), 70 | ), 71 | ) 72 | ], 73 | ), 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lib/widgets/bottombar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../utils/screen_util.dart'; 3 | import '../constants/index.dart'; 4 | class BottomAppBarItemModal { 5 | final IconData iconData; 6 | final String text; 7 | BottomAppBarItemModal(this.iconData, this.text); 8 | } 9 | 10 | class BottomAppBarItem extends StatelessWidget { 11 | final IconData iconData; 12 | final String text; 13 | final Color color; 14 | final ValueChanged onTabSeleted; 15 | final int index; 16 | BottomAppBarItem( 17 | this.iconData, this.text, this.color, this.onTabSeleted, this.index); 18 | @override 19 | Widget build(BuildContext context) { 20 | return GestureDetector( 21 | onTap: () => onTabSeleted(index), 22 | child: Column( 23 | mainAxisAlignment: MainAxisAlignment.center, 24 | children: [ 25 | Icon( 26 | iconData, 27 | color: color, 28 | ), 29 | Text( 30 | text, 31 | style: TextStyle(color: color), 32 | ) 33 | ], 34 | ), 35 | ); 36 | } 37 | } 38 | 39 | class KKBottomAppBar extends StatefulWidget { 40 | final List items; 41 | final ValueChanged onTabSeleted; 42 | final Color actviveColor; 43 | final Color color; 44 | KKBottomAppBar({this.items, this.onTabSeleted, this.actviveColor, this.color}) 45 | : super(); 46 | @override 47 | BottomAppBarState createState() => BottomAppBarState(); 48 | } 49 | 50 | class BottomAppBarState extends State { 51 | int currentIndex = 0; 52 | @override 53 | Widget build(BuildContext context) { 54 | int l = widget.items.length; 55 | // print(this.currentIndex); 56 | double bottom = ScreenUtil.bottomBarHeight; //IPhone 底部 57 | List listWidgets = List.generate(l, (index) { 58 | BottomAppBarItemModal i = widget.items[index]; 59 | return BottomAppBarItem( 60 | i.iconData, 61 | i.text, 62 | index == currentIndex ? widget.actviveColor : widget.color, 63 | onItemTap, 64 | index); 65 | }); 66 | return Container( 67 | height: Klength.bottomBarHeight, 68 | color: KColorConstant.bottomBarbgColor, 69 | alignment: Alignment.center, 70 | margin: EdgeInsets.only(bottom: bottom), 71 | child: Row( 72 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 73 | crossAxisAlignment: CrossAxisAlignment.center, 74 | children: listWidgets, 75 | ), 76 | ); 77 | } 78 | 79 | onItemTap(int i) { 80 | setState(()=>this.currentIndex=i); 81 | 82 | widget.onTabSeleted(i); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lib/model/userinfo.dart: -------------------------------------------------------------------------------- 1 | import '../globleConfig.dart'; 2 | 3 | class Userinfo { 4 | bool paywsd; 5 | String name; 6 | String acount; 7 | String id; 8 | String nickname; 9 | String avtar; 10 | String phone; 11 | String level; 12 | double point; 13 | num money; 14 | num jiangli; 15 | double frozen; 16 | double point_frozen; 17 | double point_locked; 18 | String levelname; 19 | String wallet_addr; 20 | Map json; 21 | 22 | Userinfo( 23 | {this.paywsd = false, 24 | this.acount, 25 | this.phone, 26 | this.id, 27 | this.name, 28 | this.nickname, 29 | this.avtar, 30 | this.level, 31 | this.levelname, 32 | this.point, 33 | this.money = 0.0, 34 | this.frozen = 0.0, 35 | this.point_frozen = 0.0, 36 | this.point_locked = 0.0, 37 | this.jiangli = 0.0, 38 | this.wallet_addr, 39 | this.json}); 40 | 41 | factory Userinfo.fromJson(Map json) { 42 | if (json == {} || json.length == 0) 43 | return Userinfo( 44 | phone: '18888888888', 45 | name: '新人驾到', 46 | acount: '88888888', 47 | id: "0", 48 | nickname: '新人驾到', 49 | avtar: GlobalConfig.server + 50 | '/public/images/icon_goods_thumb_empty_300.png', 51 | level: '1', 52 | money: 0.0, 53 | frozen: 0.0, 54 | jiangli: 0.0, 55 | point_locked: 0.0, 56 | point_frozen: 0.0, 57 | point: 0.0, 58 | levelname: '游客', 59 | wallet_addr: "", 60 | json: {}); 61 | else 62 | return Userinfo( 63 | paywsd: json['setpaywsd'].toString() != '' ? true : false, 64 | phone: json['phone'] ?? '18888888888', 65 | name: json['username'] ?? '新人驾到', 66 | acount: json['account']??"88888888", 67 | id: json['user_id'].toString()??"0", 68 | nickname: json['nickname'] ?? '新人驾到', 69 | avtar: json['avatar'] ?? 70 | GlobalConfig.server + 71 | '/public/images/icon_goods_thumb_empty_300.png', 72 | level: json['level'].toString() ?? '1', 73 | money: double.tryParse(json['money']) ?? 0.0, 74 | frozen: num.tryParse(json['frozen_money']) ?? 0.0, 75 | jiangli: num.tryParse(json['distribut_money']) ?? 0.0, 76 | point_locked: double.tryParse(json['points_locked']) ?? 0.0, 77 | point_frozen: double.tryParse(json['points_frozen']) ?? 0.0, 78 | point: double.tryParse(json['pay_points']) ?? 0.0, 79 | levelname: json['levelname'] ?? '游客', 80 | wallet_addr: json['wallet_addr'].toString(), 81 | json: json); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /lib/views/webView.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; 3 | import '../utils/DialogUtils.dart'; 4 | import '../globleConfig.dart'; 5 | 6 | class WebView extends StatefulWidget { 7 | final String articleUrl; 8 | final String title; 9 | 10 | WebView(this.title, this.articleUrl); 11 | 12 | @override 13 | _ArticleDetailState createState() => _ArticleDetailState(); 14 | } 15 | 16 | class _ArticleDetailState extends State { 17 | bool hasLoaded = false; 18 | final flutterWebViewPlugin = new FlutterWebviewPlugin(); 19 | 20 | @override 21 | void initState() { 22 | super.initState(); 23 | flutterWebViewPlugin.onStateChanged.listen((state) { 24 | if (state.type == WebViewState.finishLoad) { 25 | //有掘金web版本详情页的finished触发时间实在太长,所以这里就省略了hasLoaded的处理,其实也就是为了界面更友好 26 | print(state.type); 27 | hasLoaded = true; 28 | print("========2222========"); 29 | } 30 | }); 31 | 32 | } 33 | 34 | Future _requestPop() { 35 | Navigator.of(context).pop(100); 36 | ///弹出页面并传回int值100,用于上一个界面的回调 37 | return new Future.value(false); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) { 42 | return new WillPopScope( 43 | child: new WebviewScaffold( 44 | url: widget.articleUrl, 45 | /* appBar: new AppBar( 46 | // iconTheme: IconThemeData(color: Colors.white), 47 | backgroundColor: GlobalConfig.mainColor, 48 | title: new Text( 49 | widget.title, 50 | style: new TextStyle(color: Colors.white), 51 | ), 52 | ),*//* appBar: new AppBar( 53 | // iconTheme: IconThemeData(color: Colors.white), 54 | backgroundColor: GlobalConfig.mainColor, 55 | title: new Text( 56 | widget.title, 57 | style: new TextStyle(color: Colors.white), 58 | ), 59 | ),*/ 60 | withZoom: true, 61 | withLocalStorage: true, 62 | withJavascript: true, 63 | scrollBar: true, 64 | // enableAppScheme:true, 65 | geolocationEnabled: true, 66 | // resizeToAvoidBottomInset: true, 67 | initialChild: Container( 68 | color: Colors.white, 69 | child: Center( 70 | // child: Text('Waiting.....'), 71 | // child: Loading(color: Color(0xFFC9A063), size: 56.0), 72 | child: DialogUtils.uircularProgress(), 73 | ), 74 | ), 75 | ), 76 | onWillPop: _requestPop); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /lib/utils/cacheUtil.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/services.dart'; 5 | import 'package:path_provider/path_provider.dart'; 6 | 7 | class CacheUtil { 8 | ///格式化文件大小 9 | _renderSize(double value) { 10 | if (null == value) { 11 | return 0; 12 | } 13 | List unitArr = List() 14 | ..add('B') 15 | ..add('K') 16 | ..add('M') 17 | ..add('G'); 18 | int index = 0; 19 | while (value > 1024) { 20 | index++; 21 | value = value / 1024; 22 | } 23 | String size = value.toStringAsFixed(2); 24 | return size + unitArr[index]; 25 | } 26 | ///加载缓存 27 | Future loadCache() async { 28 | try { 29 | Directory tempDir = await getTemporaryDirectory(); 30 | double value = await _getTotalSizeOfFilesInDir(tempDir); 31 | /*tempDir.list(followLinks: false,recursive: true).listen((file){ 32 | //打印每个缓存文件的路径 33 | print(file.path); 34 | });*/ 35 | print('临时目录大小: ' + value.toString()); 36 | /* setState(() { 37 | _cacheSizeStr = _renderSize(value); 38 | });*/ 39 | } catch (err) { 40 | print(err); 41 | } 42 | } 43 | /// 递归方式 计算文件的大小 44 | Future _getTotalSizeOfFilesInDir(final FileSystemEntity file) async { 45 | try { 46 | if (file is File) { 47 | int length = await file.length(); 48 | return double.parse(length.toString()); 49 | } 50 | if (file is Directory) { 51 | final List children = file.listSync(); 52 | double total = 0; 53 | if (children != null) 54 | for (final FileSystemEntity child in children) 55 | total += await _getTotalSizeOfFilesInDir(child); 56 | return total; 57 | } 58 | return 0; 59 | } catch (e) { 60 | print(e); 61 | return 0; 62 | } 63 | } 64 | 65 | void _clearCache() async { 66 | //此处展示加载loading 67 | try { 68 | Directory tempDir = await getTemporaryDirectory(); 69 | //删除缓存目录 70 | await delDir(tempDir); 71 | await loadCache(); 72 | // ToastUtils.show(msg: '清除缓存成功'); 73 | } catch (e) { 74 | print(e); 75 | // ToastUtils.show(msg: '清除缓存失败'); 76 | } finally { 77 | //此处隐藏加载loading 78 | } 79 | } 80 | ///递归方式删除目录 81 | Future delDir(FileSystemEntity file) async { 82 | try { 83 | if (file is Directory) { 84 | final List children = file.listSync(); 85 | for (final FileSystemEntity child in children) { 86 | await delDir(child); 87 | } 88 | } 89 | await file.delete(); 90 | } catch (e) { 91 | print(e); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /lib/components/index_model_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../model/model_cell.dart'; 3 | import '../routers/application.dart'; 4 | import 'dart:core'; 5 | 6 | class IndexModelList extends StatelessWidget { 7 | IndexModelList(this.listData); 8 | final List listData ; 9 | // ,this.token String token; 10 | 11 | 12 | // IndexModelList({Key key, this.listData}) : super(key: key); 13 | 14 | List buildItemList( 15 | BuildContext context, 16 | ) { 17 | int number = listData.length; 18 | List widgetList = new List(); 19 | for (int i = 0; i < number; i++) { 20 | ModelCell item = listData[i]; 21 | widgetList.add(setItemWidget(context, item)); 22 | } 23 | return widgetList; 24 | } 25 | 26 | Widget setItemWidget(BuildContext context, ModelCell cellItem) { 27 | String txt = cellItem.modName; 28 | Container itemContainer = new Container( 29 | child: GestureDetector( 30 | child: new Column( 31 | mainAxisAlignment: MainAxisAlignment.center, 32 | mainAxisSize: MainAxisSize.max, 33 | crossAxisAlignment: CrossAxisAlignment.center, 34 | verticalDirection: VerticalDirection.down, 35 | children: [ 36 | Expanded( 37 | child: new Container( 38 | constraints: new BoxConstraints.expand(), 39 | decoration: new BoxDecoration( 40 | image: new DecorationImage( 41 | image: cellItem.modtype == '0' 42 | ? AssetImage('images/' + cellItem.iconname) 43 | : NetworkImage(cellItem.icon), 44 | // image: new NetworkImage('http://h.hiphotos.baidu.com/zhi6e06f06c.jpg'), 45 | // image: AssetImage('images/sysicon/icon_jilu.png'), 46 | ), 47 | ), 48 | ), 49 | ), 50 | Expanded(child: Text(txt)) 51 | ], 52 | ), 53 | /* onTap: () { 54 | Application.run(context, url);; 55 | },*/ 56 | ), 57 | ); 58 | 59 | return InkWell( 60 | onTap: () { 61 | if (cellItem.modtype == '0') { 62 | Application.run(context, cellItem.fluUrl); 63 | } else { 64 | Application.run(context, "/web",url: cellItem.url,title:txt); 65 | } 66 | }, 67 | child: itemContainer); 68 | } 69 | 70 | @override 71 | Widget build(BuildContext context) { 72 | return new Center( 73 | child: new GridView.count( 74 | crossAxisCount: 3, 75 | padding: const EdgeInsets.all(10.0), 76 | mainAxisSpacing: 0.0, 77 | crossAxisSpacing: 0.0, 78 | children: buildItemList(context), 79 | ), 80 | ); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/components/topbar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../constants/length.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | class HomeTopBar extends StatelessWidget { 5 | // This widget is the root of your application. 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | 10 | final double statusBarHeight = MediaQuery.of(context).padding.top; 11 | return Container( 12 | color: Colors.deepOrange, 13 | padding: EdgeInsets.only( 14 | top: statusBarHeight+6, left: 10, right: 10, bottom: 5), 15 | child: Row( 16 | children: [ 17 | Icon( 18 | Icons.settings_overscan, 19 | size: 22.0, 20 | color:Colors.white70,// Color.fromRGBO(132, 95, 63, 1.0), 21 | ), 22 | Expanded( 23 | flex: 1, 24 | child: GestureDetector( 25 | onTap: () { 26 | /* Navigator.push(context,CupertinoPageRoute(builder: (BuildContext context){ 27 | ;//return SearchPage(); 28 | }));*/ 29 | }, 30 | child: Container( 31 | height: Klength.topBarHeight, 32 | padding: EdgeInsets.all(5.0), 33 | // color: Color.fromRGBO(238, 238, 238, 0.5), 34 | decoration: BoxDecoration( 35 | color: Color.fromRGBO(238, 238, 238, 0.5), 36 | // border: Border.all(color: Colors.black45, width: 1.0), 37 | borderRadius: BorderRadius.circular(20.0)), 38 | child: Row( 39 | children: [ 40 | Container( 41 | margin: EdgeInsets.only(right: 5), 42 | child: Icon( 43 | Icons.search, 44 | color: Color(0xFF979797), 45 | size: 20, 46 | ), 47 | ), 48 | Text( 49 | "搜索", 50 | style: TextStyle( 51 | fontSize: 12.0, 52 | color: Color(0xFF979797), 53 | fontWeight: FontWeight.w500, 54 | decoration: TextDecoration.none, 55 | ), 56 | ), 57 | ], 58 | ), 59 | )), 60 | ), 61 | Container( 62 | margin: EdgeInsets.only(left: 6.0), 63 | child: Icon( 64 | Icons.account_balance_wallet, 65 | size: 22.0, 66 | color:Colors.white70,// Color.fromRGBO(132, 95, 63, 1.0), 67 | ), 68 | ) 69 | ], 70 | ), 71 | ); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /lib/utils/screen_util.dart: -------------------------------------------------------------------------------- 1 | // from github https://github.com/OpenFlutter/flutter_ScreenUtil/blob/master/lib/flutter_screenutil.dart 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class ScreenUtil { 6 | static ScreenUtil instance = new ScreenUtil(); 7 | 8 | //设计稿的设备尺寸修改 9 | double _designWidth; 10 | double _designHeight; 11 | 12 | static MediaQueryData _mediaQueryData; 13 | static double _screenWidth; 14 | static double _screenHeight; 15 | static double _pixelRatio; 16 | static double _statusBarHeight; 17 | 18 | static double _bottomBarHeight; 19 | 20 | static double _textScaleFactor; 21 | 22 | ScreenUtil({double width, double height}) { 23 | _designWidth = width; 24 | _designHeight = height; 25 | } 26 | 27 | static ScreenUtil getInstance() { 28 | return instance; 29 | } 30 | 31 | void init(BuildContext context) { 32 | MediaQueryData mediaQuery = MediaQuery.of(context); 33 | _mediaQueryData = mediaQuery; 34 | _pixelRatio = mediaQuery.devicePixelRatio; 35 | _screenWidth = mediaQuery.size.width; 36 | _screenHeight = mediaQuery.size.height; 37 | _statusBarHeight = mediaQuery.padding.top; 38 | _bottomBarHeight = _mediaQueryData.padding.bottom; 39 | _textScaleFactor = mediaQuery.textScaleFactor; 40 | 41 | } 42 | 43 | static MediaQueryData get mediaQueryData => _mediaQueryData; 44 | 45 | ///每个逻辑像素的字体像素数,字体的缩放比例 46 | static double get textScaleFactory => _textScaleFactor; 47 | 48 | ///设备的像素密度 49 | static double get pixelRatio => _pixelRatio; 50 | 51 | ///当前设备宽度 dp 52 | static double get screenWidthDp => _screenWidth; 53 | 54 | ///当前设备高度 dp 55 | static double get screenHeightDp => _screenHeight; 56 | 57 | ///当前设备宽度 px 58 | static double get screenWidth => _screenWidth; 59 | ///当前设备高度 px 60 | static double get screenHeight => _screenHeight; 61 | 62 | ///状态栏高度 刘海屏会更高 63 | static double get statusBarHeight => _statusBarHeight; 64 | 65 | ///底部安全区距离 66 | static double get bottomBarHeight => _bottomBarHeight; 67 | 68 | ///实际的dp与设计稿px的比例 69 | get scaleWidth => _screenWidth / instance._designWidth; 70 | 71 | get scaleHeight => _screenHeight / instance._designHeight; 72 | 73 | ///根据设计稿的设备宽度适配 74 | ///高度也根据这个来做适配可以保证不变形 75 | setWidth(int width) => width * scaleWidth; 76 | ///根据设计稿的设备宽度适配 77 | ///高度也根据这个来做适配可以保证不变形 78 | L(int width) => this.setWidth(width); 79 | H(int height) => this.setHeight(height); 80 | /// 根据设计稿的设备高度适配 81 | /// 当发现设计稿中的一屏显示的与当前样式效果不符合时, 82 | /// 或者形状有差异时,高度适配建议使用此方法 83 | /// 高度适配主要针对想根据设计稿的一屏展示一样的效果 84 | setHeight(int height) => height * scaleHeight; 85 | 86 | ///字体大小适配方法 87 | ///@param fontSize 传入设计稿上字体的px , 88 | ///@param allowFontScaling 控制字体是否要根据系统的“字体大小”辅助选项来进行缩放。默认值为true。 89 | ///@param allowFontScaling Specifies whether fonts should scale to respect Text Size accessibility settings. The default is true. 90 | setSp(int fontSize, [allowFontScaling = true]) => allowFontScaling 91 | ? setWidth(fontSize) * _textScaleFactor 92 | : setWidth(fontSize); 93 | } -------------------------------------------------------------------------------- /lib/model/pood/video_detail_model.dart: -------------------------------------------------------------------------------- 1 | /** 2 | * 视频详情 3 | * Create by Songlcy 4 | */ 5 | 6 | class VideoDetailModel { 7 | // { 8 | // "classify": { 9 | // "_id": "5b1fdbee30025ae5371ac363", 10 | // "name": "动漫" 11 | // }, 12 | // "director": ["濑藤健嗣"], 13 | // "favorited": false, 14 | // "favorited_count": 0, 15 | // "introduce": "本作是由东映动画、万代、小学馆共同发起的新企划,预定进行动画、漫画、玩具等多媒体展开。动画将于10月推出。", 16 | // "keyword": "爆钓BARHUNTER濑藤健嗣广桥凉内山夕实斋贺光希根本幸多baodiaoBARHUNTERlaitengjiansiguangqiaoliangneishanxishizhaiheguangxigenbenxingduobdBARHUNTERltjsgqlnsxszhgxgbxd", 17 | // "latest": "更新到16集", 18 | // "name": "爆钓BARHUNTER", 19 | // "number": 19, 20 | // "region": "日本", 21 | // "released_at": "2018", 22 | // "remote_url": [{ 23 | // "tag": "第01集", 24 | // "url": "https://youku163.zuida-bofang.com/20181002/16132_d52aa48b/index.m3u8" 25 | // }], 26 | // "running_time": 0, 27 | // "source": "zuidazy", 28 | // "starring": ["广桥凉", "内山夕实", "斋贺光希", "根本幸多"], 29 | // "thumbnail": "https://tupian.tupianzy.com/pic/upload/vod/2018-10-02/201810021538485416.jpg" 30 | // } 31 | 32 | Classify classify; 33 | List director; 34 | bool favorited; 35 | int favoritedCount; 36 | String introduce; 37 | String keyword; 38 | String name; 39 | String region; 40 | List remoteUrl; 41 | List starring; 42 | String releasedAt; 43 | String thumbnail; 44 | 45 | VideoDetailModel({ 46 | this.classify, 47 | this.director, 48 | this.favorited, 49 | this.favoritedCount, 50 | this.introduce, 51 | this.keyword, 52 | this.name, 53 | this.region, 54 | this.remoteUrl, 55 | this.starring, 56 | this.releasedAt, 57 | this.thumbnail 58 | }); 59 | 60 | factory VideoDetailModel.fromJson(Map jsonObj) { 61 | 62 | return VideoDetailModel( 63 | classify: Classify.fromJson(jsonObj["classify"]), 64 | director: jsonObj["director"], 65 | favorited: jsonObj["favorited"], 66 | favoritedCount: jsonObj["favoritedCount"], 67 | introduce: jsonObj["introduce"], 68 | keyword: jsonObj["keyword"], 69 | name: jsonObj["name"], 70 | region: jsonObj["region"], 71 | remoteUrl: (jsonObj["remote_url"] as List).map((item) => RemoteUrl.fromJson(item)).toList(), 72 | starring: jsonObj["starring"], 73 | releasedAt: jsonObj["released_at"], 74 | thumbnail: jsonObj["thumbnail"] 75 | ); 76 | } 77 | } 78 | class Classify { 79 | 80 | String id; 81 | String name; 82 | 83 | Classify({ this.id, this.name }); 84 | 85 | factory Classify.fromJson(Map jsonObj) { 86 | return Classify(id:jsonObj["_id"], name: jsonObj["name"]); 87 | } 88 | } 89 | 90 | class RemoteUrl { 91 | 92 | String tag; 93 | String url; 94 | 95 | RemoteUrl({ this.tag, this.url }); 96 | 97 | factory RemoteUrl.fromJson(Map jsonObj) { 98 | return RemoteUrl(tag: jsonObj["tag"], url: jsonObj["url"]); 99 | } 100 | } -------------------------------------------------------------------------------- /lib/views/person/tempdemo_list.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/cupertino.dart'; 3 | import '../../utils/HttpUtils.dart'; 4 | import '../../model/paylog_model.dart'; 5 | 6 | class DemolistPage extends StatefulWidget { 7 | @override 8 | _MyHomePageState createState() => new _MyHomePageState(); 9 | } 10 | 11 | class _MyHomePageState extends State { 12 | List list = new List(); //列表要展示的数据 13 | ScrollController _scrollController = ScrollController(); //listview的控制器 14 | int _page = 1; //加载的页数 15 | bool isLoading = false; //是否正在加载数据 16 | 17 | @override 18 | void initState() { 19 | // TODO: implement initState 20 | super.initState(); 21 | getData(); 22 | _scrollController.addListener(() { 23 | if (_scrollController.position.pixels == 24 | _scrollController.position.maxScrollExtent) { 25 | print('滑动到了最底部'); 26 | _getMore(); 27 | } 28 | }); 29 | } 30 | 31 | /** 32 | * 初始化list数据 加延时模仿网络请求 33 | */ 34 | Future getData() async { 35 | await Future.delayed(Duration(seconds: 2), () { 36 | setState(() { 37 | list = List.generate(15, (i) => '哈喽,我是原始数据 $i'); 38 | }); 39 | }); 40 | } 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | return new Scaffold( 45 | appBar: new AppBar( 46 | // Here we take the value from the MyHomePage object that was created by 47 | // the App.build method, and use it to set our appbar title. 48 | title: new Text("ddfdf"), 49 | ), 50 | body: RefreshIndicator( 51 | onRefresh: _onRefresh, 52 | child: ListView.builder( 53 | itemBuilder: _renderRow, 54 | itemCount: list.length, 55 | controller: _scrollController, 56 | ), 57 | ), 58 | // This trailing comma makes auto-formatting nicer for build methods. 59 | ); 60 | } 61 | 62 | Widget _renderRow(BuildContext context, int index) { 63 | return ListTile( 64 | title: Text(list[index]), 65 | ); 66 | } 67 | 68 | /** 69 | * 下拉刷新方法,为list重新赋值 70 | */ 71 | Future _onRefresh() async { 72 | await Future.delayed(Duration(seconds: 3), () { 73 | print('refresh'); 74 | setState(() { 75 | list = List.generate(20, (i) => '哈喽,我是新刷新的 $i'); 76 | }); 77 | }); 78 | } 79 | 80 | /** 81 | * 上拉加载更多 82 | */ 83 | Future _getMore() async { 84 | if (!isLoading) { 85 | setState(() { 86 | isLoading = true; 87 | }); 88 | await Future.delayed(Duration(seconds: 1), () { 89 | print('加载更多'); 90 | setState(() { 91 | list.addAll(List.generate(5, (i) => '第$_page次上拉来的数据')); 92 | _page++; 93 | isLoading = false; 94 | }); 95 | }); 96 | } 97 | } 98 | 99 | @override 100 | void dispose() { 101 | // TODO: implement dispose 102 | super.dispose(); 103 | _scrollController.dispose(); 104 | } 105 | } -------------------------------------------------------------------------------- /lib/video/demo_video_player.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:video_player/video_player.dart'; 3 | //import 'package:chewie/chewie.dart'; 4 | 5 | class video_player_demo extends StatefulWidget { 6 | @override 7 | video_player_demoState createState() => new video_player_demoState(); 8 | } 9 | 10 | class video_player_demoState extends State { 11 | 12 | VideoPlayerController _controller; 13 | bool _isPlaying = false; 14 | String url = 'https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4'; 15 | 16 | @override 17 | void initState() { 18 | super.initState(); 19 | _controller = VideoPlayerController.network(this.url) 20 | // 播放状态 21 | ..addListener(() { 22 | final bool isPlaying = _controller.value.isPlaying; 23 | if (isPlaying != _isPlaying) { 24 | setState(() { _isPlaying = isPlaying; }); 25 | } 26 | }) 27 | // 在初始化完成后必须更新界面 28 | ..initialize().then((_) { 29 | setState(() {}); 30 | }); 31 | } 32 | 33 | @override 34 | Widget build(BuildContext context) { 35 | return MaterialApp( 36 | title: 'Video Demo', 37 | home: new Scaffold( 38 | /* body: Center( 39 | child: new Chewie(new VideoPlayerController.network(this.url), 40 | aspectRatio: 16 / 9, 41 | autoPlay: !true, 42 | looping: true, 43 | showControls: true, 44 | // 占位图 45 | placeholder: new Container( 46 | color: Colors.grey, 47 | ), 48 | // 是否在 UI 构建的时候就加载视频 49 | autoInitialize: !true, 50 | 51 | // 拖动条样式颜色 52 | materialProgressColors: new ChewieProgressColors( 53 | playedColor: Colors.red, 54 | handleColor: Colors.blue, 55 | backgroundColor: Colors.grey, 56 | bufferedColor: Colors.lightGreen, 57 | ), 58 | ), 59 | ),*/ 60 | body: new Center( 61 | child: _controller.value.initialized 62 | // 加载成功 63 | ? new AspectRatio( 64 | aspectRatio: _controller.value.aspectRatio, 65 | child: VideoPlayer(_controller), 66 | ) : new Container(), 67 | ), 68 | floatingActionButton: new FloatingActionButton( 69 | onPressed: _controller.value.isPlaying 70 | ? _controller.pause 71 | : _controller.play, 72 | child: new Icon( 73 | _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, 74 | ), 75 | ), 76 | ), 77 | ); 78 | } 79 | 80 | @override 81 | void dispose() { 82 | // TODO: implement dispose 83 | super.dispose(); 84 | } 85 | 86 | @override 87 | void didUpdateWidget(video_player_demo oldWidget) { 88 | // TODO: implement didUpdateWidget 89 | super.didUpdateWidget(oldWidget); 90 | } 91 | 92 | @override 93 | void didChangeDependencies() { 94 | // TODO: implement didChangeDependencies 95 | super.didChangeDependencies(); 96 | } 97 | } -------------------------------------------------------------------------------- /lib/views/details/details_explain.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../utils/screen_util.dart'; 3 | import '../../model/goods.dart'; 4 | import '../../model/globle_model.dart'; 5 | import '../../globleConfig.dart'; 6 | 7 | class DetailsExplain extends StatelessWidget { 8 | final GoodInfo goodsInfo ; 9 | DetailsExplain(this.goodsInfo); 10 | double _width=ScreenUtil.screenWidth; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | if (this.goodsInfo != null) { 15 | return Padding( 16 | padding: const EdgeInsets.all(8.0), 17 | child: Card( 18 | // This ensures that the Card's children are clipped correctly. 19 | clipBehavior: Clip.antiAlias, 20 | shape: GlobalConfig.cardBorderRadius, //, 21 | elevation: 5.0, 22 | child: Padding( 23 | padding: const EdgeInsets.all(15.0), 24 | child: Column( 25 | mainAxisAlignment: MainAxisAlignment.start, 26 | children: [ 27 | goodsName(this.goodsInfo.goodsName), 28 | goodsPrice(this.goodsInfo.presentPrice, this.goodsInfo.oriPrice), 29 | goodsNumber(this.goodsInfo), 30 | ], 31 | ),)) 32 | ); 33 | } else { 34 | return Container( 35 | child: Text('正在加载中......'), 36 | ); 37 | } 38 | } 39 | /// 商品详情页的名称 40 | Widget goodsName(name) { 41 | return Container( 42 | width: _width, 43 | padding: EdgeInsets.only(left: 15), 44 | child: Text( 45 | name, 46 | style: KfontConstant.defaultStyle, 47 | ), 48 | ); 49 | } 50 | 51 | /// 商品详情页的编号 52 | Widget goodsNumber(GoodInfo goods) { 53 | return Container( 54 | width: _width, 55 | padding: EdgeInsets.only(left: 15), 56 | margin: EdgeInsets.only(top: 8), 57 | child: Text( 58 | '编号:${goods.goodsSerialNumber.toString()},库存:${goods.amount.toString()}', 59 | style: TextStyle( 60 | fontSize: ScreenUtil().setSp(14), 61 | color: Colors.black12, 62 | ), 63 | ), 64 | ); 65 | } 66 | 67 | /// 商品详情页的价格页面 68 | Widget goodsPrice(oldPrice, newPrice) { 69 | return Container( 70 | child: Row( 71 | children: [ 72 | Text( 73 | '¥${oldPrice}', 74 | style: KfontConstant.defaultPriceStyle, 75 | ), 76 | Container( 77 | padding: EdgeInsets.only(left: 15), 78 | child: RichText( 79 | text: TextSpan( 80 | text: '市场价:', 81 | style: TextStyle(color: Colors.black45), 82 | children: [ 83 | TextSpan( 84 | text: '¥${newPrice}', 85 | style: TextStyle( 86 | decoration: TextDecoration.lineThrough, 87 | color: Colors.black12), 88 | ), 89 | ]), 90 | ), 91 | ), 92 | ], 93 | ), 94 | padding: EdgeInsets.only(left: 15, top: 10), 95 | ); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /lib/views/message_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'dart:math' as math; 3 | import '../globleConfig.dart'; 4 | 5 | class MessagePage extends StatefulWidget { 6 | MessagePageState createState() => MessagePageState(); 7 | } 8 | 9 | class MessagePageState extends State with SingleTickerProviderStateMixin { 10 | TabController _tabController; 11 | 12 | double _width = GlobalConfig.cardWidth; 13 | ShapeBorder _shape = GlobalConfig.cardBorderRadius; 14 | 15 | void _initdata() {;} 16 | 17 | @override 18 | void initState() { 19 | super.initState(); 20 | _initdata(); 21 | } 22 | 23 | @override 24 | void dispose() { 25 | super.dispose(); 26 | } 27 | 28 | @override 29 | Widget build(BuildContext context) { 30 | 31 | const List choices = const [ 32 | const msgChoice( 33 | title: '消息', 34 | categoryId: 0, 35 | ), 36 | const msgChoice( 37 | title: '通知', 38 | categoryId: 1, 39 | ), 40 | const msgChoice( 41 | title: '活动', 42 | categoryId: 2, 43 | ) 44 | ]; 45 | 46 | 47 | return DefaultTabController( 48 | length: choices.length, 49 | initialIndex: 0, //初始索引 50 | child: Scaffold( 51 | appBar: AppBar( 52 | title: Text('消息通知'), 53 | bottom: TabBar( 54 | // isScrollable: true, //这个属性是导航栏是否支持滚动,false则会挤在一起了 55 | unselectedLabelColor: Colors.white, //未选标签标签的颜色(这里定义为灰色) 56 | labelColor: Colors.grey, //选中的颜色(黑色) 57 | indicatorColor: Colors.grey, //指示器颜色 58 | indicatorWeight: 2.0, //指示器厚度 59 | tabs: [ 60 | Tab( 61 | icon: Icon(Icons.message), 62 | text: "消息", 63 | ), 64 | Tab( 65 | icon: Icon(Icons.info), 66 | text: "通知", 67 | ), 68 | Tab( 69 | icon: Icon(Icons.local_play), 70 | text: '活动', 71 | ), 72 | ]), 73 | ), 74 | body: TabBarView( 75 | children: choices.map((msgChoice choice) { 76 | return SizedBox( 77 | height: 70, 78 | width: _width, 79 | child: Card( 80 | clipBehavior: Clip.antiAlias, 81 | shape: _shape, 82 | child: ListTile( 83 | title: Text(choice.title), 84 | subtitle: new Text("抗震压包装,安全到家---"+choice.title), 85 | trailing: Icon(Icons.done,color: Colors.red,) 86 | // Image.asset('images/express.png',width: 40.0, height: 40.0)) 87 | ))); 88 | //一个属于展示内容的listview 89 | }).toList(), 90 | ), 91 | ), 92 | ); 93 | 94 | } 95 | 96 | } 97 | 98 | class msgChoice { 99 | const msgChoice({this.title, this.categoryId}); 100 | 101 | final String title; //这个参数是分类名称 102 | final int categoryId; //这个适用于网络请求的参数,获取不同分类列表 103 | } 104 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/video/player.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../utils/fiexdAppbar.dart'; 3 | import 'package:video_player/video_player.dart'; 4 | import 'chewie_list_item.dart'; 5 | import 'tx_video_player.dart'; 6 | import 'video_web.dart'; 7 | import 'audioPlayerWithTxt.dart'; 8 | import 'audioplayer.dart'; 9 | 10 | class xiePlayer extends StatefulWidget { 11 | final String url; 12 | final Map video; 13 | final String type; 14 | final String vdhtml; 15 | 16 | xiePlayer( 17 | {this.type = 'mp4', 18 | this.video, 19 | this.url = 20 | "http://200024424.vod.myqcloud.com/200024424_709ae516bdf811e6ad39991f76a4df69.f20.mp4", 21 | this.vdhtml=''}); 22 | @override 23 | PlayerState createState() => new PlayerState(); 24 | } 25 | 26 | class PlayerState extends State { 27 | VideoPlayerController _controller; 28 | bool _isPlaying = false; 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | final Color bkgColor = Color.fromARGB(255, 237, 88, 84); 33 | var topBar = new Container( 34 | child: toplay(), //注意:加入了child,AppBar的高度会是Container的实际高度,而不是你指定的高度 35 | color: Colors.blue, 36 | ); 37 | return Scaffold( 38 | appBar: new FiexdAppbar( 39 | contentChild: topBar, 40 | contentHeight: 250.0, 41 | statusBarColor: bkgColor, 42 | ), 43 | body: mainwt(), 44 | ); 45 | } 46 | 47 | Widget toplay() { 48 | String url = widget.url; 49 | if (widget.type == 'mp4') 50 | return TxVideoPlayer(url); 51 | else if (widget.type == 'mp3') 52 | return AudioPlayerWuthTxt(url: url,video: widget.video,); 53 | // return AudioApp(url: url); 54 | else if (widget.type == 'web') 55 | return VideoWebPlayer(url); 56 | else 57 | return ChewieListItem( 58 | videoPlayerController: VideoPlayerController.network( 59 | url, 60 | ), 61 | ); 62 | } 63 | 64 | Widget mainwt() { 65 | return ListView( 66 | children: [ 67 | Text("暂无简介"), 68 | Text("暂无相关"), 69 | ], 70 | ); 71 | } 72 | 73 | @override 74 | void initState() { 75 | // TODO: implement initState 76 | super.initState(); 77 | _controller = VideoPlayerController.network(widget.url) 78 | // 播放状态 79 | ..addListener(() { 80 | final bool isPlaying = _controller.value.isPlaying; 81 | if (isPlaying != _isPlaying) { 82 | setState(() { 83 | _isPlaying = isPlaying; 84 | }); 85 | } 86 | }) 87 | // 在初始化完成后必须更新界面 88 | ..initialize().then((_) { 89 | setState(() {}); 90 | }); 91 | } 92 | 93 | @override 94 | void dispose() { 95 | // TODO: implement dispose 96 | super.dispose(); 97 | } 98 | 99 | @override 100 | void didUpdateWidget(xiePlayer oldWidget) { 101 | // TODO: implement didUpdateWidget 102 | super.didUpdateWidget(oldWidget); 103 | } 104 | 105 | @override 106 | void didChangeDependencies() { 107 | // TODO: implement didChangeDependencies 108 | super.didChangeDependencies(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /lib/SplashScreen.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:shared_preferences/shared_preferences.dart'; 3 | import 'package:intro_slider/intro_slider.dart'; 4 | import 'package:intro_slider/slide_object.dart'; 5 | import 'homePage.dart'; 6 | 7 | class SplashScreen extends StatefulWidget { 8 | @override 9 | State createState() { 10 | return new SplashScreenState() ; 11 | } 12 | } 13 | class SplashScreenState extends State { 14 | List slides = new List(); 15 | @override 16 | void initState() { 17 | super.initState(); 18 | slides.add( 19 | new Slide( 20 | title: "Flutter", 21 | description: 22 | "Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。", 23 | styleDescription: TextStyle( 24 | color: Colors.white, 25 | fontSize: 20.0, 26 | fontFamily: 'Raleway'), 27 | marginDescription: EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0, bottom: 70.0), 28 | colorBegin: Color(0xffFFDAB9), 29 | colorEnd: Color(0xff40E0D0), 30 | directionColorBegin: Alignment.topLeft, 31 | directionColorEnd: Alignment.bottomRight, 32 | ), 33 | ); 34 | slides.add( 35 | new Slide( 36 | title: "Wanandroid", 37 | description: 38 | "这是一款使用Flutter写的WanAndroid客户端应用,在Android和IOS都完美运行,可以用来入门Flutter,简单明了,适合初学者,项目完全开源,如果本项目确实能够帮助到你学习Flutter,谢谢start,有问题请提交Issues,我会及时回复。", 39 | styleDescription: TextStyle( 40 | color: Colors.white, 41 | fontSize: 20.0, 42 | fontFamily: 'Raleway'), 43 | marginDescription: EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0, bottom: 70.0), 44 | colorBegin: Color(0xffFFFACD), 45 | colorEnd: Color(0xffFF6347), 46 | directionColorBegin: Alignment.topLeft, 47 | directionColorEnd: Alignment.bottomRight, 48 | ), 49 | ); 50 | slides.add( 51 | new Slide( 52 | title: "Welcome", 53 | description: 54 | "赠人玫瑰,手有余香;\n分享技术,传递快乐。", 55 | styleDescription: TextStyle( 56 | color: Colors.white, 57 | fontSize: 20.0, 58 | fontFamily: 'Raleway'), 59 | marginDescription: EdgeInsets.only(left: 20.0, right: 20.0, top: 20.0, bottom: 70.0), 60 | colorBegin: Color(0xffFFA500), 61 | colorEnd: Color(0xff7FFFD4), 62 | directionColorBegin: Alignment.topLeft, 63 | directionColorEnd: Alignment.bottomRight, 64 | ), 65 | ); 66 | } 67 | void onDonePress() { 68 | _setHasSkip(); 69 | Navigator.of(context).pushAndRemoveUntil( 70 | new MaterialPageRoute( 71 | builder: (context) => App()), 72 | (route) => route == null); 73 | } 74 | void _setHasSkip ()async { 75 | SharedPreferences prefs = await SharedPreferences.getInstance(); 76 | await prefs.setBool("hasSkip", true); 77 | } 78 | @override 79 | Widget build(BuildContext context) { 80 | return IntroSlider( 81 | slides: this.slides, 82 | onDonePress: this.onDonePress, 83 | nameSkipBtn: "跳过", 84 | nameNextBtn: "下一页", 85 | nameDoneBtn: "进入", 86 | ); 87 | } 88 | } -------------------------------------------------------------------------------- /lib/views/player/audio_tool.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:audioplayers/audioplayers.dart'; 3 | import '../../model/song.dart'; 4 | import 'package:rxdart/rxdart.dart'; 5 | 6 | enum AudioToolsState { 7 | beginPlay, 8 | isPlaying, 9 | isPaued, 10 | isCacheing, 11 | isStoped, 12 | isEnd, 13 | isError 14 | } 15 | 16 | class AudioTools { 17 | AudioPlayer audioPlayer = new AudioPlayer(); 18 | final stateSubject = new BehaviorSubject.seeded(AudioToolsState.isStoped); 19 | final progressSubject = new BehaviorSubject.seeded(0); 20 | final durationSubject = new BehaviorSubject.seeded(0); 21 | 22 | AudioTools() { 23 | AudioPlayer.logEnabled = false; 24 | audioPlayer.onDurationChanged.listen((Duration d) { 25 | // print('Max duration: $d'); 26 | this.durationSubject.value = d.inSeconds; 27 | }); 28 | audioPlayer.onAudioPositionChanged.listen((Duration p) { 29 | this.progressSubject.value =p.inMilliseconds;// p.inSeconds; 30 | if (p.inMilliseconds <= 200) { 31 | setPlayerState(AudioToolsState.isPlaying); 32 | } 33 | }); 34 | audioPlayer.onPlayerStateChanged.listen((AudioPlayerState s) { 35 | print('Current player state: $s'); 36 | if (s == AudioPlayerState.PAUSED) { 37 | setPlayerState(AudioToolsState.isPaued); 38 | } 39 | if (s == AudioPlayerState.STOPPED) { 40 | setPlayerState(AudioToolsState.isStoped); 41 | } 42 | }); 43 | audioPlayer.onPlayerCompletion.listen((event) { 44 | print('onPlayerCompletion'); 45 | setPlayerState(AudioToolsState.isEnd); 46 | }); 47 | audioPlayer.onPlayerError.listen((msg) { 48 | print('audioPlayer error : $msg'); 49 | setPlayerState(AudioToolsState.isError); 50 | }); 51 | } 52 | /// 播放 53 | Future play(String songurl,{isloclal=false}) async { 54 | if (audioPlayer.state != AudioPlayerState.STOPPED) { 55 | await audioPlayer.stop(); 56 | } 57 | 58 | audioPlayer.play(songurl,isLocal: isloclal).then((value) { 59 | if (value == 1) { 60 | setPlayerState(AudioToolsState.beginPlay); 61 | } else { 62 | } 63 | return value; 64 | }); 65 | } 66 | /// 暂停 67 | Future pause() async { 68 | audioPlayer.pause().then((value) { 69 | if (value == 1) { 70 | 71 | } else { 72 | 73 | } 74 | return value; 75 | }); 76 | } 77 | Future seek(int value) async { 78 | Duration d = Duration(seconds: value); 79 | audioPlayer.seek(d).then((value) { 80 | if (value == 1) { 81 | 82 | } else { 83 | 84 | } 85 | return value; 86 | }); 87 | } 88 | /// resume 89 | Future resume() async { 90 | audioPlayer.resume().then((value) { 91 | if (value == 1) { 92 | setPlayerState(AudioToolsState.isPlaying); 93 | } else { 94 | 95 | } 96 | return value; 97 | }); 98 | } 99 | /// 停止 100 | Future stop() async { 101 | audioPlayer.stop().then((value) { 102 | if (value == 1) { 103 | 104 | } else { 105 | 106 | } 107 | return value; 108 | }); 109 | } 110 | 111 | setPlayerState(AudioToolsState state) { 112 | stateSubject.value = state; 113 | } 114 | } -------------------------------------------------------------------------------- /lib/views/details/Details_bottom.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import '../../model/goods.dart'; 3 | import '../../utils/screen_util.dart'; 4 | 5 | class DetailsBottom extends StatelessWidget { 6 | @override 7 | Widget build(BuildContext context) { 8 | GoodInfo goodsInfo = null; 9 | 10 | var goodsCount = 3;//val.allGoodsCount; //购物车中数量 11 | return Container( 12 | width: ScreenUtil.screenWidth, 13 | height: ScreenUtil().L(60), 14 | color: Colors.white, 15 | child: Row( 16 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 17 | children: [ 18 | Stack( 19 | children: [ 20 | InkWell( 21 | onTap: () { 22 | Navigator.pop(context); 23 | }, 24 | child: Container( 25 | width: ScreenUtil().L(80), 26 | alignment: Alignment.center, 27 | child: Icon( 28 | Icons.shopping_cart, 29 | size: 35, 30 | color: Colors.red, 31 | ), 32 | ), 33 | ), 34 | 35 | Positioned( 36 | top: 0, 37 | right: 10, 38 | child: Container( 39 | padding: EdgeInsets.fromLTRB(6, 3, 6, 3), 40 | decoration: BoxDecoration( 41 | color: Colors.pink, 42 | border: Border.all(width: 2, color: Colors.white), 43 | borderRadius: BorderRadius.circular(12), 44 | ), 45 | child: Text( 46 | '${goodsCount}', 47 | style: TextStyle( 48 | color: Colors.white, 49 | fontSize: ScreenUtil().setSp(12),), 50 | ), 51 | ), 52 | ) 53 | 54 | ], 55 | ), 56 | Expanded(child:InkWell( 57 | onTap: () async { 58 | /* await Provide.value(context) 59 | .save(goodsId, goodsName, count, price, images);*/ 60 | }, 61 | child: Container( 62 | alignment: Alignment.center, 63 | color: Colors.green, 64 | child: Text( 65 | '加入购物车', 66 | style: TextStyle( 67 | color: Colors.white, fontSize: ScreenUtil().setSp(16)), 68 | ), 69 | // width: ScreenUtil().L(120), 70 | // height: ScreenUtil().L(80), 71 | ), 72 | ) ) 73 | , 74 | Expanded(child: InkWell( 75 | onTap: () async { 76 | /* await Provide.value(context).remove();*/ 77 | }, 78 | child: Container( 79 | alignment: Alignment.center, 80 | color: Colors.red, 81 | child: Text( 82 | '立即购买', 83 | style: TextStyle( 84 | color: Colors.white, fontSize: ScreenUtil().setSp(16)), 85 | ), 86 | // width: ScreenUtil().L(320), 87 | // height: ScreenUtil().L(80), 88 | ), 89 | ) 90 | ), 91 | ], 92 | ), 93 | ); 94 | } 95 | } 96 | --------------------------------------------------------------------------------