Flutter中使用flutter_html解析html文件

Posted aiguangyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter中使用flutter_html解析html文件相关的知识,希望对你有一定的参考价值。

1. 安装插件

配置 flutter_html 插件。

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  date_format: ^1.0.6
  flutter_cupertino_date_picker: ^1.0.26+2 
  flutter_swiper: ^1.1.6
  fluttertoast: ^7.1.6
  http: ^0.12.2
  dio: ^3.0.10
  
  # 解析HTML
  flutter_html: ^1.1.0

在pubspec.yaml中配置保存后,在VS Code环境中会自动下载依赖包。

如果无法正常下载,执行 flutter pub get 

2. 引入依赖

在需要用到的该插件的文件中引入插件包。

import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html/html_parser.dart';
import 'package:flutter_html/style.dart';

3. 使用插件

Html(
    // 渲染的数据
    data:htmlData,
    // 自定义样式
    style: ,
    customRender: 
        "flutter": (RenderContext context, Widget child, attributes, _) 
            return FlutterLogo(
                style: (attributes['horizontal'] != null)
                    ? FlutterLogoStyle.horizontal
                    : FlutterLogoStyle.markOnly,
                textColor: context.style.color,
                size: context.style.fontSize.size * 5,
            );
        ,
    ,
    onLinkTap: (url) 
        print("Opening $url...");
    ,
    onImageTap: (src) 
        print(src);
    ,
    onImageError: (exception, stackTrace) 
        print(exception);
    ,
),

4. 完整示例

如下所示为一个新闻列表页的代码。

// pages/News.dart;
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:dio/dio.dart';


class NewsPage extends StatefulWidget 
    NewsPage(Key key) : super(key: key);
    @override
    _NewsPageState createState() => _NewsPageState();


class _NewsPageState extends State<NewsPage> 
    // 当前页数
    int  _page = 1;
    // 页面数据
    List _list = [];
    // 是否还有
    bool _hasMore = true;
    // 滚动控制器
    ScrollController _scrollController = new ScrollController();
    @override
    void initState() 
        super.initState();
        this._getData();
        // 监听滚动事件
        _scrollController.addListener(()
            // 获取滚动条下拉的距离
            // print(_scrollController.position.pixels);
            // 获取整个页面的高度
            // print(_scrollController.position.maxScrollExtent);
            if(_scrollController.position.pixels>_scrollController.position.maxScrollExtent-40)
                this._getData();
            
        );
    

    // 获取数据列表
    void _getData() async
        if(this._hasMore)

            var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=$_page";
            // 请求远程数据
            Response result = await Dio().get(url);
            var list = json.decode(result.data)["result"];

            setState(() 
                // 拼接数据
                this._list.addAll(list); 
                this._page++;
            );

            if(list.length<20)
                setState(() 
                    // 关闭加载
                   this._hasMore = false;
                );
            
        
    

    // 下拉刷新
    Future<void> _onRefresh() async
        print("下拉刷新");
        // 持续两秒
        await Future.delayed(Duration(milliseconds:2000),()
           this._getData();
        );
    
      

    // 加载动画
    Widget _getMoreWidget() 

        // 如果还有数据
        if(this._hasMore)
            return Center(
                child: Padding(
                    padding: EdgeInsets.all(10.0),
                    child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: <Widget>[
                            Text(
                                '加载中',
                                style: TextStyle(fontSize: 16.0),
                            ),
                            // 加载图标
                            CircularProgressIndicator(
                                strokeWidth: 1.0,
                            )
                        ],
                    ),
                ),
            );
        else
            return Center(
                child: Text("...我是有底线的..."),
            );
        
    

    @override
    Widget build(BuildContext context) 
        return Container(
            child:Scaffold(
                appBar: AppBar(
                title:Text("新闻列表")
                ),
                body:this._list.length==0?this._getMoreWidget():RefreshIndicator(
                    child: ListView.builder(
                        // 上拉加载控制器
                        controller: _scrollController,
                        itemCount: this._list.length,
                        itemBuilder: (context,index)

                            Widget tip = Text("");
                            // 当渲染到最后一条数据时,加载动画提示
                            if(index == this._list.length-1)
                                tip = _getMoreWidget();
                             
                            return Column(
                                children: <Widget>[
                                    ListTile(
                                        title:Text(
                                            "$this._list[index]["title"]",
                                            maxLines:1,
                                        ),
                                        onTap:()
                                            Navigator.pushNamed(context,'/content',arguments: 
                                                "aid":this._list[index]["aid"]
                                            );
                                        ,
                                    ),
                                    Divider(),
                                    // 加载提示
                                    tip
                                ],
                            );
                        ,   
                    ), 
                    // 下拉刷新事件
                    onRefresh:this._onRefresh
                )
            )
        );
    

新闻列表页的效果图如下: 

以下是点击新闻列表页跳转详情页的代码,这个页面中会用到解析html的插件。

// pages/Content.dart;

import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

// 引入解析html的插件
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html/html_parser.dart';
import 'package:flutter_html/style.dart';

class ContentPage extends StatefulWidget 
    final Map arguments;
    ContentPage(Key key,this.arguments) : super(key: key);

    @override
    _ContentPageState createState() => _ContentPageState(this.arguments);


class _ContentPageState extends State<ContentPage> 

    final Map arguments;
    List _list=[];
    _ContentPageState(this.arguments);

    @override
    void initState() 
        super.initState();
        // 发起请求
        this._getData();
    

    // 请求数据
    void _getData() async
        // 将新闻页面中传入的参数作为请求参数
        var url = "http://www.phonegap100.com/appapi.php?a=getPortalArticle&aid=$this.arguments['aid']";
        var result = await Dio().get(url);
        setState(() 
            this._list = json.decode(result.data)["result"];
        );
    

    @override
    Widget build(BuildContext context) 
        return Container(
            child: Scaffold(
                appBar: AppBar(
                    title: Text("新闻详情"),
                ),
                body: SingleChildScrollView(
                    child: Column(
                        children: <Widget>[
                            // 官方代码
                            Html(
                                // 渲染的数据
                                data:this._list.length>0?this._list[0]["content"]:'',
                                // 自定义样式
                                style: ,
                                customRender: 
                                    "flutter": (RenderContext context, Widget child, attributes, _) 
                                        return FlutterLogo(
                                            style: (attributes['horizontal'] != null)
                                                ? FlutterLogoStyle.horizontal
                                                : FlutterLogoStyle.markOnly,
                                            textColor: context.style.color,
                                            size: context.style.fontSize.size * 5,
                                        );
                                    ,
                                ,
                                onLinkTap: (url) 
                                    print("Opening $url...");
                                ,
                                onImageTap: (src) 
                                    print(src);
                                ,
                                onImageError: (exception, stackTrace) 
                                    print(exception);
                                ,
                            ),
                        ],
                    )
                ),
            )
        );
    

以下是详情页解析的Html文件的效果图。

参考:flutter_html | Flutter Package 

以上是关于Flutter中使用flutter_html解析html文件的主要内容,如果未能解决你的问题,请参考以下文章

在flutter web中加载html内容?

在Flutter中解析复杂的JSON

Flutter AnimatedAlign 使用解析

在 Flutter 中解析 JSON 日期

flutter AnimatedPositionedDirectional 使用解析

Flutter RichText 使用案例解析 Flutter WidgetSpan 设置图片显示