前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flutter中使用flutter_html解析html文件

Flutter中使用flutter_html解析html文件

作者头像
越陌度阡
发布2021-01-13 10:42:22
5.3K0
发布2021-01-13 10:42:22
举报

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文件的效果图。

参考:https://pub.flutter-io.cn/packages/flutter_html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-01-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 安装插件
  • 2. 引入依赖
  • 3. 使用插件
  • 4. 完整示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档