PageView常见属性
Flutter中的轮动图以及抖音上下滑页切换视频功能等等,这些都可以通过 PageView 轻松实现
| 属性 | 描述 |
|---|---|
| scrollDirection | Axis.horizonta水平方向 Axis.vertical锤子方向 |
| children | 配置子元素 |
| allowImplicitScrolling | 缓存当前页面的前后两页 |
| onPageChanged | page改变的时候触发 |
| controller | 控制器 |
| physics | 滑动效果 |
| pageSnapping | 是否滑动到下一页 |
| reverse | 是否反向滑动 |
PageView 的使用
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({super.key});
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return PageView(
scrollDirection: Axis.vertical, // 上下滑动, 默认是水平方向就是左右滑动
children: [
Center(
child: Text('第一屏', style: Theme.of(context).textTheme.headlineLarge,),
),
Center(
child: Text('第二屏', style: Theme.of(context).textTheme.headlineLarge,),
),
Center(
child: Text('第三屏', style: Theme.of(context).textTheme.headlineLarge,),
),
],
);
}
}

PageView.builder
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({super.key});
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return PageView.builder(
itemBuilder: (context, index) {
return Container(
alignment: Alignment.center,
color: Colors.blue[100 * (index % 9)],
child: Text('CategoryPage $index'),
);
},
);
}
}

PageView上拉无限加载的实现思路
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({super.key});
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
List<Widget> _list = [];
@override
void initState() {
super.initState();
for(var i = 0; i < 10; i++){
_list.add(ListTile(
title: Text('我是第$i个列表'),
));
}
}
@override
Widget build(BuildContext context) {
return PageView(
scrollDirection: Axis.vertical,
onPageChanged: (index){
print('当前是第$index页');
// 实现无限循环
if(index == _list.length - 1){
_list.addAll([
ListTile(
title: Text('我是第${_list.length}个列表'),
),
ListTile(
title: Text('我是第${_list.length + 1}个列表'),
),
]);
}
},
children: _list,
);
}
}
PageView实现一个轮播图
import 'package:flutter/material.dart';
class CategoryPage extends StatefulWidget {
const CategoryPage({super.key});
@override
State<CategoryPage> createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 200,
child: PageView(
pageSnapping:true,
children: [
Container(
color: Colors.red,
child: Image.network('https://www.itying.com/images/flutter/1.png', fit: BoxFit.cover)
),
Container(
color: Colors.blue,
child: Image.network('https://www.itying.com/images/flutter/2.png', fit: BoxFit.cover)
),
Container(
color: Colors.yellow,
child: Image.network('https://www.itying.com/images/flutter/3.png', fit: BoxFit.cover)
),
],
),
);
}
}
PageView 实现一个无限轮播的轮播图
1. 创建一个自定义的轮播图组件 Image.dart
import 'package:flutter/material.dart';
class ImagePage extends StatelessWidget {
final double width;
final double height;
final String url;
const ImagePage({super.key, this.width = double.infinity, this.height = 200, required this.url});
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
height: height,
child: Image.network(url, fit: BoxFit.cover),
);
}
}
2. 创建一个自定义的轮播图组件 ImagePageView.dart
import 'package:flutter/material.dart';
import 'image.dart';
class ImagePageView extends StatefulWidget {
const ImagePageView({super.key});
@override
State<ImagePageView> createState() => _ImagePageViewState();
}
class _ImagePageViewState extends State<ImagePageView> {
List<Widget> list = [];
@override
void initState() {
super.initState();
list = const [
ImagePage(
width: double.infinity,
height: 200,
url: 'https://www.itying.com/images/flutter/1.png'
),
ImagePage(
width: double.infinity,
height: 200,
url: 'https://www.itying.com/images/flutter/2.png'
),
ImagePage(
width: double.infinity,
height: 200,
url: 'https://www.itying.com/images/flutter/3.png'
),
];
}
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: 200,
child: PageView.builder(
itemCount: 1000,
itemBuilder: (context, index){
return list[index%list.length]; // 0 1 2 0 1 2 0 1 2 这里用取余的方式实现无限轮播
}),
);
}
}
Fluuter 定时器
const timeout = Duration(seconds: 3);
var t=Timer.periodic(timeout, (timer) {
print('afterTimer='+DateTime.now().toString()););
// timer.cancel(); // 取消定时器
});
t.cancel();
void dispose() {
super.dispose();
t.cancel();
}
PageController animateToPage自动切换页面
1. 创建一个自定义的轮播图组件 Image.dart
import 'package:flutter/material.dart';
class ImagePage extends StatelessWidget {
final double width;
final double height;
final String url;
const ImagePage({super.key, this.width = double.infinity, this.height = 200, required this.url});
@override
Widget build(BuildContext context) {
return SizedBox(
width: width,
height: height,
child: Image.network(url, fit: BoxFit.cover),
);
}
}
2. 创建一个自定义的轮播图组件 swiper.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'image.dart';
class SwiperPage extends StatefulWidget {
// ignore: prefer_typing_uninitialized_variables
final double width;
// ignore: prefer_typing_uninitialized_variables
final double height;
final List<String> list;
const SwiperPage(
{super.key,
this.width = double.infinity,
this.height = 200,
required this.list});
@override
State<SwiperPage> createState() => _SwiperPageState();
}
class _SwiperPageState extends State<SwiperPage> {
int _currentIndex = 0;
late PageController _pageController;
List<Widget> pagelist = [];
late Timer timer;
@override
void initState() {
super.initState();
for (var i = 0; i < widget.list.length; i++) {
pagelist.add(ImagePage(
width: widget.width,
height: widget.height,
url: widget.list[i],
));
}
_pageController = PageController(
initialPage: _currentIndex,
);
var timer = Timer.periodic(const Duration(seconds: 5), (t) {
_pageController.animateToPage((_currentIndex + 1) % pagelist.length,
duration: const Duration(microseconds: 200), curve: Curves.linear);
});
}
@override
void dispose() {
super.dispose();
timer.cancel();
_pageController.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
SizedBox(
width: widget.width,
height: widget.height,
child: PageView.builder(
controller: _pageController,
onPageChanged: (index) {
setState(() {
_currentIndex = index % pagelist.length;
});
},
itemCount: 1000,
itemBuilder: (context, index) {
return pagelist[index %
pagelist.length]; // 0 1 2 0 1 2 0 1 2 这里用取余的方式实现无限轮播
}),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
color: Colors.black.withOpacity(0.3),
padding: const EdgeInsets.all(10),
child: Row(
// 三个点
mainAxisAlignment: MainAxisAlignment.center,
children: pagelist.asMap().keys.map((e) {
return Container(
width: 10,
height: 10,
margin: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: e == _currentIndex ? Colors.red : Colors.white,
borderRadius: BorderRadius.circular(10),
),
);
}).toList(),
),
),
),
],
);
}
}
3. 创建一个自定义的轮播图组件 ImagePageView.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'swiper.dart';
class ImagePageView extends StatefulWidget {
const CategoryPage({super.key});
@override
State<ImagePageView> createState() => _ImagePageViewState();
}
class _ImagePageViewState extends State<ImagePageView> {
List<String> list = [];
@override
void initState() {
super.initState();
list = const [
'https://www.itying.com/images/flutter/1.png',
'https://www.itying.com/images/flutter/2.png',
'https://www.itying.com/images/flutter/3.png',
];
}
@override
Widget build(BuildContext context) {
return SwiperPage(
list: list,
);
}
}

