1. physics的参数
flutter中PageView 默认是可以左右滑动的,如果想禁止滑动修改physics的参数为NeverScrollableScrollPhysics(),即可
PageView(
physics: const NeverScrollableScrollPhysics(),
children: <Widget>[
Page1(),
Page2(),
Page3(),
Page4(),
Page5(),
],
controller: pageController,
onPageChanged: onPageChanged,
),
在 Flutter 中,ScrollPhysics 的作用是确定可滚动控件的物理特性, 常见的有以下几个:
ScrollPhysics | 释义 |
---|---|
BouncingScrollPhysics | 允许滚动出边界,超过边界时会有回弹效果,会响应滚动事件 |
ClampingScrollPhysics | 不允许滚动出边界,会响应滚动事件 |
AlwaysScrollableScrollPhysics | 一直响应滚动事件 |
NeverScrollableScrollPhysics | 禁止滚动,不响应滚动事件 |
FixedExtentScrollPhysics | ListWheelScrollView滚轮使用时,item都会停止在中间位置,不会停在分割线 |
PageScrollPhysics | PageView滚轮使用时,item都会停止在一页,不会停止在分割线位置 |
RangeMaintainingScrollPhysics | 当内容突然改变尺寸时,试图将滚动位置保持在范围内的滚动物理 |
滚动条案例:
// main.dart
import 'package:flutter/material.dart';
import 'pages/home.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
// home.dart
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class HomePage extends StatefulWidget {
HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool showFab = false;
ScrollController? _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
}
void dispose() {
_scrollController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Firebase Notifications")),
body: NotificationListener<UserScrollNotification>(
onNotification: (notification) {
setState(() {
if (notification.direction == ScrollDirection.forward) {
showFab = false;
} else if (notification.direction == ScrollDirection.reverse) {
showFab = true;
}
});
return true;
},
child: ListView.builder(
itemCount: 200,
controller: _scrollController,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
}),
),
floatingActionButton: showFab
? FloatingActionButton(
child: Icon(Icons.arrow_downward_rounded),
onPressed: () {
_scrollController
?.jumpTo(_scrollController!.position.maxScrollExtent);
},
)
: null);
}
}
2. controller
页面滑动案例
// main.dart
import 'package:flutter/material.dart';
import 'pages/demo/demo1.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PageViewPage(),
);
}
}
// demo1.dart
import 'package:flutter/material.dart';
class PageViewPage extends StatefulWidget {
PageViewPage({Key? key}) : super(key: key);
@override
_PageViewPageState createState() => _PageViewPageState();
}
class _PageViewPageState extends State<PageViewPage> {
// 当前子项索引
int currentIndex = 0;
// 子项集
late List<Widget> children;
// 控制器
late PageController _controller;
@override
void initState() {
super.initState();
// 初始化控制器
_controller = PageController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('PageView - ZeroFlutter'),
),
// 这里改为 PageView
body: PageView(
// 设置控制器
controller: _controller,
// 设置子项集
children: <Widget>[
PageDetails(title: '首页'),
PageDetails(title: '消息'),
PageDetails(title: '我的'),
],
// 添加页面滑动改变后,去改变索引变量刷新页面来更新底部导航
onPageChanged: (value) {
currentIndex = value;
setState(() {});
},
),
bottomNavigationBar: BottomNavigationBar(
// 当前页面索引
currentIndex: currentIndex,
// 导航子项集
items: [
// 导航子项
BottomNavigationBarItem(
// 图标
icon: Icon(Icons.home),
// 文字内容
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.message_rounded),
label: '消息',
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: '我的',
),
],
onTap: (value) {
// 点击事件,用于改变当前索引,然后刷新
setState(() {
currentIndex = value;
});
// 通过控制器实现跳转页面
_controller.jumpToPage(currentIndex);
},
));
}
}
class PageDetails extends StatefulWidget {
PageDetails({Key? key, required this.title}) : super(key: key);
final String title;
@override
_PageDetailsState createState() => _PageDetailsState();
}
//- 这里混入了 AutomaticKeepAliveClientMixin
class _PageDetailsState extends State<PageDetails>
with AutomaticKeepAliveClientMixin {
int count = 0;
@override
Widget build(BuildContext context) {
super.build(context);
// 这里的打印可以记录一下,后面会用到
print('PageDetails build title:${widget.title}');
return Scaffold(
body: GestureDetector(
onTap: () {
setState(() {
count += 1;
});
},
child: Center(
child: Text('${widget.title} count:$count'),
),
),
);
}
// 设置 true 期望保持页面状态
@override
bool get wantKeepAlive => true;
}