【做个开源软件】Flutter 自定义书源看书APP《信息阅读》(看小说,看漫画,看资讯)

2,402 阅读3分钟

效果展示

APP下载体验

img_v2_131ce2c1-dd7a-456d-afdc-bc6c0d559a1g.jpg

前言

最近做了个看小说软件。

因为我老婆喜欢看小说,而免费的小说总在奇奇怪怪的网站,看起来广告多体验差。

她是苹果手机,基本找不到那种可以换源的小说软件。

最后决定利用flutter自己做一个,IOS打包给他直连电脑运行release包就行了。

代码仓库

规划

计划要做一个很全能的app。

  • 可以支持自定义书源
  • 可以支持看小说
  • 可以支持看资讯
  • 可以支持看漫画
  • 可以支持Android IOS linux windows macos
  • 如果可能的话,甚至还想实现看视频

名字就叫做信息阅读

开发技术直接使用Flutter,完美跨平台,轻松完成安卓,苹果和桌面端的app产出。

书源

要想实现自定义书源。就需要一套通用的规则。市面上自定义书源规则做的最好的小说软件自然是阅读

所以我用flutter实现了90%兼容阅读书源规则的方案。

直接把阅读APP的书源拷贝导入信息阅读APP就基本上能使用了。

阅读APP的书源规则

img

并且预置了一些常用书源可以直接导入。

因为dart没有jsoup这样可以功能强大的css selector 选择器。所以我使用flutter_html 加 正则表达式进行规则解析。

具体代码在RuleUtil.ElementExt中。

///[rule] 匹配规则
///当前支持
/// - && 连接多个不同的匹配结果
/// - @ 分割css 选择器匹配
/// - ## 后面跟随正则表达式
/// 比如ol.am-breadcrumb@li:nth-of-type(2)@text
///[matchReplace] 是否处理图片url等需要替换的值
///比如  dt@a@href##.*/(\\d+)/(\\d+)/##https://style.31xs.net/img/$1/$2/$2s.jpg
///从 https://m.31xs.com/201/201996/ url中提取出 两个数字关键词 201, 201996
///将其作为$1和$2替换到结果中
///
String? parseRule(String? rule, [AttrBean? attrBean = null]) {
  if (rule?.isNotEmpty != true) return null;
  if (attrBean != null) {
    rule = attrBean.dealRes(rule);
  }

  ///正则 处理 ##分割
  var regexSpan = rule!.split('##');
  String? regex;
  String? replace;
  if (regexSpan.length > 1) {
    regex = regexSpan[1];
  }
  if (regexSpan.length > 2) {
    replace = regexSpan[2];
  }

  String? resultStr = _selectElement(regexSpan[0], regex, replace, rule.endsWith("###"));
  return resultStr;
}

资讯

对于资讯类别的源,展示的很简单。只是列表和详情页的展示。

常用资讯源中内置了《福利吧》源。

待办

[ ] 新增关键内容提取规则(针对需要提取一些链接内容的情况)

image.png

小说

小说阅读器的实现,最难点的地方在于段落,文字的计算。将一章节的内容均匀分布到每一页,要计算的恰到好处,才有良好的阅读体验。

这一块参考了lwlizhe大佬的开源阅读器flutter_novel

自己取了其中的段落字数计算代码,实现了横向翻页能力。效果如下。

img

文字绘制主要分这么三步。

  1. 根据文字大小,段落间距,展示区域大小,计算出章节中每一页的所有文字。
  2. 绘制当前页面的文字到画布中(CustomPainter)。滑动的时候会绘制两页
  3. 翻页完成之后根据需要预先加载下一章节的内容,以及计算分页。

关键的计算代码如下:

///算出给定区域大小内,能完全绘制出来的最后文字偏移量
int endOffset = textPainter.getPositionForOffset(Offset(width, limitHeight - currentHeight)).offset;

通过算出来的偏移量就知道文字需不需要多页绘制,和每一页能绘制到哪个文字。

漫画

当前漫画的实现比较简单,只是列表的展示。

漫画往前翻页没有实现,往后翻页勉强可用。还没有想到好的实现方案。想实现bilibili漫画那样的效果这一块技术难度还挺大的,需要我好好学习才行。

img

最后

通过开发一个软件来学习一些知识,不失为可取的方式。

成功自己还能使用,何乐而不为