我曾尝试使用swipedetector插件进行滑动操作,以实现向右滑动的新屏幕的导航,但无法正常工作,不会引发任何错误,并且在调试时永远不会碰到断点。我查看了GestureDector,但不确定是否可以在向右滑动的场景中使用,我们希望当屏幕上的任意位置向右滑动时将其导航到屏幕。
@override
Widget build(BuildContext context){
return new Scaffold(
appBar : LBAppBar().getAppBar(),
//drawer: new LBDrawer().getDrawer(),
body: Container(
decoration: BoxDecoration(
gradient: new LinearGradient(
colors: [Color.fromRGBO(1,89,99, 1.0), Colors.grey],
begin: Alignment.bottomLeft,
end: Alignment.topRight
)
),
child:
SwipeDetector(
onSwipeRight: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new WidgetsPage())
); },
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Row(
children: [
Container(
margin: EdgeInsets.only(left: 20.0,top: 10.0, bottom: 10.0, right:30.0),
child: Column(
children: <Widget>[
Text("Hi ${user.firstName}, Today is " + formatDate(), style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.bold, fontSize: 19.0
)),
],
),
),
]
),
Row(
//ROW 1
children: [
Container(
margin: EdgeInsets.only(left: 30.0,top: 60.0, bottom: 30.0, right:30.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.checkSquare,
size: 50.0,
color: Colors.white70,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new CheckIn()));
}),
Text("Check In", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
),
Container(
margin: EdgeInsets.only(left: 50.0,top: 60.0, bottom: 30.0, right:30.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.list,
size: 50.0,
color: Colors.white70,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new DayAtAGlance()));
}),
Text("My Day", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
),
Container(
margin: EdgeInsets.only(left: 30.0,top: 60.0, bottom: 30.0, right:30.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.phone,
size: 45.0,
color: Colors.white70,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new CommunicationLinks()));
}),
Text("Communication", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
),
]
),
Row(//ROW 2
children: [
Container(
margin: EdgeInsets.only(left: 32.0,top: 50.0, bottom: 30.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.dollarSign,
size: 50.0,
color: Colors.white70,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new Budget()));
}),
Text("Budget", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
),
Container(
margin: EdgeInsets.only(left: 75.0, top: 50.0, bottom: 30.0, right: 30.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.trophy,
size: 50.0,
color: Colors.white70,
),
onTap: () {
print("Pressed");
}),
Text("Goals", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
),
Container(
margin: EdgeInsets.only(left: 50.0, top: 50.0, bottom: 30.0, right: 20.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.calendar,
size: 50.0,
color: Colors.white70,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new CalendarsPage()));
}),
Text("Calendar", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
)
]),
Row(// ROW 3
children: [
Container(
margin: EdgeInsets.only(left: 30.0, top: 50.0, bottom: 30.0, right: 30.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.comments,
size: 50.0,
color: Colors.white70,
),
onTap: () {
print("Pressed");
}),
Text("Community", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
),
Container(
margin: EdgeInsets.only(left: 20.0, top: 50.0, bottom: 30.0, right: 20.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.shoppingCart,
size: 50.0,
color: Colors.white70,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new ShoppingList()));
}),
Text("Shopping", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.normal ))
],
),
),
Container(
margin: EdgeInsets.only(left: 50.0, top: 50.0, bottom: 30.0, right: 40.0),
child: Column(
children: <Widget>[
GestureDetector(
child: Icon(
FontAwesomeIcons.solidCheckSquare,
size: 50.0,
color: Colors.white70,
),
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new CheckOut()));
}),
Text("Check Out", style: new TextStyle( color: Colors.white70, fontWeight: FontWeight.bold ))
],
),
),
]),
],
),
)
)
);
答案 0 :(得分:7)
将Widget
包裹在GestureDetector
中,并使用onHorizontalDragUpdate
作为
GestureDetector(
onHorizontalDragUpdate: (details) {
// Note: Sensitivity is integer used when you don't want to mess up vertical drag
if (details.delta.dx > sensitivity) {
// Right Swipe
} else if(details.delta.dx < -sensitivity){
//Left Swipe
}
}
);
答案 1 :(得分:7)
在某些情况下,如果 GestureDetector
用作其他可滚动小部件的子级或父级,则它不会触发手势事件。
检测任何手势的最佳方法是使用 Listener
小部件。
Listener(
onPointerMove: (moveEvent){
if(moveEvent.delta.dx > 0) {
print("swipe right");
}
}
child: PageView(...) // or any other widget
)
答案 2 :(得分:4)
这是我使用 GestureDetector 的解决方案。我将处理程序放在 onPanEnd 中,因为在进行滑动时会多次调用 onPanUpdate。
@override
Widget build(BuildContext context) {
String swipeDirection;
return GestureDetector(
onPanUpdate: (details) {
swipeDirection = details.delta.dx < 0 ? 'left' : 'right';
},
onPanEnd: (details) {
if (swipeDirection == 'left') {
//handle swipe left event
}
if (swipeDirection == 'right') {
//handle swipe right event
}
},
child: //child widget
);
}
答案 3 :(得分:3)
对我来说,这里的其他解决方案会引起一些问题,例如每次滑动多次触发触发器。我最终使用了onHorizontalDragEnd
手势检测器,每次滑动仅触发一次。
class MyPageView extends StatefulWidget {
@override
_MyPageViewState createState() => _MyPageViewState();
}
class _MyPageViewState extends State<MyPageView> {
PageController _pageController;
Duration pageTurnDuration = Duration(milliseconds: 500);
Curve pageTurnCurve = Curves.ease;
@override
void initState() {
super.initState();
// The PageController allows us to instruct the PageView to change pages.
_pageController = PageController();
}
void _goForward() {
_pageController.nextPage(duration: pageTurnDuration, curve: pageTurnCurve);
}
void _goBack() {
_pageController.previousPage(
duration: pageTurnDuration, curve: pageTurnCurve);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
// Using the DragEndDetails allows us to only fire once per swipe.
onHorizontalDragEnd: (dragEndDetails) {
if (dragEndDetails.primaryVelocity < 0) {
// Page forwards
print('Move page forwards');
_goForward();
} else if (dragEndDetails.primaryVelocity > 0) {
// Page backwards
print('Move page backwards');
_goBack();
}
},
child: PageView.builder(
itemCount: 10,
controller: _pageController,
// NeverScrollableScrollPhysics disables PageView built-in gestures.
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return new Center(child: Text('item ${++index}'));
}),
),
);
}
}
答案 4 :(得分:2)
答案在源代码消失后更新
现在,您可以将 swipedetector 与 SwipeConfiguration dart类一起使用,该类可以检测上,下,左,右滑动。
使用SwipeDetector很简单,只需将其包裹在要检测滑动的小部件上即可。
要使用swipedetector
类,只需复制并粘贴文件代码或将以下dart文件拖放到您的项目目录中。并导入为import 'package:[Your directory path]/swipedetector.dart'
;
创建一个swipedetector.dart
并将此代码复制并粘贴到您的文件中
import 'package:flutter/material.dart';
class SwipeConfiguration {
//Vertical swipe configuration options
double verticalSwipeMaxWidthThreshold = 50.0;
double verticalSwipeMinDisplacement = 100.0;
double verticalSwipeMinVelocity = 300.0;
//Horizontal swipe configuration options
double horizontalSwipeMaxHeightThreshold = 50.0;
double horizontalSwipeMinDisplacement = 100.0;
double horizontalSwipeMinVelocity = 300.0;
SwipeConfiguration({
double verticalSwipeMaxWidthThreshold,
double verticalSwipeMinDisplacement,
double verticalSwipeMinVelocity,
double horizontalSwipeMaxHeightThreshold,
double horizontalSwipeMinDisplacement,
double horizontalSwipeMinVelocity,
}) {
if (verticalSwipeMaxWidthThreshold != null) {
this.verticalSwipeMaxWidthThreshold = verticalSwipeMaxWidthThreshold;
}
if (verticalSwipeMinDisplacement != null) {
this.verticalSwipeMinDisplacement = verticalSwipeMinDisplacement;
}
if (verticalSwipeMinVelocity != null) {
this.verticalSwipeMinVelocity = verticalSwipeMinVelocity;
}
if (horizontalSwipeMaxHeightThreshold != null) {
this.horizontalSwipeMaxHeightThreshold = horizontalSwipeMaxHeightThreshold;
}
if (horizontalSwipeMinDisplacement != null) {
this.horizontalSwipeMinDisplacement = horizontalSwipeMinDisplacement;
}
if (horizontalSwipeMinVelocity != null) {
this.horizontalSwipeMinVelocity = horizontalSwipeMinVelocity;
}
}
}
class SwipeDetector extends StatelessWidget {
final Widget child;
final Function() onSwipeUp;
final Function() onSwipeDown;
final Function() onSwipeLeft;
final Function() onSwipeRight;
final SwipeConfiguration swipeConfiguration;
SwipeDetector(
{@required this.child,
this.onSwipeUp,
this.onSwipeDown,
this.onSwipeLeft,
this.onSwipeRight,
SwipeConfiguration swipeConfiguration})
: this.swipeConfiguration = swipeConfiguration == null
? SwipeConfiguration()
: swipeConfiguration;
@override
Widget build(BuildContext context) {
//Vertical drag details
DragStartDetails startVerticalDragDetails;
DragUpdateDetails updateVerticalDragDetails;
//Horizontal drag details
DragStartDetails startHorizontalDragDetails;
DragUpdateDetails updateHorizontalDragDetails;
return GestureDetector(
child: child,
onVerticalDragStart: (dragDetails) {
startVerticalDragDetails = dragDetails;
},
onVerticalDragUpdate: (dragDetails) {
updateVerticalDragDetails = dragDetails;
},
onVerticalDragEnd: (endDetails) {
double dx = updateVerticalDragDetails.globalPosition.dx -
startVerticalDragDetails.globalPosition.dx;
double dy = updateVerticalDragDetails.globalPosition.dy -
startVerticalDragDetails.globalPosition.dy;
double velocity = endDetails.primaryVelocity;
//Convert values to be positive
if (dx < 0) dx = -dx;
if (dy < 0) dy = -dy;
double positiveVelocity = velocity < 0 ? -velocity : velocity;
if (dx > swipeConfiguration.verticalSwipeMaxWidthThreshold) return;
if (dy < swipeConfiguration.verticalSwipeMinDisplacement) return;
if (positiveVelocity < swipeConfiguration.verticalSwipeMinVelocity)
return;
if (velocity < 0) {
//Swipe Up
if (onSwipeUp != null) {
onSwipeUp();
}
} else {
//Swipe Down
if (onSwipeDown != null) {
onSwipeDown();
}
}
},
onHorizontalDragStart: (dragDetails) {
startHorizontalDragDetails = dragDetails;
},
onHorizontalDragUpdate: (dragDetails) {
updateHorizontalDragDetails = dragDetails;
},
onHorizontalDragEnd: (endDetails) {
double dx = updateHorizontalDragDetails.globalPosition.dx -
startHorizontalDragDetails.globalPosition.dx;
double dy = updateHorizontalDragDetails.globalPosition.dy -
startHorizontalDragDetails.globalPosition.dy;
double velocity = endDetails.primaryVelocity;
if (dx < 0) dx = -dx;
if (dy < 0) dy = -dy;
double positiveVelocity = velocity < 0 ? -velocity : velocity;
if (dx < swipeConfiguration.horizontalSwipeMinDisplacement) return;
if (dy > swipeConfiguration.horizontalSwipeMaxHeightThreshold) return;
if (positiveVelocity < swipeConfiguration.horizontalSwipeMinVelocity)
return;
if (velocity < 0) {
//Swipe Up
if (onSwipeLeft != null) {
onSwipeLeft();
}
} else {
//Swipe Down
if (onSwipeRight != null) {
onSwipeRight();
}
}
},
);
}
}
并像这样使用它
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: SwipeDetector(
child: Container(height: 200, width: 300), //Your Widget Tree here
onSwipeUp: () {
print("Swipe Up");
},
onSwipeDown: () {
print("Swipe Down");
},
onSwipeLeft: () {
print("Swipe Left");
},
onSwipeRight: () {
print("Swipe Right");
},
),
),
);
}
要下载 swipedetector.dart 文件 https://github.com/pkmangukiya/SwipeDetector/blob/main/swipedetector.dart
答案 5 :(得分:1)
将小部件包装在GestureDetector
中,然后像这样使用onPanUpdate
:
GestureDetector(onPanUpdate: (details) {
if (details.delta.dx > 0) {
// swiping in right direction
}
});
答案 6 :(得分:0)
To带回@Vimal Rai的答案。我发现onHorizontalDragUpdate每次更新都会调用该函数。这可能会导致您的应用程序出现不良行为。如果您希望在滑动时仅调用一次函数,请使用OnHorizontalDragEnd:
GestureDetector(
onHorizontalDragEnd: (DragEndDetails details) {
if (details.primaryVelocity > 0) {
// User swiped Left
} else if (details.primaryVelocity < 0) {
// User swiped Right
}
}
);
答案 7 :(得分:0)
另一种方法是将小部件包装为可解散的。 就我而言,此方法效果很好,因为它具有交互式动画,为用户提供了一种中止的清晰方法。
Dismissible(
key: UniqueKey(),
child: yourWidget, //the widget you want the swipe to be detected on
direction: DismissDirection.up, // or whatever
confirmDismiss: (direction) {
if (direction == DismissDirection.up) { // or other directions
// Swiped up do your thing.
}
return Future.value(false); // always deny the actual dismiss, else it will expect the widget to be removed
})
答案 8 :(得分:-1)
尝试使用PageView。您可以给它提供一组页面,然后向右滑动即可浏览这些页面。