如何在 Flutter 中使用 PageView 创建轮播(滑动动画)?
How to create a carrousel (sliding animation) with PageView in Flutter?
我想用图像创建滑块动画,还想允许用户使用滑动手势来回移动。另一个要求是页面指示器。为此,我使用了
page_indicator: ^0.1.3
目前我可以使用带有页面指示器的滑动手势在图像之间滑动,现在我想以 x 的持续时间重复设置幻灯片动画。
我的代码如下。
final PageController controller = new PageController();
@override
Widget build(BuildContext context) {
List<Widget> list = new List<Widget>();
list.add(new SliderBox(image: 'assets/shirt.png'));
list.add(new SliderBox(image: 'assets/laptops.png'));
list.add(new SliderBox(image: 'assets/bags.png'));
PageIndicatorContainer container = new PageIndicatorContainer(
pageView: new PageView(
children: list,
controller: controller,
),
length: 3,
padding: EdgeInsets.fromLTRB(10, 40, 10, 10),
indicatorSpace: 10,
indicatorColor: Colors.grey[350],
indicatorSelectorColor: Colors.grey,
);
return Stack(children: <Widget>[
Container(color: Colors.grey[100], height: double.infinity),
Container(
color: Colors.white,
child: container,
margin: EdgeInsets.only(bottom: 50)),Text('$moveToPage')
]);
class SliderBox extends StatelessWidget {
final image;
const SliderBox({Key key, this.image}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
padding: EdgeInsets.all(10),
child: Image.asset(
image,
height: 300,
fit: BoxFit.fill,
));
}
}
我对您的小部件进行了一些修改,以便为您提供一个完整的示例。您可以通过多种方式执行此操作,使用 AnimationController by itself or even combined with a custom Animation 或者,您可以采用最快的方式来实现您想要实现的目标:使用递归方法等待 x 持续时间(单页时间)然后为新页面设置一些新的持续时间。为此,您可以例如:
使您的 List
在 state
本身内可用,以便检索其长度。
创建将处理动画本身的递归方法。
确保在屏幕上呈现第一帧后调用它,以防止 PageController
在 PageView
呈现在屏幕上之前被访问,这你可能不想要。为此,您可以利用 WidgetsBinding.instance.addPostFrameCallback.
class Carousel extends StatefulWidget {
_CarouselState createState() => _CarouselState();
}
class _CarouselState extends State<Carousel> with SingleTickerProviderStateMixin {
final PageController _controller = PageController();
List<Widget> _list = [
SliderBox(
child: FlutterLogo(
colors: Colors.red,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.green,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.blue,
))
];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _animateSlider());
}
void _animateSlider() {
Future.delayed(Duration(seconds: 2)).then((_) {
int nextPage = _controller.page.round() + 1;
if (nextPage == _list.length) {
nextPage = 0;
}
_controller
.animateToPage(nextPage, duration: Duration(seconds: 1), curve: Curves.linear)
.then((_) => _animateSlider());
});
}
@override
Widget build(BuildContext context) {
PageIndicatorContainer container = new PageIndicatorContainer(
pageView: new PageView(
children: _list,
controller: _controller,
),
length: _list.length,
padding: EdgeInsets.fromLTRB(10, 40, 10, 10),
indicatorSpace: 10,
indicatorColor: Colors.grey[350],
indicatorSelectorColor: Colors.grey,
);
return Stack(
children: <Widget>[
Container(color: Colors.grey[100], height: double.infinity),
Container(color: Colors.white, child: container, margin: EdgeInsets.only(bottom: 50)),
],
);
}
}
class SliderBox extends StatelessWidget {
final Widget child;
const SliderBox({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(padding: EdgeInsets.all(10), child: child);
}
}
将 Worm Indicator 与 PageView 一起使用以显示滚动进度
在你的flutter项目中添加lib依赖
dependencies:
worm_indicator: 0.1.1
使用
WormIndicator(
length: PAGE_VIEW_SIZE,
controller: PAGE_VIEW_CONTROLLER,
size: DOT_SIZE_IN_PT,
spacing: DOT_SPACING_IN_PT,
),
Circle
和方形 DotShape
需要尺寸。 Rectangle
DotShape
需要宽度和高度。
WormIndicator(
length: 3,
controller: _controller,
shape: Shape(
size: 16,
spacing: 8,
shape: DotShape.Circle // Similar for Square
),
),
WormIndicator(
length: 3,
controller: _controller,
shape: Shape(
width: 16,
height: 24,
spacing: 8,
shape: DotShape.Rectangle
),
),
我想用图像创建滑块动画,还想允许用户使用滑动手势来回移动。另一个要求是页面指示器。为此,我使用了
page_indicator: ^0.1.3
目前我可以使用带有页面指示器的滑动手势在图像之间滑动,现在我想以 x 的持续时间重复设置幻灯片动画。 我的代码如下。
final PageController controller = new PageController();
@override
Widget build(BuildContext context) {
List<Widget> list = new List<Widget>();
list.add(new SliderBox(image: 'assets/shirt.png'));
list.add(new SliderBox(image: 'assets/laptops.png'));
list.add(new SliderBox(image: 'assets/bags.png'));
PageIndicatorContainer container = new PageIndicatorContainer(
pageView: new PageView(
children: list,
controller: controller,
),
length: 3,
padding: EdgeInsets.fromLTRB(10, 40, 10, 10),
indicatorSpace: 10,
indicatorColor: Colors.grey[350],
indicatorSelectorColor: Colors.grey,
);
return Stack(children: <Widget>[
Container(color: Colors.grey[100], height: double.infinity),
Container(
color: Colors.white,
child: container,
margin: EdgeInsets.only(bottom: 50)),Text('$moveToPage')
]);
class SliderBox extends StatelessWidget {
final image;
const SliderBox({Key key, this.image}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
padding: EdgeInsets.all(10),
child: Image.asset(
image,
height: 300,
fit: BoxFit.fill,
));
}
}
我对您的小部件进行了一些修改,以便为您提供一个完整的示例。您可以通过多种方式执行此操作,使用 AnimationController by itself or even combined with a custom Animation 或者,您可以采用最快的方式来实现您想要实现的目标:使用递归方法等待 x 持续时间(单页时间)然后为新页面设置一些新的持续时间。为此,您可以例如:
使您的
List
在state
本身内可用,以便检索其长度。创建将处理动画本身的递归方法。
确保在屏幕上呈现第一帧后调用它,以防止
PageController
在PageView
呈现在屏幕上之前被访问,这你可能不想要。为此,您可以利用 WidgetsBinding.instance.addPostFrameCallback.
class Carousel extends StatefulWidget {
_CarouselState createState() => _CarouselState();
}
class _CarouselState extends State<Carousel> with SingleTickerProviderStateMixin {
final PageController _controller = PageController();
List<Widget> _list = [
SliderBox(
child: FlutterLogo(
colors: Colors.red,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.green,
)),
SliderBox(
child: FlutterLogo(
colors: Colors.blue,
))
];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => _animateSlider());
}
void _animateSlider() {
Future.delayed(Duration(seconds: 2)).then((_) {
int nextPage = _controller.page.round() + 1;
if (nextPage == _list.length) {
nextPage = 0;
}
_controller
.animateToPage(nextPage, duration: Duration(seconds: 1), curve: Curves.linear)
.then((_) => _animateSlider());
});
}
@override
Widget build(BuildContext context) {
PageIndicatorContainer container = new PageIndicatorContainer(
pageView: new PageView(
children: _list,
controller: _controller,
),
length: _list.length,
padding: EdgeInsets.fromLTRB(10, 40, 10, 10),
indicatorSpace: 10,
indicatorColor: Colors.grey[350],
indicatorSelectorColor: Colors.grey,
);
return Stack(
children: <Widget>[
Container(color: Colors.grey[100], height: double.infinity),
Container(color: Colors.white, child: container, margin: EdgeInsets.only(bottom: 50)),
],
);
}
}
class SliderBox extends StatelessWidget {
final Widget child;
const SliderBox({Key key, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(padding: EdgeInsets.all(10), child: child);
}
}
将 Worm Indicator 与 PageView 一起使用以显示滚动进度
在你的flutter项目中添加lib依赖
dependencies:
worm_indicator: 0.1.1
使用
WormIndicator(
length: PAGE_VIEW_SIZE,
controller: PAGE_VIEW_CONTROLLER,
size: DOT_SIZE_IN_PT,
spacing: DOT_SPACING_IN_PT,
),
Circle
和方形 DotShape
需要尺寸。 Rectangle
DotShape
需要宽度和高度。
WormIndicator(
length: 3,
controller: _controller,
shape: Shape(
size: 16,
spacing: 8,
shape: DotShape.Circle // Similar for Square
),
),
WormIndicator(
length: 3,
controller: _controller,
shape: Shape(
width: 16,
height: 24,
spacing: 8,
shape: DotShape.Rectangle
),
),