Last active
September 25, 2019 06:34
-
-
Save lwlizhe/2a0ad72a9d9d253e7098fcc9dad111e8 to your computer and use it in GitHub Desktop.
flutter 小说阅读器分页逻辑
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// em…………由于大量文字计算,即Cpu计算,在UI的Isolate会阻塞后续的UI事件(例如跳转,动画啥的),所以采取新建Isolate的方式,这也是flutter中建议的&…… | |
| /// 但是目前尴尬的是: | |
| /// 非UI的Isolate不支持UI控件,即下面的textPainter.layout废了……一调用就报错 | |
| /// https://github.com/flutter/flutter/issues/30604 | |
| /// 所以,理论上来说,这块的计算应该放到一个子线程中,对于目前功能来说,也可以说是isolate中,但是flutter 现在不支持…… | |
| /// 现在个人有几种想法: | |
| /// 1、翻页的时候动态计算,只缓存几页的内容,下次翻页的时候再计算 | |
| /// 2、https://github.com/flutter/flutter/issues/30604 裁剪canvas | |
| /// 3、平台计算…… | |
| /// 4、自己新建一个主isolate?但是不给它任何View? | |
| /// | |
| /// | |
| /// 评测结果记录: | |
| /// 1、这样不行,这样无法计算上一章的最后一页 | |
| /// 2、但是这种方式是基于不自定义段落间距,而固定所有行距实现的,无法自定义 | |
| /// 3、但是不能保证Android平台和ios平台自己计算结果和flutter的一致…… | |
| /// 4、好像https://pub.dev/packages/flutter_isolate 实现了这点,但是运行不起来,不太清楚具体原因,先看下官方plugin中的android_alarm_manager具体实现方式吧。 | |
| static List<ReaderChapterPageContentConfig> getChapterPageContentConfigList( | |
| int targetChapterId, | |
| String content, | |
| double height, | |
| double width, | |
| double fontSize, | |
| double lineSpacing, | |
| double paragraphSpacing, | |
| ) { | |
| String tempTotalContent = content; | |
| List<ReaderChapterPageContentConfig> pageConfigList = []; | |
| double currentHeight = 0; | |
| TextPainter textPainter = TextPainter(textDirection: TextDirection.ltr); | |
| while (tempTotalContent.length > 0) { | |
| ReaderChapterPageContentConfig config = ReaderChapterPageContentConfig(); | |
| config.paragraphConfigs = []; | |
| config.currentChapterId = targetChapterId; | |
| config.currentContentFontSize = fontSize; | |
| config.currentContentFontSize = fontSize; | |
| config.currentContentLineSpacing = lineSpacing; | |
| config.currentContentParagraphSpacing = paragraphSpacing; | |
| /// 配置段落 | |
| ContentParagraphConfig paragraphConfig = ContentParagraphConfig(); | |
| paragraphConfig.paragraphLines = []; | |
| List<String> lines = List(); | |
| while (currentHeight < height) { | |
| /// 配置画笔 /// | |
| textPainter.text = TextSpan( | |
| text: tempTotalContent, style: TextStyle(fontSize: fontSize)); | |
| textPainter.layout(maxWidth: width); | |
| /// 如果最后一行再添一行比页面高度大,或者已经没有内容了,那么当前页面计算结束 | |
| if (currentHeight + fontSize + lineSpacing >= height || | |
| tempTotalContent.length == 0) { | |
| break; | |
| } | |
| /// 单行的偏移量 | |
| int endContentSingleLineOffset = | |
| textPainter.getPositionForOffset(Offset(width, 0)).offset; | |
| /// 当前一行的内容 | |
| String currentSingleLineContent = | |
| tempTotalContent.substring(0, endContentSingleLineOffset); | |
| /// 重置内容 | |
| tempTotalContent = tempTotalContent.substring( | |
| endContentSingleLineOffset, tempTotalContent.length); | |
| lines.add(currentSingleLineContent); | |
| /// 如果行开头是换行符,表示当前段落已经到了结尾,那么将当前段落配置加入到总配置中,并重置内容 | |
| if (tempTotalContent.startsWith("\n")) { | |
| /// 如果以换行符开头,那么删除换行符 | |
| tempTotalContent = | |
| tempTotalContent.substring(1, tempTotalContent.length); | |
| paragraphConfig.paragraphLines.addAll(lines); | |
| config.paragraphConfigs.add(paragraphConfig); | |
| paragraphConfig = ContentParagraphConfig(); | |
| paragraphConfig.paragraphLines = []; | |
| lines = List(); | |
| currentHeight += (fontSize + paragraphSpacing); | |
| } else { | |
| /// 改变当前计算高度 | |
| currentHeight += (fontSize + lineSpacing); | |
| } | |
| } | |
| if (lines != null && lines.length != 0) { | |
| paragraphConfig.paragraphLines = lines; | |
| config.paragraphConfigs.add(paragraphConfig); | |
| } | |
| pageConfigList.add(config); | |
| currentHeight = 0; | |
| } | |
| return pageConfigList; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment