Flutter 新闻客户端 - 09 详情页展示、分享、远程真机调试
16lz
2021-01-26
B站视频
https://www.bilibili.com/vide...
https://www.bilibili.com/vide...
本节目标
- 详情页技术方案比较
- 载入 web 内容
- 自动计算高度
- 清除广告、推荐
- 拦截请求
- loading 状态显示
- 分享插件
- 远程 android 设备调试
详情展示
技术方案选择
分析工具 UI automator view
- 文件位置
/Users/ducafecat/Library/Android/sdk/tools/bin/uiautomatorviewer
淘宝方案
混合方式
头条
混合方式
什么值得买
单一 webView
技术点分析
-
- webView 原生 混合方式
-
- 计算 web 页面高度
-
- 拦截请求,自定义指令
-
- 内存占用(尽量少的 dom 元素)
安装插件
- webview_flutter
https://pub.flutter-io.cn/pac...
- pubspec.yaml
dependencies: webview_flutter: ^0.3.20+2
- ios/Runner/Info.plist
io.flutter.embedded_views_preview
构建界面代码
// 顶部导航 Widget _buildAppBar() { return Container(); } // 页标题 Widget _buildPageTitle() { return Container(); } // 页头部 Widget _buildPageHeader() { return Container(); } // web内容 Widget _buildWebView() { return Container(); } @override Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), body: SingleChildScrollView( child: Column( children: [ _buildPageTitle(), Divider(height: 1), _buildPageHeader(), _buildWebView(), ], ), ), ); }
url 载入
Widget _buildWebView() { return Container( height: _webViewHeight, child: WebView( initialUrl: '$SERVER_API_URL/news/content/${widget.item.id}', //widget.url, javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController webViewController) async { _controller.complete(webViewController); }, gestureNavigationEnabled: true, ), ); }
计算高度
-
PX DP
- https://blog.akanelee.me/2018...
-
设备像素密度
一个逻辑像素占用多少个实际像素
- https://developer.mozilla.org...
- https://api.flutter.dev/flutt...
- 注册 js
double _webViewHeight = 200; javascriptChannels: [ _invokeJavascriptChannel(context), ].toSet(),
// 注册js回调 JavascriptChannel _invokeJavascriptChannel(BuildContext context) { return JavascriptChannel( name: 'Invoke', onMessageReceived: (JavascriptMessage message) { print(message.message); var webHeight = double.parse(message.message); if (webHeight != null) { setState(() { _webViewHeight = webHeight; }); } }); }
- 回调
onPageFinished: (String url) { _getWebViewHeight(); setState(() { _isPageFinished = true; }); },
// 获取页面高度 _getWebViewHeight() async { await (await _controller.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 {} '''); }
清除广告、推荐
- https://cn.engadget.com/cn-20...
- 删除广告
onPageStarted: (String url) { Timer(Duration(seconds: 1), () { setState(() { _isPageFinished = true; }); _removeAd(); _getViewHeight(); }); },
_removeWebViewAd() async { await (await _controller.future)?.evaluateJavascript(''' try { function removeElement(elementName){ let _element = document.getElementById(elementName); if(!_element) { _element = document.querySelector(elementName); } if(!_element) { return; } let _parentElement = _element.parentNode; if(_parentElement){ _parentElement.removeChild(_element); } } removeElement('module-engadget-deeplink-top-ad'); removeElement('module-engadget-deeplink-streams'); removeElement('footer'); } catch{} '''); }
拦截请求
- 页面中 href
chrome os chromebook computer gear google laptop personal computing personalcomputing pixelbook go
- navigation 拦截
navigationDelegate: (NavigationRequest request) { if (request.url != '$SERVER_API_URL/news/content/${widget.item.id}') { toastInfo(msg: request.url); return NavigationDecision.prevent; } return NavigationDecision.navigate; },
loading 状态显示
bool _isPageFinished = false; @override Widget build(BuildContext context) { return Scaffold( appBar: _buildAppBar(), body: Stack( children: [ SingleChildScrollView( child: Column( children: [ _buildPageTitle(), Divider(height: 1), _buildPageHeader(), _buildWebView(), ], ), ), _isPageFinished == true ? Container() : Align( alignment: Alignment.center, child: LoadingBouncingGrid.square(), ), ], )); }
分享
安装插件
dependencies: share: ^0.6.4
代码
onPressed: () { Share.share('${widget.item.title} ${widget.item.url}'); },
真机调试
- scrcpy
https://github.com/Genymobile...
资源
视频
- b 站
- 油管镜像
蓝湖设计稿(加微信给授权 ducafecat)
https://lanhuapp.com/url/lYuz1
密码: gSKl
蓝湖现在收费了,所以查看标记还请自己上传 xd 设计稿
商业设计稿文件不好直接分享, 可以加微信联系 ducafecat
YAPI 接口管理
http://yapi.demo.qunar.com/
代码
https://github.com/ducafecat/...
参考
https://pub.flutter-io.cn/pac...
https://pub.flutter-io.cn/pac...
https://pub.flutter-io.cn/pac...
https://github.com/Genymobile...
VSCode 插件
- Flutter、Dart
- Flutter Widget Snippets
- Awesome Flutter Snippets
- Paste JSON as Code
- bloc
- Code Spell Checker
更多相关文章
- ListView的item高度调整
- Android中textview显示不全的问题
- Android(安卓)RelativeLayout使用一个小问题
- Android(安卓)Studio插件推荐-GsonFormat,ButterKnifeZelezny
- 自定义Android(安卓)Gradle插件的3种方式
- AndroidStudio上面最好用的插件
- 67-Flutter中高德地图插件的使用
- Android开发环境搭建(一)——开发环境简介
- 腾讯Bugly热更新集成总结