AutomaticKeepAliveClientMixin 缓存PageView页面
import 'package:flutter/material.dart';
class PageViewKeepAlive extends StatefulWidget {
const PageViewKeepAlive({super.key});
@override
State<PageViewKeepAlive> createState() => _PageViewKeepAliveState();
}
class _PageViewKeepAliveState extends State<PageViewKeepAlive> {
@override
Widget build(BuildContext context) {
return PageView.builder(
scrollDirection: Axis.vertical,
itemCount: 10,
itemBuilder: (context, index) {
return MyContainer(num: index);
},
);
}
}
class MyContainer extends StatefulWidget {
final int num;
const MyContainer({super.key, required this.num});
@override
State<MyContainer> createState() => _MyContainerState();
}
// 自定义组件
class _MyContainerState extends State<MyContainer> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
print(widget.num); // 默认数据是没有缓存的,每次滑动都会执行build方法
return Center(
child: Text('第${widget.num}屏', style: Theme.of(context).textTheme.headlineLarge,),
);
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
自定义KeepAliveWrapper 缓存页面
1. 创建一个自定义keepAliveWrapper组件 keepAliveWrapper.dart
import 'package:flutter/material.dart';
class KeepAliveWrapper extends StatefulWidget {
const KeepAliveWrapper(
{Key? key, @required this.child, this.keepAlive = true})
: super(key: key);
final Widget? child;
final bool keepAlive;
@override
State<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}
class _KeepAliveWrapperState extends State<KeepAliveWrapper>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
return widget.child!;
}
@override
bool get wantKeepAlive => widget.keepAlive;
@override
void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
if (oldWidget.keepAlive != widget.keepAlive) {
// keepAlive 状态需要更新,实现在 AutomaticKeepAliveClientMixin 中
updateKeepAlive();
}
super.didUpdateWidget(oldWidget);
}
}
2. 创建一个自定义的轮播图组件 ImagePageView.dart
import 'package:flutter/material.dart';
import 'keepAliveWrapper.dart';
class PageViewKeepAlive extends StatefulWidget {
const PageViewKeepAlive({super.key});
@override
State<PageViewKeepAlive> createState() => _PageViewKeepAliveState();
}
class _PageViewKeepAliveState extends State<PageViewKeepAlive> {
@override
Widget build(BuildContext context) {
return PageView.builder(
scrollDirection: Axis.vertical,
itemCount: 10,
itemBuilder: (context, index) {
return KeepAliveWrapper(
child: MyContainer(num: index),
);
// )MyContainer(num: index);
},
);
}
}
class MyContainer extends StatefulWidget {
final int num;
const MyContainer({super.key, required this.num});
@override
State<MyContainer> createState() => _MyContainerState();
}
// 自定义组件
class _MyContainerState extends State<MyContainer> {
@override
Widget build(BuildContext context) {
print(widget.num); // 默认数据是没有缓存的,每次滑动都会执行build方法
return Center(
child: Text('第${widget.num}屏', style: Theme.of(context).textTheme.headlineLarge,),
);
}
}