width默认屏幕宽度,可设置高度。

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'cf_banner_indicator.dart';
typedef GetWidgetCallback = Widget Function(int index);
///width默认为屏幕宽度
class CfBanner extends StatefulWidget {
final int length;
final GetWidgetCallback callback;
final double height;
final Widget selectorWidget;
final Widget normalWidget;
final bool autoLoop;
final bool showIndicator;
final bool spaceMode;
CfBanner(
{Key key,
this.length,
this.callback,
@required this.height,
this.selectorWidget,
this.normalWidget,
this.autoLoop = true,
this.showIndicator = true,
this.spaceMode = true});
@override
State<StatefulWidget> createState() {
return _CfBannerState();
}
}
class _CfBannerState extends State<CfBanner> {
@override
void didUpdateWidget(CfBanner oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
void deactivate() {
super.deactivate();
}
@override
void dispose() {
super.dispose();
if (_timer != null) {
_timer.cancel();
}
}
PageController _pageController;
int _currentIndex = 100;
Timer _timer;
//设置定时器
_setTimer() {
if (_timer != null) {
return;
}
_timer = Timer.periodic(Duration(seconds: 5), (_) {
_pageController.animateToPage(_currentIndex + 1,
duration: Duration(milliseconds: 400), curve: Curves.easeOut);
});
}
@override
Widget build(BuildContext context) {
return getBanner2();
}
int bannerMax = 10000000000;
double currentWidth = 0;
CfBannerIndicator indicator;
GlobalKey<CfBannerIndicatorState> indicatorKey =
GlobalKey<CfBannerIndicatorState>();
double viewportFractionCustom = 1;
double paddingCustom = 0;
Widget getBanner2() {
if (widget.spaceMode) {
viewportFractionCustom = 0.925;
paddingCustom = 0.0125;
}
currentWidth = MediaQuery.of(context).size.width;
if (widget.length > 0 && _pageController == null) {
_pageController = new PageController(
initialPage: widget.length * 100,
viewportFraction: viewportFractionCustom);
_currentIndex = widget.length * 100;
if (widget.autoLoop) {
_setTimer();
}
}
if (widget.length == 0) {
return Container();
}
PageView pageView = new PageView.builder(
itemBuilder: ((context, index) {
GlobalKey _key = new GlobalKey();
Container container = Container(
key: _key,
//左右两个padding
margin: EdgeInsets.only(
left: currentWidth * paddingCustom,
right: currentWidth * paddingCustom),
width: currentWidth,
height: widget.height,
child: widget.callback(index % widget.length),
);
return container;
}),
itemCount: bannerMax,
scrollDirection: Axis.horizontal,
reverse: false,
controller: _pageController,
physics: PageScrollPhysics(parent: BouncingScrollPhysics()),
onPageChanged: ((index) {
_currentIndex = index;
if (indicatorKey.currentState != null) {
indicatorKey.currentState
.updateWidgets(widget.length, (_currentIndex) % widget.length);
} else {}
}),
);
if (widget.showIndicator) {
indicator = CfBannerIndicator(
normalWidget: widget.normalWidget,
selectorWidget: widget.selectorWidget,
key: indicatorKey,
length: widget.length,
select: (_currentIndex) % widget.length,
);
}
return Container(
width: MediaQuery.of(context).size.width,
height: widget.height,
child: Stack(
children: <Widget>[pageView, _getIndicator()],
),
);
}
Widget _getIndicator() {
if (widget.showIndicator) {
return Positioned(
bottom: currentWidth * 0.02,
left: 0,
right: 0,
child: indicator,
);
} else {
return Container();
}
}
}
指示器
import 'package:flutter/material.dart';
class CfBannerIndicator extends StatefulWidget {
int length;
int select;
final Widget selectorWidget;
final Widget normalWidget;
CfBannerIndicator(
{Key key,
this.length,
this.select,
this.selectorWidget,
this.normalWidget})
: super(key: key);
@override
State<StatefulWidget> createState() {
return CfBannerIndicatorState();
}
}
class CfBannerIndicatorState extends State<CfBannerIndicator> {
List<Widget> points() {
List<Widget> list;
for (var i = 0; i < widget.length; i++) {
if (list == null) {
list = new List();
}
list.add(_getWidget(i));
}
if (list == null) {
list = new List();
list.add(Container());
}
return list;
}
Widget _getWidget(int i) {
int index = widget.select;
if (index == i) {
if (widget.selectorWidget != null) {
return widget.selectorWidget;
}
return Container(
margin: EdgeInsets.only(left: 0.5, right: 0.5),
child: Image.asset(
"images/banner_select_true.png",
height: 10,
width: 15,
),
);
} else {
if (widget.normalWidget != null) {
return widget.normalWidget;
}
return Container(
margin: EdgeInsets.only(left: 0.5, right: 0.5),
child: Image.asset(
"images/banner_select_false.png",
height: 5,
width: 10,
),
);
}
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: points(),
);
}
updateWidgets(int length, int select) {
widget.length = length;
widget.select = select;
setState(() {});
}
}
网友评论