This article uses an example of PageView to reinforce the impression, and in future columns, we’ll expand on this example to create an image Banner that slides up, down, left, and right indefinitely, and teach you how to make it into a Dart Library and open it to others.
Unlimited sliding PageView
Before implementing the PageView indicator, we need to implement a PageView first. Implementing a PageView in Flutter is simple.
class BannerGalleryWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return BannerGalleryWidgetState();
}
}
class BannerGalleryWidgetState extends State<BannerGalleryWidget> {
final PageController controller = PageController(initialPage: 200);
@override
Widget build(BuildContext context) {
returnSizedBox(height: 250.0, Child: Container(color: colors. grey, child: pageView. builder(Controller: controller, itemBuilder: (context, index) {return new Center(
child: new Text('page ${index}')); },),)); }}Copy the code
The above code produces an interface like this. To explain the code a bit:
Final PageController Controller = PageController(initialPage: 200); SizedBox(height: 250.0) /// a Container that sets the background color to gray. Color.grey) /// the main PageView, with the text centered to show the current index. PageView.builder( controller: controller, itemBuilder: (context, index) {return new Center(
child: new Text('page ${index}')); },),Copy the code
Implement an indicator
Now that we have an infinite sliding PageView, let’s associate another indicator:
class Indicator extends StatelessWidget { Indicator({ this.controller, this.itemCount: 0, }) : assert(controller ! = null); /// PageView controller final PageController controller; Final int itemCount; // final Color normalColor = color.blue; /// final Color selectedColor = color.red; /// Final double size = 8.0; /// Final double spacing = 4.0; /// dot Widget _buildIndicator(int index, int pageCount, double dotSize, {// Whether the current page is selected bool isCurrentPageSelected = index == (controller.page! = null ? controller.page.round() % pageCount : 0);return new Container(
height: size,
width: size + (2 * spacing),
child: new Center(
child: new Material(
color: isCurrentPageSelected ? selectedColor : normalColor,
type: MaterialType.circle,
child: new Container(
width: dotSize,
height: dotSize,
),
),
),
);
}
@override
Widget build(BuildContext context) {
return new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: new List<Widget>.generate(itemCount, (int index) {
return_buildIndicator(index, itemCount, size, spacing); })); }}Copy the code
This code is relatively simple and builds a horizontal List inside the build() method. The Item of the List is a fixed size dot, selected is one color, not selected is another color.
3. Associate PageView with indicator
class BannerGalleryWidgetState2 extends State<BannerGalleryWidget2> {
final PageController controller = PageController(initialPage: 200);
void _pageChanged(int index) {
setState(() {});
}
@override
Widget build(BuildContext context) {
returnColumn(children: <Widget>[SizedBox(height: 150.0, child: Container(color: Colors. Grey, child: PageView.builder( onPageChanged: _pageChanged, controller: controller, itemBuilder: (context, index) {return new Center(
child: new Text('page ${index}')); }, ), )), Indicator( controller: controller, itemCount: 5, ), ], ); }}Copy the code
Change the layout container, wrap PageView and Indicator with a column, attach an onPageChanged to PageView, and check that setState() refreshes the UI when the page changes.
At this point, the unlimited sliding PageView indicator is complete, and although it looks a little different from the example image at the beginning of the column, it is at least fulfilled. But right now the indicator is silly, for example, it changes color only after it is selected and it doesn’t zoom in. In future columns, I’ll show you how to improve this indicator and provide complete code for the entire project.