sliding_window_indicator 0.1.0
sliding_window_indicator: ^0.1.0 copied to clipboard
A Flutter PageView line indicator with a sliding visible window of lines. Ideal for carousels and galleries with many pages.
import 'package:flutter/material.dart';
import 'package:sliding_window_indicator/sliding_window_indicator.dart';
void main() {
runApp(const SlidingWindowIndicatorDemo());
}
class SlidingWindowIndicatorDemo extends StatelessWidget {
const SlidingWindowIndicatorDemo({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'sliding_window_indicator',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF1B4DFF),
brightness: Brightness.light,
),
useMaterial3: true,
scaffoldBackgroundColor: const Color(0xFFF2F4F8),
),
home: const DemoHomePage(),
);
}
}
class DemoHomePage extends StatefulWidget {
const DemoHomePage({super.key});
@override
State<DemoHomePage> createState() => _DemoHomePageState();
}
class _DemoHomePageState extends State<DemoHomePage> {
static const _pageCount = 12;
late final PageController _controller;
@override
void initState() {
super.initState();
_controller = PageController();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
return Scaffold(
appBar: AppBar(
title: const Text('Sliding Window Indicator'),
centerTitle: false,
backgroundColor: scheme.surface,
surfaceTintColor: Colors.transparent,
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 8),
child: Text(
'Swipe the carousel. Only a few lines stay visible while the '
'window slides across many pages.',
style: Theme.of(
context,
).textTheme.bodyLarge?.copyWith(color: scheme.onSurfaceVariant),
),
),
Expanded(
child: PageView.builder(
controller: _controller,
itemCount: _pageCount,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 12,
),
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color.lerp(
scheme.primaryContainer,
scheme.secondaryContainer,
index / (_pageCount - 1),
)!,
Color.lerp(
scheme.secondaryContainer,
scheme.tertiaryContainer,
index / (_pageCount - 1),
)!,
],
),
),
child: Center(
child: Text(
'Page ${index + 1}',
style: Theme.of(context).textTheme.headlineMedium
?.copyWith(fontWeight: FontWeight.w700),
),
),
),
);
},
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20, 8, 20, 32),
child: Center(
child: SlidingWindowIndicator(
itemCount: _pageCount,
controller: _controller,
visibleLineCount: 4,
lineColor: scheme.outlineVariant,
lineSelectedColor: scheme.onSurface,
lineWidth: 36,
lineHeight: 3,
lineSpacing: 12,
lineBorderRadius: const BorderRadius.all(Radius.circular(2)),
),
),
),
],
),
);
}
}