-
-
Save johnmuchow/8f327e30f7b488a877472b96523d37bd to your computer and use it in GitHub Desktop.
PageView example with dots indicator
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
// Copyright 2017, the Flutter project authors. Please see the AUTHORS file | |
// for details. All rights reserved. Use of this source code is governed by a | |
// BSD-style license that can be found in the LICENSE file. | |
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
home: MyHomePage(), | |
debugShowCheckedModeBanner: false, | |
); | |
} | |
} | |
/// An indicator showing the currently selected page of a PageController | |
class DotsIndicator extends AnimatedWidget { | |
DotsIndicator({ | |
this.controller, | |
this.itemCount, | |
this.onPageSelected, | |
this.color: Colors.white, | |
}) : super(listenable: controller); | |
/// The PageController that this DotsIndicator is representing. | |
final PageController controller; | |
/// The number of items managed by the PageController | |
final int itemCount; | |
/// Called when a dot is tapped | |
final ValueChanged<int> onPageSelected; | |
/// The color of the dots. | |
/// | |
/// Defaults to `Colors.white`. | |
final Color color; | |
// The base size of the dots | |
static const double _kDotSize = 8.0; | |
// The increase in the size of the selected dot | |
static const double _kMaxZoom = 2.0; | |
// The distance between the center of each dot | |
static const double _kDotSpacing = 25.0; | |
Widget _buildDot(int index) { | |
double selectedness = Curves.easeOut.transform( | |
max( | |
0.0, | |
1.0 - ((controller.page ?? controller.initialPage) - index).abs(), | |
), | |
); | |
double zoom = 1.0 + (_kMaxZoom - 1.0) * selectedness; | |
return Container( | |
width: _kDotSpacing, | |
child: Center( | |
child: Material( | |
color: color, | |
type: MaterialType.circle, | |
child: Container( | |
width: _kDotSize * zoom, | |
height: _kDotSize * zoom, | |
child: InkWell( | |
onTap: () => onPageSelected(index), | |
), | |
), | |
), | |
), | |
); | |
} | |
Widget build(BuildContext context) { | |
return Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: List<Widget>.generate(itemCount, _buildDot), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
@override | |
State createState() => MyHomePageState(); | |
} | |
class MyHomePageState extends State<MyHomePage> { | |
final _controller = PageController(); | |
static const _kDuration = const Duration(milliseconds: 300); | |
static const _kCurve = Curves.ease; | |
final _kArrowColor = Colors.black.withOpacity(0.8); | |
final List<Widget> _pages = <Widget>[ | |
ConstrainedBox( | |
constraints: const BoxConstraints.expand(), | |
child: FlutterLogo(colors: Colors.blue), | |
), | |
ConstrainedBox( | |
constraints: const BoxConstraints.expand(), | |
child: FlutterLogo(style: FlutterLogoStyle.stacked, colors: Colors.red), | |
), | |
ConstrainedBox( | |
constraints: const BoxConstraints.expand(), | |
child: FlutterLogo(style: FlutterLogoStyle.horizontal, colors: Colors.green), | |
), | |
]; | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: IconTheme( | |
data: IconThemeData(color: _kArrowColor), | |
child: Stack( | |
children: <Widget>[ | |
PageView.builder( | |
physics: AlwaysScrollableScrollPhysics(), | |
controller: _controller, | |
itemBuilder: (BuildContext context, int index) { | |
return _pages[index % _pages.length]; | |
}, | |
), | |
Positioned( | |
bottom: 0.0, | |
left: 0.0, | |
right: 0.0, | |
child: Container( | |
color: Colors.grey[800].withOpacity(0.5), | |
padding: const EdgeInsets.all(20.0), | |
child: Center( | |
child: DotsIndicator( | |
controller: _controller, | |
itemCount: _pages.length, | |
onPageSelected: (int page) { | |
_controller.animateToPage( | |
page, | |
duration: _kDuration, | |
curve: _kCurve, | |
); | |
}, | |
), | |
), | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Removed the new keyword as it's no longer needed