Flutter分页文本展示插件paginated_text的使用
Flutter分页文本展示插件paginated_text的使用
简介
paginated_text
是一个Flutter插件,提供了分页文本视图,并且可以选择自动调整大小的首字下沉效果。该插件允许你根据需要自定义动画和控件,同时提供了一个控制器和一个带有构建器的Widget,但你也可以创建自己的自定义Widget。
功能特性
- 自动分页:文本会根据Widget的布局大小自动分页。
- 自定义动画和控件:你可以使用任何你喜欢的动画和控件,或者完全不使用动画。
- 首字下沉:
- 首字可以是自动定位和调整大小的下沉字母。
- 计算并缓存了下沉字母和正文字体的实际字母高度(使用字母’Z’)。
- 下沉字母的基线可以对齐到第n行文本的基线(通过
capLines
配置)。 - 下沉字母的顶部与第一行文本的顶部对齐。
- 注意:此方法目前对哥特式、手写体或书法字体效果不佳。
- 解析内联Markdown:支持解析内联Markdown(从
drop_cap_text
包中继承)。 - 自动分页:可以根据不同的规则自动分页。
enum PageBreak {
/// 在页面的最后一可见单词处断页
word,
/// 尝试在句号、逗号、分号或破折号处断页
sentenceFragment,
/// 尝试在句子结束处断页
sentence,
/// 尝试在段落(两个连续的换行符)处断页
paragraph;
}
使用方法
paginated_text
插件没有其他依赖,只需要Dart 3 / Flutter 3 和 collection
包。以下是基本的使用示例:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:paginated_text/paginated_text.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
final text = pwp.trim(); // 示例文本
final style = GoogleFonts.notoSerif(fontSize: 36, height: 1.5); // 正文样式
final dropCapStyle = GoogleFonts.calligraffitti(); // 下沉字母样式
return MaterialApp(
themeMode: ThemeMode.dark,
theme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: PaginatedExample(
text: text,
style: style,
dropCapStyle: dropCapStyle,
),
),
);
}
}
class PaginatedExample extends StatefulWidget {
const PaginatedExample({
super.key,
required this.text,
required this.style,
required this.dropCapStyle,
});
final String text;
final TextStyle style;
final TextStyle dropCapStyle;
[@override](/user/override)
State<PaginatedExample> createState() => _PaginatedExampleState();
}
class _PaginatedExampleState extends State<PaginatedExample>
with SingleTickerProviderStateMixin {
late Future _googleFontsPending;
late PaginatedController _controller;
[@override](/user/override)
void dispose() {
_controller.dispose();
super.dispose();
}
[@override](/user/override)
void initState() {
super.initState();
_controller = PaginatedController(PaginateData(
text: widget.text,
dropCapLines: 3, // 下沉字母占据的行数
style: widget.style,
dropCapStyle: widget.dropCapStyle,
pageBreakType: PageBreakType.paragraph, // 分页类型
breakLines: 1, // 分页时保留的空白行数
resizeTolerance: 3, // 字体调整容差
parseInlineMarkdown: true, // 解析内联Markdown
));
_googleFontsPending = GoogleFonts.pendingFonts([
widget.style,
widget.dropCapStyle,
]);
}
[@override](/user/override)
Widget build(BuildContext context) {
return FutureBuilder(
future: _googleFontsPending,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const CircularProgressIndicator.adaptive();
}
final reverse = _controller.pageIndex < _controller.previousPageIndex;
return Padding(
padding: const EdgeInsets.all(16),
child: PaginatedText(
_controller,
builder: (context, child) {
return DefaultTextStyle(
style: widget.style,
child: Column(
children: [
Text('The Promise of World Peace',
style: widget.dropCapStyle.copyWith(
fontSize: 40, fontStyle: FontStyle.italic)),
Expanded(
child: PageTransitionSwitcher(
duration: const Duration(seconds: 1),
reverse: reverse,
transitionBuilder:
(child, primaryAnimation, secondaryAnimation) {
const offscreen = Offset(-1.5, 0.0);
return SlideTransition(
position: Tween<Offset>(
begin: Offset.zero,
end: offscreen,
).animate(secondaryAnimation),
child: FadeTransition(
opacity: Tween<double>(
begin: 0.0,
end: 1.0,
).animate(primaryAnimation),
child: child,
),
);
},
child: Padding(
key: ValueKey(_controller.currentPage.pageIndex),
padding: const EdgeInsets.all(40),
child: SelectionArea(child: child),
),
),
),
const SizedBox(height: 20),
Text(
'Page ${_controller.pageNumber} of ${_controller.numPages}',
style: widget.style.copyWith(fontSize: 24)),
const SizedBox(height: 20),
ButtonBar(
alignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: _controller.isFirst
? null
: () {
setState(() {
_controller.previous();
});
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child:
Text('Prev', style: TextStyle(fontSize: 30)),
),
),
TextButton(
onPressed: _controller.isLast
? null
: () {
setState(() {
_controller.next();
});
},
child: const Padding(
padding: EdgeInsets.all(8.0),
child:
Text('Next', style: TextStyle(fontSize: 30)),
),
),
],
),
],
),
);
},
),
);
});
}
}
更多关于Flutter分页文本展示插件paginated_text的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter分页文本展示插件paginated_text的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用paginated_text
插件来实现分页文本展示的示例代码。这个插件允许你在一个页面上显示长文本,并允许用户通过滑动来浏览不同的页面。
首先,你需要在你的pubspec.yaml
文件中添加paginated_text
依赖:
dependencies:
flutter:
sdk: flutter
paginated_text: ^x.y.z # 请替换为最新的版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在你的Dart文件中使用PaginatedText
小部件。下面是一个完整的示例代码:
import 'package:flutter/material.dart';
import 'package:paginated_text/paginated_text.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Paginated Text Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Paginated Text Example'),
),
body: Center(
child: PaginatedTextExample(),
),
),
);
}
}
class PaginatedTextExample extends StatefulWidget {
@override
_PaginatedTextExampleState createState() => _PaginatedTextExampleState();
}
class _PaginatedTextExampleState extends State<PaginatedTextExample> {
final String longText = """
这是一个很长的文本示例,用于展示paginated_text插件的分页功能。
你可以在这里添加任意长度的文本内容,paginated_text会自动将其分页显示。
每一页的内容会根据屏幕大小自动调整,以提供最佳的阅读体验。
继续添加一些内容,以确保文本足够长,能够展示分页效果。
分页功能在处理长文档或电子书时特别有用,用户可以轻松地在页面上滑动浏览。
希望这个示例能够帮助你理解如何使用paginated_text插件。
如果你有任何问题或建议,请随时与我们联系。
""";
@override
Widget build(BuildContext context) {
return PaginatedText(
text: longText,
style: TextStyle(fontSize: 18),
builder: (context, state) {
return Padding(
padding: EdgeInsets.all(16.0),
child: state.widget,
);
},
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个PaginatedText
小部件。PaginatedText
小部件接受以下参数:
text
:要显示的文本内容。style
:文本的样式。builder
:一个可选的builder函数,允许你对分页文本的布局进行自定义。在这个例子中,我们使用了Padding
来添加一些内边距。
运行这个应用,你会看到一个长文本被分页显示,并且你可以通过滑动来浏览不同的页面。
请注意,这个示例代码仅展示了paginated_text
插件的基本用法。根据实际需求,你可以进一步自定义和扩展这个插件的功能。