Flutter开发之PageView指示器(31)

it2022-05-05  227

移动开发中圆点指示器给用户很好的用户体验,iOS 有自己的控件UIPageControl 方便快捷实现。既然想用Flutter代替,就想着如何实现UIPageControl 类似的功能。这篇文章就在前辈的基础上,实战一下PageView指示器。来实现圆点指示器的功能。(文章结尾会贴上参考的文章)

先看一下效果

完整代码:

import 'dart:math'; import 'package:flutter/material.dart'; class PageControlTest extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('DemoList'), ), body: new MyHomePage(), ); } } /// 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,int pageCount) { // 当前位置 double currentPosition = ((controller.page ?? controller.initialPage.toDouble()) % pageCount.toDouble()); // 计算变化曲线 double selectedness = Curves.easeOut.transform( max( 0.0, 1.0 - (currentPosition - index).abs(), ), ); // 从0点跳到最后一个时状态需要特殊处理 if (currentPosition > pageCount - 1 && index == 0) { selectedness = 1 - (pageCount.toDouble() - currentPosition); } print('selectedness $index'); print('selectedness $selectedness'); print('selectedness $controller.page'); print('selectedness $controller.initialPage'); // 计算缩放大小 double zoom = 1.0 + (_kMaxZoom - 1.0) * selectedness; return new Container( width: _kDotSpacing, child: new Center( child: new Material( color: color, type: MaterialType.circle, child: new Container( width: _kDotSize * zoom, height: _kDotSize * zoom, child: new InkWell( onTap: () => onPageSelected(index), ), ), ), ), ); } Widget build(BuildContext context) { return new Row( mainAxisAlignment: MainAxisAlignment.center, children: new List<Widget>.generate(itemCount,(int index) { return _buildDot(index, itemCount); }), ); } } class MyHomePage extends StatefulWidget { @override State createState() => new MyHomePageState(); } class MyHomePageState extends State<MyHomePage> { final _controller = new 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>[ new ConstrainedBox( constraints: const BoxConstraints.expand(), child: new FlutterLogo(colors: Colors.blue), ), new ConstrainedBox( constraints: const BoxConstraints.expand(), child: new FlutterLogo(style: FlutterLogoStyle.stacked, colors: Colors.red), ), new ConstrainedBox( constraints: const BoxConstraints.expand(), child: new FlutterLogo(style: FlutterLogoStyle.horizontal, colors: Colors.green), ), ]; @override Widget build(BuildContext context) { return new Scaffold( // appBar: new AppBar( // title: new Text('PageControl'), // ), body: Center( child:new IconTheme( data: new IconThemeData(color: _kArrowColor), child: new Stack( children: <Widget>[ new PageView.builder( physics: new AlwaysScrollableScrollPhysics(), controller: _controller, itemBuilder: (BuildContext context, int index) { return _pages[index % _pages.length]; }, ), new Positioned( bottom: 0.0, left: 0.0, right: 0.0, child: new Container( color: Colors.grey[800].withOpacity(0.5), padding: const EdgeInsets.all(20.0), child: new Center( child: new DotsIndicator( controller: _controller, itemCount: _pages.length, onPageSelected: (int page) { _controller.animateToPage( page, duration: _kDuration, curve: _kCurve, ); }, ), ), ), ), ], ), ), ) ); } }

BannerGalleryInFlutter

这是一个多样化定制的轮播图,实现无限滑动Banner。

参考文章

Flutter pageview切换指示器 flutter PageView实现左右滑动切换视图


最新回复(0)