详情页开发中
This commit is contained in:
parent
101d1a42fa
commit
3f86568f5c
|
@ -32,6 +32,7 @@ class MyApp extends StatelessWidget {
|
||||||
title: 'News',
|
title: 'News',
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: AppTheme.light,
|
theme: AppTheme.light,
|
||||||
|
unknownRoute: AppPages.notFoundRoute,
|
||||||
initialRoute: AppPages.Initial,
|
initialRoute: AppPages.Initial,
|
||||||
getPages: AppPages.pages,
|
getPages: AppPages.pages,
|
||||||
navigatorObservers: [AppPages.observer],
|
navigatorObservers: [AppPages.observer],
|
||||||
|
@ -56,6 +57,7 @@ class MyApp extends StatelessWidget {
|
||||||
maxOverScrollExtent: 100,
|
maxOverScrollExtent: 100,
|
||||||
footerTriggerDistance: 150,
|
footerTriggerDistance: 150,
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
|
// todo 有没有更好的解决方案
|
||||||
return ConfigService.to.isGrayFilter.isTrue ? ColorFiltered(
|
return ConfigService.to.isGrayFilter.isTrue ? ColorFiltered(
|
||||||
colorFilter: ColorFilter.mode(Colors.grey, BlendMode.color),
|
colorFilter: ColorFilter.mode(Colors.grey, BlendMode.color),
|
||||||
child: app,
|
child: app,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'bookmarks_controller.dart';
|
||||||
|
|
||||||
|
class BookmarksBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => BookmarksController());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'bookmarks_state.dart';
|
||||||
|
|
||||||
|
class BookmarksController extends GetxController {
|
||||||
|
final BookmarksState state = BookmarksState();
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'bookmarks_controller.dart';
|
||||||
|
|
||||||
|
class BookmarksPage extends GetView<BookmarksController> {
|
||||||
|
const BookmarksPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
child: Text('BookmarksPage'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class BookmarksState {
|
||||||
|
BookmarksState() {
|
||||||
|
///Initialize variables
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import 'detail_controller.dart';
|
||||||
|
|
||||||
|
class DetailBinding extends Bindings {
|
||||||
|
@override
|
||||||
|
void dependencies() {
|
||||||
|
Get.lazyPut(() => DetailController());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:news_getx/config/server.dart';
|
||||||
|
import 'package:news_getx/data/model/news.dart';
|
||||||
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
|
||||||
|
import 'detail_state.dart';
|
||||||
|
|
||||||
|
class DetailController extends GetxController {
|
||||||
|
/// 响应式成员变量
|
||||||
|
// 页面是否加载完成
|
||||||
|
var isPageFinished = false.obs;
|
||||||
|
|
||||||
|
// webView高度
|
||||||
|
var webViewHeight = 200.0.obs;
|
||||||
|
|
||||||
|
/// 成员变量
|
||||||
|
// 页面详情
|
||||||
|
final DetailState state = DetailState();
|
||||||
|
|
||||||
|
WebViewController webViewController = WebViewController();
|
||||||
|
|
||||||
|
/// 方法
|
||||||
|
// 注册js回调
|
||||||
|
void _invokeJavascriptChannel() {
|
||||||
|
webViewController.addJavaScriptChannel(
|
||||||
|
'Invoke',
|
||||||
|
onMessageReceived: (JavaScriptMessage message) {
|
||||||
|
print(message.message);
|
||||||
|
var webHeight = double.tryParse(message.message);
|
||||||
|
if (webHeight != null) {
|
||||||
|
webViewHeight.value = webHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 获取页面高度
|
||||||
|
_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 {}
|
||||||
|
// ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
void initWebController() {
|
||||||
|
webViewController.setJavaScriptMode(JavaScriptMode.unrestricted);
|
||||||
|
webViewController.setBackgroundColor(Colors.black);
|
||||||
|
webViewController.setNavigationDelegate(NavigationDelegate(
|
||||||
|
onProgress: (int progress) {},
|
||||||
|
onPageStarted: (String url) {},
|
||||||
|
onPageFinished: (String url) {
|
||||||
|
_getWebViewHeight();
|
||||||
|
isPageFinished.value = true;
|
||||||
|
},
|
||||||
|
onWebResourceError: (WebResourceError error) {},
|
||||||
|
onNavigationRequest: (NavigationRequest request) {
|
||||||
|
// if (request.url != '$ServerApiUrl/news/content/${state.item.id}') {
|
||||||
|
if (request.url != 'https://www.youtube.com/') {
|
||||||
|
return NavigationDecision.prevent;
|
||||||
|
}
|
||||||
|
return NavigationDecision.navigate;
|
||||||
|
},
|
||||||
|
));
|
||||||
|
// 注册js回调
|
||||||
|
_invokeJavascriptChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 声明周期
|
||||||
|
@override
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:news_getx/modules/widgets/app_bar.dart';
|
||||||
|
import 'package:news_getx/theme/app_colors.dart';
|
||||||
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
import 'detail_controller.dart';
|
||||||
|
|
||||||
|
class DetailPage extends GetView<DetailController> {
|
||||||
|
DetailPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
// 顶部导航
|
||||||
|
AppBar _buildAppBar() {
|
||||||
|
return transparentAppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.arrow_back,
|
||||||
|
color: AppColors.primaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.bookmark_border,
|
||||||
|
color: AppColors.primaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.share,
|
||||||
|
color: AppColors.primaryText,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPageTitle() {
|
||||||
|
return Text('data');
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildPageHeader() {
|
||||||
|
return Text('data');
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildWebView() {
|
||||||
|
return WebViewWidget(
|
||||||
|
controller: controller.webViewController,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return _buildWebView();
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: _buildAppBar(),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildPageTitle(),
|
||||||
|
Divider(height: 1),
|
||||||
|
_buildPageHeader(),
|
||||||
|
_buildWebView(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import 'package:news_getx/data/model/news.dart';
|
||||||
|
|
||||||
|
class DetailState {
|
||||||
|
late final NewsItem item;
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ class MainController extends GetxController {
|
||||||
/// 方法
|
/// 方法
|
||||||
// 拉取数据
|
// 拉取数据
|
||||||
asyncLoadAllData() async {
|
asyncLoadAllData() async {
|
||||||
|
// todo 因为缓存导致这两项无法刷新 得找个地方刷新或者调整逻辑 例如缓存加超时
|
||||||
state.categories = await newsRepository.categories(cacheDisk: true);
|
state.categories = await newsRepository.categories(cacheDisk: true);
|
||||||
state.channels = await newsRepository.channels(cacheDisk: true);
|
state.channels = await newsRepository.channels(cacheDisk: true);
|
||||||
// 分类对应的数据(推荐、新闻)
|
// 分类对应的数据(推荐、新闻)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:get/get.dart';
|
||||||
import 'package:news_getx/data/services/config.dart';
|
import 'package:news_getx/data/services/config.dart';
|
||||||
import 'package:news_getx/modules/main/main_controller.dart';
|
import 'package:news_getx/modules/main/main_controller.dart';
|
||||||
import 'package:news_getx/modules/widgets/image.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/theme/app_colors.dart';
|
||||||
import 'package:news_getx/utils/date.dart';
|
import 'package:news_getx/utils/date.dart';
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ class NewsRecommendWidget extends GetView<MainController> {
|
||||||
// 图
|
// 图
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
print("进入详情页");
|
Get.toNamed(AppRoutes.Detail, arguments: controller.state.newsRecommend!);
|
||||||
},
|
},
|
||||||
child: netImageCached(
|
child: netImageCached(
|
||||||
controller.state.newsRecommend?.thumbnail ?? "",
|
controller.state.newsRecommend?.thumbnail ?? "",
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'package:get/get.dart';
|
||||||
|
|
||||||
class NotFoundController extends GetxController {
|
class NotFoundController extends GetxController {
|
||||||
// title
|
// title
|
||||||
final _title = "".obs;
|
final _title = "Not Found".obs;
|
||||||
|
|
||||||
set title(value) => _title.value = value;
|
set title(value) => _title.value = value;
|
||||||
get title => _title.value;
|
get title => _title.value;
|
||||||
|
|
|
@ -8,6 +8,8 @@ import 'package:news_getx/modules/application/application_page.dart';
|
||||||
import 'package:news_getx/modules/bookmarks/bookmarks_binding.dart';
|
import 'package:news_getx/modules/bookmarks/bookmarks_binding.dart';
|
||||||
import 'package:news_getx/modules/category/category_binding.dart';
|
import 'package:news_getx/modules/category/category_binding.dart';
|
||||||
import 'package:news_getx/modules/category/category_page.dart';
|
import 'package:news_getx/modules/category/category_page.dart';
|
||||||
|
import 'package:news_getx/modules/detail/detail_binding.dart';
|
||||||
|
import 'package:news_getx/modules/detail/detail_page.dart';
|
||||||
import 'package:news_getx/modules/main/main_binding.dart';
|
import 'package:news_getx/modules/main/main_binding.dart';
|
||||||
import 'package:news_getx/modules/not_found/not_found_binding.dart';
|
import 'package:news_getx/modules/not_found/not_found_binding.dart';
|
||||||
import 'package:news_getx/modules/not_found/not_found_page.dart';
|
import 'package:news_getx/modules/not_found/not_found_page.dart';
|
||||||
|
@ -27,6 +29,14 @@ abstract class AppPages {
|
||||||
static final NavigatorObserver observer = AppNavigatorObserver();
|
static final NavigatorObserver observer = AppNavigatorObserver();
|
||||||
static List<String> history = [];
|
static List<String> history = [];
|
||||||
|
|
||||||
|
// 404
|
||||||
|
static final notFoundRoute = GetPage(
|
||||||
|
name: AppRoutes.NotFound,
|
||||||
|
page: () => NotFoundPage(),
|
||||||
|
binding: NotFoundBinding(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 页面
|
||||||
static final pages = [
|
static final pages = [
|
||||||
// 免登陆
|
// 免登陆
|
||||||
GetPage(
|
GetPage(
|
||||||
|
@ -35,21 +45,18 @@ abstract class AppPages {
|
||||||
binding: WelcomeBinding(),
|
binding: WelcomeBinding(),
|
||||||
middlewares: [RouteWelcomeMiddleware()],
|
middlewares: [RouteWelcomeMiddleware()],
|
||||||
),
|
),
|
||||||
|
// 登录页
|
||||||
GetPage(
|
GetPage(
|
||||||
name: AppRoutes.Signin,
|
name: AppRoutes.Signin,
|
||||||
page: () => SignInPage(),
|
page: () => SignInPage(),
|
||||||
binding: SignInBinding(),
|
binding: SignInBinding(),
|
||||||
),
|
),
|
||||||
|
// 注册页
|
||||||
GetPage(
|
GetPage(
|
||||||
name: AppRoutes.Signup,
|
name: AppRoutes.Signup,
|
||||||
page: () => SignUpPage(),
|
page: () => SignUpPage(),
|
||||||
binding: SignUpBinding(),
|
binding: SignUpBinding(),
|
||||||
),
|
),
|
||||||
GetPage(
|
|
||||||
name: AppRoutes.NotFound,
|
|
||||||
page: () => NotFoundPage(),
|
|
||||||
binding: NotFoundBinding(),
|
|
||||||
),
|
|
||||||
// 应用页
|
// 应用页
|
||||||
GetPage(
|
GetPage(
|
||||||
name: AppRoutes.Application,
|
name: AppRoutes.Application,
|
||||||
|
@ -65,5 +72,14 @@ abstract class AppPages {
|
||||||
RouteAuthMiddleware(),
|
RouteAuthMiddleware(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
// 详情页
|
||||||
|
GetPage(
|
||||||
|
name: AppRoutes.Detail,
|
||||||
|
page: () => DetailPage(),
|
||||||
|
binding: DetailBinding(),
|
||||||
|
middlewares: [
|
||||||
|
RouteAuthMiddleware(),
|
||||||
|
],
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,4 +8,5 @@ abstract class AppRoutes {
|
||||||
|
|
||||||
static const Application = '/application';
|
static const Application = '/application';
|
||||||
static const Category = '/category';
|
static const Category = '/category';
|
||||||
|
static const Detail = '/detail';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue