Flutter flutter_html插件加载html标签内容、 flutter_webview_plugin插件加载网页

纸上得来终觉浅,绝知此事要躬行。——陆游

自从Flutter官网发布第一版就开始接触了,中间有1年多没有接触,因为当初考虑这是新的技术框架,还是比较开好原生开发。时代变化的浪潮中,谁也无法预料未来谁会成为未来技术的主流,是语言还是莫某框架,有未可知。

最近着手用纯Flutter框架开发了一款 app,在开发的过程中也许遇到了和当年原生才出来的时候一样的坑,虽然坑不同,那也得去解决坑呀。当我们在技术的道路上着手解决了一系列问题,也许就是我们很自信的去和老板谈薪资的时候了。废话不多说了,我今天就遇到了两个问题:一个问题是Flutter编写的app在安卓和苹果机器上运行时加载htm标签内容需要显示加载的进度,第二个问题就是在两端机器上无法加载网页连接以http开头的网页。其实这两个问题都解决了,且听我慢慢道来。

先说第一个问题,其实第二个问题不是要说的重点,第二个问题我在搜索引擎中找到了答案,哈哈

实现后的效果:

                    

加载内容:<img src="http开头图片地址" alt="图片">

思路:

1、监听网页开始加载、加载中、加载完成

2、显示加载转圈提示

3、加载完成取消加载转圈提示

既然我们是使用的 flutter_html插件,为了能进一步实现我们想要的功能,首先得从插件源码进行粗略的观看了。

我们不难发现是继承自一个绘制的UI页的状态包括被渲染的内容都是始终不变的Widget 。

注意:有必要了解一下了解到了StatelessWidget和StatefullWidget的区别

class Html extends StatelessWidget {
  Html({
    Key key,
    @required this.data,
    this.padding,
    this.backgroundColor,
    this.defaultTextStyle,
    this.onLinkTap,
    this.renderNewlines = false,
    this.customRender,
    this.customEdgeInsets,
    this.customTextStyle,
    this.customTextAlign,
    this.blockSpacing = 14.0,
    this.useRichText = true,
    this.onImageError,
    this.linkStyle = const TextStyle(
        decoration: TextDecoration.underline,
        color: Colors.blueAccent,
        decorationColor: Colors.blueAccent),
    this.shrinkToFit = false,
    this.imageProperties,
    this.onImageTap,
    this.showImages = true,
  }) : super(key: key);

useRichText 表示是否使用富文本或者原始解析html方式,因为有图片和文本的加载我当选useRichText=true

通过解析html标签节点的方式去加载不同htm内容l标签,今天主要讲包含img标签的。

1、节点包括src、data:image、base64:

2、点击包括src、asset:

3、今天我遇到的也是要讲的,开头只是src :

 准备缓存图片:

node.attributes['src']表示获取到的图片地址,例如:<img src="http开头图片地址" alt="图片">

 precacheImage(
                    NetworkImage(node.attributes['src']),
                    buildContext,
                    onError: onImageError ?? (_, __) {},
                  );

Image.network()加载网络图片:

 frameBuilder 用于展示要加载的图片

loadingBuilder 用于展示图片加载开始到完成整过过程任意可表示加载进度的控件,此部分在flutter_html插件中没有,是我今天对此插件进行改装后的代码。

ImageChunkEvent loadingProgress表示加载的进度,表示没有加载或者加载完成,就不不需要展示加载的进度

表示加载的进度条,可自定义 
return Container(
                          width: ViewUtils.currentHeight(400.0),
                          height: ViewUtils.currentWidth(400.0),
                          alignment: Alignment.center,
                          child: NetLoadingDialog(
                            //requestCallBack: _register(),
                            outsideDismiss: false,
                          ),
                        );
 loadingBuilder: (BuildContext context, Widget child,
                          ImageChunkEvent loadingProgress) {
                        if (loadingProgress == null) return child;
                        return Container(
                          width: ViewUtils.currentHeight(400.0),
                          height: ViewUtils.currentWidth(400.0),
                          alignment: Alignment.center,
                          child: NetLoadingDialog(
                            //requestCallBack: _register(),
                            outsideDismiss: false,
                          ),
                        );
                      },
                    child: Image.network(
                      node.attributes['src'],
                      frameBuilder: (context, child, frame, _) {
                        if (node.attributes['alt'] != null && frame == null) {
                          return BlockText(
                            child: RichText(
                              textAlign: TextAlign.center,
                              text: TextSpan(
                                text: node.attributes['alt'],
                                style: nextContext.childStyle,
                              ),
                            ),
                            shrinkToFit: shrinkToFit,
                          );
                        }
                        if (frame != null) {
                          return child;
                        }
                        return Container();
                      },
                      loadingBuilder: (BuildContext context, Widget child,
                          ImageChunkEvent loadingProgress) {
                        if (loadingProgress == null) return child;
                        return Container(
                          width: ViewUtils.currentHeight(400.0),
                          height: ViewUtils.currentWidth(400.0),
                          alignment: Alignment.center,
                          child: NetLoadingDialog(
                            //requestCallBack: _register(),
                            outsideDismiss: false,
                          ),
                        );
                      },
                      width: (width ?? -1) > 0 ? width : null,
                      height: (height ?? -1) > 0 ? height : null,
                      scale: imageProperties?.scale ?? 1.0,
                      matchTextDirection:
                          imageProperties?.matchTextDirection ?? false,
                      centerSlice: imageProperties?.centerSlice,
                      filterQuality:
                          imageProperties?.filterQuality ?? FilterQuality.low,
                      alignment: imageProperties?.alignment ?? Alignment.center,
                      colorBlendMode: imageProperties?.colorBlendMode,
                      fit: imageProperties?.fit,
                      color: imageProperties?.color,
                      repeat: imageProperties?.repeat ?? ImageRepeat.noRepeat,
                      semanticLabel: imageProperties?.semanticLabel,
                      excludeFromSemantics:
                          (imageProperties?.semanticLabel == null)
                              ? true
                              : false,
                    ),
                    onTap: () {
                      if (onImageTap != null) {
                        onImageTap(node.attributes['src']);
                      }
                    },

最后使用了:

  child: Html(
                  useRichText: true,
                  data: _content,
                  defaultTextStyle: TextStyle(
                    fontSize: 18.0,
                    color: Colors.black,
                    decoration: TextDecoration.none,
                  ),
                ),

总结:加载带html标签的内容,我们需要知晓官方源码是通过解析标签根节点的方式去获取图片地址或者文本内容进行加载,其中的原理不是很复杂。

参考:

flutter_html插件:https://pub.flutter-io.cn/packages/flutter_html

StatelessWidget&StatefulWidgethttps://flutterchina.club/widgets-intro/

Image.net:https://api.flutter.dev/flutter/widgets/Image/Image.network.html

资源下载:https://download.csdn.net/download/u013491829/12276485

发布了22 篇原创文章 · 获赞 17 · 访问量 6932

猜你喜欢

转载自blog.csdn.net/u013491829/article/details/105153666