diff --git a/lib/modules/account/account_page.dart b/lib/modules/account/account_page.dart index 226f9e1..6e1871b 100644 --- a/lib/modules/account/account_page.dart +++ b/lib/modules/account/account_page.dart @@ -30,7 +30,8 @@ class AccountPage extends GetView { Container( height: 200.h, alignment: Alignment.center, - child: ClipOval( + child: CircleAvatar( + radius: 54, child: Image.asset( "assets/images/account_header.png", height: 108, diff --git a/lib/modules/category/widgets/news_item.dart b/lib/modules/category/widgets/news_item.dart index 15eeace..c7368c5 100644 --- a/lib/modules/category/widgets/news_item.dart +++ b/lib/modules/category/widgets/news_item.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; import 'package:news_getx/data/model/news.dart'; import 'package:news_getx/modules/widgets/image.dart'; +import 'package:news_getx/routes/app_pages.dart'; import 'package:news_getx/theme/app_colors.dart'; import 'package:news_getx/utils/date.dart'; @@ -23,6 +25,7 @@ class NewsListItem extends StatelessWidget { InkWell( onTap: () { // 到详情页 + Get.toNamed(AppRoutes.Detail, arguments: newsItem); }, child: SizedBox( width: 121.w, @@ -58,6 +61,7 @@ class NewsListItem extends StatelessWidget { InkWell( onTap: () { // 到详情页 + Get.toNamed(AppRoutes.Detail, arguments: newsItem); }, child: Container( margin: EdgeInsets.only(top: 10.h), diff --git a/lib/modules/detail/detail_controller.dart b/lib/modules/detail/detail_controller.dart index 3552922..b6d3e84 100644 --- a/lib/modules/detail/detail_controller.dart +++ b/lib/modules/detail/detail_controller.dart @@ -26,7 +26,6 @@ class DetailController extends GetxController { webViewController.addJavaScriptChannel( 'Invoke', onMessageReceived: (JavaScriptMessage message) { - print(message.message); var webHeight = double.tryParse(message.message); if (webHeight != null) { webViewHeight.value = webHeight; @@ -35,23 +34,26 @@ class DetailController extends GetxController { ); } - // 获取页面高度 _getWebViewHeight() async { - // await (await webViewController.future)?.evaluateJavascript(''' - // try { - // // Invoke.postMessage([document.body.clientHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight]); - // let scrollHeight = document.documentElement.scrollHeight; - // if (scrollHeight) { - // Invoke.postMessage(scrollHeight); - // } - // } catch {} - // '''); + // 一直变动高度的 设置最大高度变更次数 + await webViewController.runJavaScript(""" + // 设置最大高度变更次数 + let retryNum = 3; + const resizeObserver = new ResizeObserver(entries => { + if (retryNum > 0) { + Invoke.postMessage(document.documentElement.scrollHeight.toString()); + retryNum -= 1; + } + }); + resizeObserver.observe(document.body); + """); } void initWebController() { + // 控制器设置 webViewController.setJavaScriptMode(JavaScriptMode.unrestricted); - webViewController.setBackgroundColor(Colors.black); + webViewController.setBackgroundColor(Colors.transparent); webViewController.setNavigationDelegate(NavigationDelegate( onProgress: (int progress) {}, onPageStarted: (String url) {}, @@ -61,8 +63,8 @@ class DetailController extends GetxController { }, onWebResourceError: (WebResourceError error) {}, onNavigationRequest: (NavigationRequest request) { - // if (request.url != '$ServerApiUrl/news/content/${state.item.id}') { - if (request.url != 'https://www.youtube.com/') { + // 限制内部导航的url + if (request.url != '$ServerApiUrl/news/content/${state.item.id}') { return NavigationDecision.prevent; } return NavigationDecision.navigate; @@ -77,12 +79,12 @@ class DetailController extends GetxController { void onInit() { super.onInit(); NewsItem newsItem = Get.arguments; - print(newsItem); state.item = newsItem; - // 初始化WebViewController信息 initWebController(); - const url = "https://www.baidu.com/#iact=wiseindex%2Ftabs%2Fnews%2Factivity%2Fnewsdetail%3D%257B%2522linkData%2522%253A%257B%2522name%2522%253A%2522iframe%252Fmib-iframe%2522%252C%2522id%2522%253A%2522feed%2522%252C%2522index%2522%253A0%252C%2522url%2522%253A%2522https%253A%252F%252Fmbd.baidu.com%252Fnewspage%252Fdata%252Flandingpage%253Fs_type%253Dnews%2526dsp%253Dwise%2526context%253D%25257B%252522nid%252522%25253A%252522news_9417572788407561368%252522%25257D%2526pageType%253D1%2526n_type%253D1%2526p_from%253D-1%2526rec_src%253D52%2526innerIframe%253D1%2526browserId%253D25%2522%252C%2522isThird%2522%253Afalse%252C%2522title%2522%253Anull%257D%257D"; - webViewController.loadRequest(Uri.parse(url)); + // TODO 如果遇到页面是固定100vh的,那么获取到的高度就是初始的SizeBox的高度 + // const url = "https://www.baidu.com/#iact=wiseindex%2Ftabs%2Fnews%2Factivity%2Fnewsdetail%3D%257B%2522linkData%2522%253A%257B%2522name%2522%253A%2522iframe%252Fmib-iframe%2522%252C%2522id%2522%253A%2522feed%2522%252C%2522index%2522%253A0%252C%2522url%2522%253A%2522https%253A%252F%252Fmbd.baidu.com%252Fnewspage%252Fdata%252Flandingpage%253Fs_type%253Dnews%2526dsp%253Dwise%2526context%253D%25257B%252522nid%252522%25253A%252522news_9417572788407561368%252522%25257D%2526pageType%253D1%2526n_type%253D1%2526p_from%253D-1%2526rec_src%253D52%2526innerIframe%253D1%2526browserId%253D25%2522%252C%2522isThird%2522%253Afalse%252C%2522title%2522%253Anull%257D%257D"; + // const url = "https://blog.csdn.net/m0_55635384/article/details/129020261"; + webViewController.loadRequest(Uri.parse(newsItem.url!)); } } diff --git a/lib/modules/detail/detail_page.dart b/lib/modules/detail/detail_page.dart index ed6ba9e..a804add 100644 --- a/lib/modules/detail/detail_page.dart +++ b/lib/modules/detail/detail_page.dart @@ -1,8 +1,13 @@ import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:loading_animations/loading_animations.dart'; import 'package:news_getx/modules/widgets/app_bar.dart'; +import 'package:news_getx/modules/widgets/image.dart'; import 'package:news_getx/theme/app_colors.dart'; +import 'package:news_getx/utils/date.dart'; import 'package:webview_flutter/webview_flutter.dart'; + import 'detail_controller.dart'; class DetailPage extends GetView { @@ -11,63 +16,190 @@ class DetailPage extends GetView { // 顶部导航 AppBar _buildAppBar() { return transparentAppBar( - leading: IconButton( + leading: IconButton( + onPressed: () { + Get.back(); + }, + icon: Icon( + Icons.arrow_back, + color: AppColors.primaryText, + ), + ), + actions: [ + IconButton( onPressed: () {}, icon: Icon( - Icons.arrow_back, + Icons.bookmark_border, color: AppColors.primaryText, ), ), - actions: [ - IconButton( - onPressed: () {}, - icon: Icon( - Icons.bookmark_border, - color: AppColors.primaryText, - ), + IconButton( + onPressed: () {}, + icon: Icon( + Icons.share, + color: AppColors.primaryText, ), - IconButton( - onPressed: () {}, - icon: Icon( - Icons.share, - color: AppColors.primaryText, - ), - ), - ]); + ), + ], + ); } Widget _buildPageTitle() { - return Text('data'); + return Container( + margin: EdgeInsets.all(10.w), + child: Row( + children: [ + Column( + children: [ + // 标题 + Text( + controller.state.item.category ?? "--", + style: TextStyle( + fontFamily: "Montserrat", + fontWeight: FontWeight.normal, + fontSize: 30.sp, + color: AppColors.thirdElement, + ), + ), + // 作者 + Text( + controller.state.item.author ?? "--", + style: TextStyle( + fontFamily: "Avenir", + fontWeight: FontWeight.normal, + fontSize: 14.sp, + color: AppColors.thirdElementText, + ), + ), + ], + ), + Spacer(), + // 标志 + CircleAvatar( + // 头像半径 + radius: 22.w, + backgroundImage: AssetImage("assets/images/channel-fox.png"), + ) + ], + ), + ); } Widget _buildPageHeader() { - return Text('data'); + return Container( + margin: EdgeInsets.all(10.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 图 + netImageCached( + controller.state.item.thumbnail!, + width: 335, + height: 290, + ), + // 标题 + Container( + margin: EdgeInsets.only(top: 10.h), + child: Text( + controller.state.item.title!, + style: TextStyle( + fontFamily: 'Montserrat', + fontWeight: FontWeight.w600, + color: AppColors.primaryText, + fontSize: 24.sp, + height: 1, + ), + ), + ), + + // 一行三列 + Container( + margin: EdgeInsets.only(top: 10.h), + child: Row( + children: [ + // 分类 + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 120, + ), + child: Text( + controller.state.item.category!, + style: TextStyle( + fontFamily: 'Avenir', + fontWeight: FontWeight.normal, + color: AppColors.secondaryElementText, + fontSize: 14.sp, + height: 1, + ), + overflow: TextOverflow.clip, + maxLines: 1, + ), + ), + // 添加时间 + SizedBox( + width: 15.w, + ), + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 120, + ), + child: Text( + '• ${timeLineFormat(controller.state.item.addtime ?? DateTime(0))}', + style: TextStyle( + fontFamily: 'Avenir', + fontWeight: FontWeight.normal, + color: AppColors.thirdElementText, + fontSize: 14.sp, + height: 1, + ), + overflow: TextOverflow.clip, + maxLines: 1, + ), + ), + ], + ), + ) + ], + ), + ); } Widget _buildWebView() { - return WebViewWidget( - controller: controller.webViewController, - ); + return Obx(() { + return SizedBox( + height: controller.webViewHeight.value, + child: WebViewWidget( + controller: controller.webViewController, + ), + ); + }); } @override Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), - body: _buildWebView(), - ); - - return Scaffold( - appBar: _buildAppBar(), - body: SingleChildScrollView( - child: Column( - children: [ - _buildPageTitle(), - Divider(height: 1), - _buildPageHeader(), - _buildWebView(), - ], - ), + body: Stack( + children: [ + SingleChildScrollView( + child: Column( + children: [ + _buildPageTitle(), + Divider(height: 1), + _buildPageHeader(), + _buildWebView(), + ], + ), + ), + Obx(() { + return controller.isPageFinished.isTrue + ? Container() + : Align( + alignment: Alignment.center, + child: LoadingBouncingGrid.square(), + ); + }) + ], ), ); } diff --git a/lib/modules/main/widgets/news_list.dart b/lib/modules/main/widgets/news_list.dart index 9c5ef4b..cdec343 100644 --- a/lib/modules/main/widgets/news_list.dart +++ b/lib/modules/main/widgets/news_list.dart @@ -5,6 +5,7 @@ import 'package:news_getx/data/model/news.dart'; import 'package:news_getx/modules/main/main_controller.dart'; import 'package:news_getx/modules/main/widgets/ad.dart'; import 'package:news_getx/modules/widgets/image.dart'; +import 'package:news_getx/routes/app_pages.dart'; import 'package:news_getx/theme/app_colors.dart'; import 'package:news_getx/utils/date.dart'; @@ -20,7 +21,7 @@ class NewsListWidget extends GetView { // 左侧图 InkWell( onTap: () { - // 到详情页 + Get.toNamed(AppRoutes.Detail, arguments: item); }, child: SizedBox( width: 121.w, @@ -56,6 +57,7 @@ class NewsListWidget extends GetView { InkWell( onTap: () { // 到详情页 + Get.toNamed(AppRoutes.Detail, arguments: item); }, child: Container( margin: EdgeInsets.only(top: 10.h), @@ -129,7 +131,8 @@ class NewsListWidget extends GetView { ), ], ), - ), ], + ), + ], ), ), ],