Flutter页面指示器插件faabul_page_indicator的使用
Flutter页面指示器插件faabul_page_indicator的使用
faabul_page_indicator 是由 Faabul Live Quizzes 开发和使用的插件。
另一个点指示器?
我们创建了这个包,因为它能满足以下需求:
- 支持自定义“点”构建器
- 在页数过多且指示器空间受限的情况下,具有良好的用户体验
- 同时支持LTR(从左到右)和RTL(从右到左)语言环境
- 具有良好的性能
使用方法
请参阅 示例 获取完整的示例代码。
只需将指示器传递给现有的控制器和页面数量,即可显示默认的点指示器:
late final _controller = PageController();
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: PageView.builder(
itemCount: 20,
itemBuilder: _buildPage,
controller: _controller,
),
),
FaabulPageIndicator(
itemCount: 20,
controller: _controller,
),
],
);
}
指示器会自动处理溢出情况,并在页面之间进行点击导航。
如果你需要不同的样式或功能,可以传递一个自定义构建器。你可以使用默认的 FaabulPageIndicatorDot
或任何你喜欢的小部件。
FaabulPageIndicator(
itemCount: 20,
itemSize: Size(30, 30),
controller: _controller,
itemBuilder: (BuildContext context, int index, int? currentPage) =>
FaabulPageIndicatorDot(
key: ValueKey(index),
size: 30,
decoration: index == currentPage
? BoxDecoration(
border: Border.all(
color: colorScheme.primary, width: 2),
borderRadius: BorderRadius.circular(8),
color: colorScheme.primaryContainer,
)
: BoxDecoration(
border: Border.all(
color: colorScheme.outlineVariant,
width: 2),
borderRadius: BorderRadius.circular(4),
),
isActive: index == currentPage,
onTap: () => _controller.jumpToPage(index),
),
)
你也可以传递任何小部件,使每个“点”独一无二:
使用自定义构建器时,请确保渲染的点大小与 itemSize
属性相对应。
性能
FaabulPageIndicator 针对性能进行了优化。它内部使用了 ListView.builder
来显示点。这意味着只有可见的点才会被渲染,并且该指示器可以处理大量页面而不会出现性能下降。内部指示器仅在实际页面(作为整数)在 PageController
中发生变化时才进行工作。
实时查看
你可以在 Faabul Live Quizzes 应用中实时查看指示器的效果。每次玩测验时都可以看到。
完整示例代码
以下是完整的示例代码,展示了如何使用 faabul_page_indicator 插件:
import 'package:faabul_page_indicator/faabul_page_indicator.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
late final headlineStyle = Theme.of(context).textTheme.headlineMedium;
late final colorScheme = Theme.of(context).colorScheme;
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: SafeArea(
bottom: false,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 600),
child: SingleChildScrollView(
padding: const EdgeInsets.all(32),
child: Column(
children: [
Text('3 pages', style: headlineStyle),
const _PageView(pages: 3),
const Divider(height: 64),
Text('42 pages', style: headlineStyle),
const _PageView(pages: 42, initialPage: 21),
const Divider(height: 64),
Text('Customized FaabulPageIndicatorDot', style: headlineStyle),
_PageView(
pages: 16,
initialPage: 0,
size: 30,
itemBuilder: (
BuildContext context,
int index,
int? currentPage,
) => FaabulPageIndicatorDot(
key: ValueKey(index),
size: 30,
decoration: index == currentPage
? BoxDecoration(
border: Border.all(
color: colorScheme.primary, width: 2),
borderRadius: BorderRadius.circular(8),
color: colorScheme.primaryContainer,
)
: BoxDecoration(
border: Border.all(
color: colorScheme.outlineVariant,
width: 2),
borderRadius: BorderRadius.circular(4),
),
isActive: index == currentPage,
)),
const Divider(height: 64),
Text('Custom builder', style: headlineStyle),
_PageView(
pages: 42,
initialPage: 21,
size: 44,
itemBuilder: (
BuildContext context,
int index,
int? currentPage,
) => _Dot(
key: ValueKey(index),
shape: index.isEven
? BoxShape.circle
: BoxShape.rectangle,
isActive: index == currentPage,
child: Center(
child: Text('$index',
style: TextStyle(
fontSize: 16,
color: index == currentPage
? colorScheme.onPrimary
: colorScheme
.onSecondaryContainer)),
),
)),
const Divider(height: 64),
Text('A million pages', style: headlineStyle),
const _PageView(
pages: 1000000,
initialPage: 500000,
),
const Divider(height: 64),
Directionality(
textDirection: TextDirection.rtl,
child: Column(
children: [
Text('An RTL PageView', style: headlineStyle),
const _PageView(pages: 42, initialPage: 21),
],
),
),
],
),
),
),
),
),
),
);
}
}
class _PageView extends StatefulWidget {
final int pages;
final int? initialPage;
final FaabulDotIndicatorItemBuilder? itemBuilder;
final double size;
const _PageView({
required this.pages,
this.initialPage,
this.itemBuilder,
this.size = 20.0,
});
[@override](/user/override)
State<_PageView> createState() => __PageViewState();
}
class __PageViewState extends State<_PageView> {
late final _controller = PageController(
viewportFraction: 0.8, initialPage: widget.initialPage ?? 0);
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 300,
child: PageView.builder(
itemCount: widget.pages,
itemBuilder: _buildPage,
controller: _controller,
),
),
FaabulPageIndicator(
itemBuilder: widget.itemBuilder,
itemSize: Size(widget.size, widget.size),
itemCount: widget.pages,
controller: _controller,
),
],
);
}
Widget? _buildPage(BuildContext context, int index) {
return Card(
margin: const EdgeInsets.all(32),
color: index.isEven ? Colors.red : Colors.blue,
child: Center(
child: Text(
'Page $index',
style: const TextStyle(fontSize: 32),
),
),
);
}
}
class _Dot extends StatelessWidget {
final BoxShape shape;
final Widget child;
final bool isActive;
const _Dot(
{required super.key,
required this.shape,
required this.child,
required this.isActive});
[@override](/user/override)
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return SizedBox(
width: 44,
height: 44,
child: Center(
child: AnimatedContainer(
duration: Durations.long2,
curve: Curves.easeInOut,
width: isActive ? 40 : 32,
height: isActive ? 40 : 32,
decoration: BoxDecoration(
color:
isActive ? colorScheme.primary : colorScheme.secondaryContainer,
shape: shape,
),
child: child,
)),
);
}
}
更多关于Flutter页面指示器插件faabul_page_indicator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter页面指示器插件faabul_page_indicator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用faabul_page_indicator
插件的一个示例。faabul_page_indicator
是一个流行的页面指示器插件,用于在分页视图中显示小圆点或其他样式的指示器。
首先,确保你已经在pubspec.yaml
文件中添加了faabul_page_indicator
依赖:
dependencies:
flutter:
sdk: flutter
faabul_page_indicator: ^latest_version # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Dart文件中,你可以使用FaabulPageIndicator
来创建一个页面指示器。下面是一个完整的示例,展示了如何结合PageView
和FaabulPageIndicator
来实现分页视图和指示器。
import 'package:flutter/material.dart';
import 'package:faabul_page_indicator/faabul_page_indicator.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Faabul Page Indicator Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
final PageController _pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Faabul Page Indicator Example'),
),
body: Column(
children: <Widget>[
Expanded(
child: PageView(
controller: _pageController,
children: <Widget>[
Center(child: Text('Page 1')),
Center(child: Text('Page 2')),
Center(child: Text('Page 3')),
],
),
),
FaabulPageIndicator(
controller: _pageController,
itemCount: 3,
indicatorSpace: 10.0,
indicatorColor: Colors.grey,
activeIndicatorColor: Colors.blue,
indicatorSize: 8.0,
activeIndicatorSize: 12.0,
shape: IndicatorShape.circle, // 可以选择其他形状,比如 IndicatorShape.roundRect
),
],
),
);
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
}
在这个示例中:
- 我们创建了一个
PageView
,它包含三个页面,每个页面都显示一个居中的文本。 - 我们使用
FaabulPageIndicator
作为页面指示器,并传递了PageController
来控制分页视图。 FaabulPageIndicator
的各种属性,如indicatorColor
、activeIndicatorColor
、indicatorSize
和activeIndicatorSize
,允许我们自定义指示器的外观。indicatorSpace
属性控制指示器之间的间距。shape
属性允许我们选择指示器的形状。
确保你已经正确导入了faabul_page_indicator
包,并根据需要调整属性和样式。这样,你就可以在你的Flutter应用中使用faabul_page_indicator
来实现漂亮的页面指示器了。