【发布时间】:2020-10-03 16:01:32
【问题描述】:
我在 Flutter 中看到了一个 PageView,它可以正确地在不同页面之间滑动。但是我们可以在当前页面的任意位置滑动以向左或向右移动。但我的问题是只在特定区域左右滑动。如何实现?
在上图中,我只想在蓝色容器中向左或向右滑动。
【问题讨论】:
-
您可以使用Flutter_Swipper实现这一目标
我在 Flutter 中看到了一个 PageView,它可以正确地在不同页面之间滑动。但是我们可以在当前页面的任意位置滑动以向左或向右移动。但我的问题是只在特定区域左右滑动。如何实现?
在上图中,我只想在蓝色容器中向左或向右滑动。
【问题讨论】:
我能够通过以下代码得到上述问题的解决方案:
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"),
);
}
}
如果有比这更好的解决方案,请告诉我。
【讨论】:
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 认为手势检测器是想要的做某事。使用透明颜色的 Container 来填充所有可用空间(如果我只使用 Center 或 Text,它只会包装该文本,请检查颤振检查器以查看整个区域)。
比较您的示例的优势:
【讨论】: