我在Flutter中看到了一个PageView,可以正确地在不同页面之间滑动。但是我们可以在当前页面上的任意位置向左或向右滑动。但是我的问题是只能在某些区域内左右滑动。如何实现?
在上图中,我只想在蓝色容器中向左或向右滑动。
答案 0 :(得分:0)
我可以使用以下代码来解决上述问题:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: AccountScreen(),
);
}
}
class AccountScreen extends StatefulWidget {
@override
_AccountScreenState createState() => _AccountScreenState();
}
class _AccountScreenState extends State<AccountScreen> {
PageController _bannerController = PageController(
initialPage: 0,
);
PageController _contentController = PageController(
initialPage: 0,
);
@override
void dispose() {
_bannerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Expanded(
flex: 1,
child: PageView(
controller: _bannerController,
onPageChanged: (int value) {
_contentController.animateToPage(value,
duration: Duration(milliseconds: 400),
curve: Curves.easeInOut);
},
children: [
MyPage1Widget(),
MyPage2Widget(),
],
),
),
Expanded(
flex: 2,
child: PageView(
physics: NeverScrollableScrollPhysics(),
controller: _contentController,
children: [
MyPage1Widget(),
MyPage2Widget(),
],
),
)
],
),
);
}
}
class MyPage1Widget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text("Page 1"),
);
}
}
class MyPage2Widget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text("Page 2"),
);
}
}
让我知道是否有比这更好的解决方案。
答案 1 :(得分:0)
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: AccountScreen(),
);
}
}
class AccountScreen extends StatefulWidget {
@override
_AccountScreenState createState() => _AccountScreenState();
}
class _AccountScreenState extends State<AccountScreen> {
PageController _contentController = PageController(
initialPage: 0,
);
@override
void dispose() {
_contentController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return PageView(
controller: _contentController,
physics: AlwaysScrollableScrollPhysics(),
children: [
//They are different just to see different approaches
MyPage3Widget(),
MyPage4Widget(),
],
);
}
}
class MyPage3Widget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(color: Colors.blue, height: 200),
Expanded(
child: GestureDetector(
onHorizontalDragUpdate: (_) {}, //This does the trick
child: Container(
color: Colors.transparent,
child: Center(child: Text("Page 2")))),
)
],
)
);
}
}
class MyPage4Widget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(), //it will scroll only when dragging the AppBar as if it were your banner
body: GestureDetector(
onHorizontalDragUpdate: (_) {}, //This does the trick
child: Container(
color: Colors.transparent,
child: Center(child: Text("Page 2"))
)
),
);
}
}
将GestureDetector添加到您不希望用户使用空手势滚动的位置(onHorizontalDragUpdate,因为您不想水平拖动)会欺骗Gesture Arena认为手势检测器是您想要的手势检测器做某事。使用透明颜色的容器填充所有可用空间(如果我仅使用居中或文本,它将仅包裹该文本,请检查颤动检查器以查看整个区域)。
比较您的示例的优势: