import 'dart:convert'; import 'dart:io'; import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_module/utils/ui_utils.dart'; import 'package:flutter_swiper_null_safety/flutter_swiper_null_safety.dart'; import '../../ui/widget/ad_express.dart'; import '../../ui/widget/refresh_listview.dart'; import '../../utils/ad_util.dart'; import '../../utils/pageutils.dart'; import '../../utils/ui_constant.dart'; import '../../model/video/home_type_model.dart'; import '../../model/video/search_special_model.dart'; import 'api/video_api.dart'; import 'model/video/home_ad_model.dart'; import 'ui/widget/video_item.dart'; import 'utils/jump_page.dart'; class HomePage extends StatefulWidget { HomePage({Key? key, required this.title}) : super(key: key); final String title; @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State with SingleTickerProviderStateMixin { final MyRefreshController _refreshController = MyRefreshController(initialRefresh: false); List bannerList = []; List homeTypeList = []; int page = 1; int totalCount = 0; List categoryList = []; bool hasDYHot = true; String searchKw = ""; //信息流广告 Widget? expressAd; AdType? expressAdType; String? expressPid; ExpressAdController _expressAdController = ExpressAdController(); @override void initState() { super.initState(); init(); AdUtil.getAdType(AdPosition.other).then((value) { setState(() { expressAdType = value; }); if (expressAdType == AdType.csj) { expressPid = CSJADConstant.PID_RECOMMEND_BIG_PICTURE; } else if (expressAdType == AdType.gdt) { expressPid = GDTADConstant.PID_RECOMMEND_BIG_PICTURE; } }); // Future.delayed(Duration(seconds: 5),(){ uiMethodChannel.invokeMethod("setStatusBarLight"); // }); } void init() { getHomeAd(); getHomeType(page); getSearchSpecial(); getHotSearch(); //刷新 _expressAdController.refresh; } void jumpPage(String name, dynamic params) { JumpPageUtil.jumpPage(name, context, params: params, native: true, callback: (data) {}); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: Column(children: [ Container( color: ColorConstant.theme, padding: const EdgeInsets.fromLTRB(10, 12, 10, 12), child: InkWell( onTap: () { jumpPage("SearchPage", {"title": searchKw}); }, child: Container( height: 32, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16)), child: Row( children: [ Container( width: 12, ), Image.asset( "assets/imgs/icon_search_home.png", height: 17, ), Container( width: 10, ), Text( searchKw, style: TextStyle( color: const Color(0xFF787878), fontSize: 14), ) ], ), )), ), Expanded( child: RefreshListView( refreshController: _refreshController, content: CustomScrollView(slivers: [ SliverList( delegate: SliverChildBuilderDelegate( (content, index) { if (index == 0) { return bannerList.isEmpty ? Container() : getBannerView(); } else if (index == 1) { return categoryList.isEmpty ? Container() : getCategoryView(); } else if (index == 2) { return getAdView(); } else { return getHomeTypeView(index - 3, context); } }, childCount: homeTypeList.length + 3, )) ]), refresh: () { page = 1; init(); }, loadMore: () { getHomeType(page + 1); }, )) ])); } void getHomeAd() async { Map? result = await HomeApiUtil.getHomeAd(context, "recommend", "1628826741158"); if (result == null) { return; } if (result["IsPost"] == "true") { List list = result["Data"]["data"]; List adList = []; for (var element in list) { adList.add(HomeAdModel.fromJson(element)); } setState(() { bannerList = adList; }); } } void getHomeType(int _page) async { page = _page; Map? result = await HomeApiUtil.getHomeTypes( context, "recommend", "1628826741158", _page); _refreshController.refreshCompleted(resetFooterState: true); //请求失败了 if (result == null) { if (page > 1) { page = page - 1; } if (homeTypeList.isEmpty) { _refreshController.apiError!(); } return; } if (result["IsPost"] == "true") { List list = result["Data"]["data"]; totalCount = int.parse(result["Data"]["count"]); List tempHomeTypeList = []; for (var element in list) { tempHomeTypeList.add(HomeTypeModel.fromJson(element)); } setState(() { if (_page == 1) { homeTypeList = tempHomeTypeList; } else { if (tempHomeTypeList.isNotEmpty) { homeTypeList.addAll(tempHomeTypeList); } } }); if (totalCount <= homeTypeList.length) { _refreshController.loadNoData(); } else { if (_page > 1) { _refreshController.loadComplete(); } } if (homeTypeList.isEmpty) { _refreshController.dataEmpty!(); } else { //正常的状态 _refreshController.dataNormal!(); } } } void getSearchSpecial() async { Map? result = await HomeApiUtil.getRecommendSearchSpecial(context); _refreshController.refreshCompleted(resetFooterState: true); //请求失败了 if (result == null) { if (page > 1) { page = page - 1; } return; } if (result["IsPost"] == "true") { List list = result["Data"]; List tempList = []; for (var element in list) { tempList.add(SearchSpecialModel.fromJson(element)); } // tempList.add(SearchSpecialModel( // id: "novel", // icon: "assets/imgs/home/icon_home_category_novel.png", // name: "小说")); setState(() { categoryList = tempList; }); } } void getHotSearch() async { Map? result = await SearchApiUtil.getHotSearch(context); if (result == null) { return; } if (result["IsPost"] == "true") { List list = result["Data"]["data"]; setState(() { searchKw = list[Random().nextInt(list.length)]; }); } } Widget getBannerView() { double width = MediaQuery.of(context).size.width; double itemWidth = width - 40; double itemHeight = itemWidth * 0.4382; CustomLayoutOption customLayoutOption = CustomLayoutOption(startIndex: -1, stateCount: 3); customLayoutOption.addTranslate([ Offset(-(width - 65), 0), const Offset(0.0, 0.0), Offset(width - 65, 0) ]); customLayoutOption.addScale([0.8, 1, 0.8], Alignment.center); return KeepAliveWrapper( child: bannerList.isNotEmpty ? Container( padding: EdgeInsets.only(top: 10), child: SizedBox( width: width, height: itemHeight, child: Swiper( itemBuilder: (BuildContext context, int index) { return ClipRRect( child: VideoImage( bannerList[index].picture, ), borderRadius: BorderRadius.circular(8), ); }, layout: SwiperLayout.DEFAULT, customLayoutOption: customLayoutOption, indicatorLayout: PageIndicatorLayout.COLOR, autoplay: true, duration: 500, itemCount: bannerList.length, pagination: const SwiperPagination( margin: EdgeInsets.all(10), builder: DotSwiperPaginationBuilder( size: 8, activeColor: ColorConstant.theme, color: Colors.grey)), itemWidth: itemWidth, outer: false, scale: 0.86, viewportFraction: 0.86, // containerHeight: itemHeight-30, // containerWidth:width, itemHeight: itemHeight, onTap: (index) { print("banner点击:$index"); if (bannerList[index].linkType == 1) { jumpPage("VideoDetailPage", { "video": bannerList[index].video!.toJson(), }); } else if (bannerList[index].linkType == 2) { dynamic json = jsonDecode(bannerList[index].params!); String url = json["url"]; jumpPage("BrowserPage", { "url": url, }); } }, )), ) : Container()); } Widget getCategoryView() { return categoryList.isNotEmpty ? Container( padding: const EdgeInsets.fromLTRB(10, 20, 10, 10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: categoryList .map((e) => InkWell( onTap: () { jumpPage( "VideoListPage", {"kw": e.id!, "title": e.name}); }, child: Column(children: [ CommonImage( e.icon!, width: MediaQuery.of(context).size.width * 55 / 375, ), Text( e.name!, style: const TextStyle( color: Color(0xFF3B3B3B), fontSize: 12), ) ]))) .toList())) : Container(); } Widget getAdView() { return expressAdType != null ? Container( padding: const EdgeInsets.fromLTRB(10, 10, 10, 10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // const Text( // "今日热点", // style: TextStyle(color: Color(0xFF5F5F5F), fontSize: 16), // ), SizedBox( height: (MediaQuery.of(context).size.width - 20) * 0.75, width: MediaQuery.of(context).size.width, child: _nativeView(), ) ], ), ) : Container(); } Widget _nativeView() { return expressAdType == AdType.csj ? CSJEXpressAd( expressPid!, MediaQuery.of(context).size.width - 20, (MediaQuery.of(context).size.width - 20) * 0.8, controller: _expressAdController, close: () { setState(() { expressAdType = null; }); }, loadFail: () { setState(() { expressAdType = null; }); }, ) : GDTEXpressAd( expressPid!, MediaQuery.of(context).size.width - 20, (MediaQuery.of(context).size.width - 20) * 0.8, controller: _expressAdController, close: () { setState(() { expressAdType = null; }); }, loadFail: () { setState(() { expressAdType = null; }); }, ); } Widget getHomeTypeView(index, BuildContext context) { HomeTypeModel homeType = homeTypeList[index]; double mx = MediaQuery.of(context).size.width; return VideoListUIUtil.getHomeTypeItem(mx, homeType, context); } }