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

技术点分析

    1. webView 原生 混合方式
    1. 计算 web 页面高度
    1. 拦截请求,自定义指令
    1. 内存占用(尽量少的 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

更多相关文章

  1. ListView的item高度调整
  2. Android中textview显示不全的问题
  3. Android(安卓)RelativeLayout使用一个小问题
  4. Android(安卓)Studio插件推荐-GsonFormat,ButterKnifeZelezny
  5. 自定义Android(安卓)Gradle插件的3种方式
  6. AndroidStudio上面最好用的插件
  7. 67-Flutter中高德地图插件的使用
  8. Android开发环境搭建(一)——开发环境简介
  9. 腾讯Bugly热更新集成总结

随机推荐

  1. MySQL数据库入门——多实例配置
  2. LNMP架构应用实战—Nginx反向代理负载均
  3. 【CSS入门】CCS基本语法和常用选择器的使
  4. box-sizing功能,相对定位/绝对定位
  5. 新手如何有效学习linux?
  6. 孟德尔自由组合定理--计算机模拟
  7. 安装Kali linux
  8. 短信营销推广如何降低成本?
  9. Linux系统rsync实战操作
  10. LAMP架构应用实战—Apache服务介绍与安装