- Install
- Set up an editor
- Test drive
- Write your first Flutter app, part 1
- Learn more
- Flutter for Android developers
- Flutter for iOS developers
- Flutter for React Native developers
- Flutter for web developers
- Flutter for Xamarin.Forms developers
- Introduction to declarative UI
- Cookbook
- Codelabs
- Tutorials
- User interface
- Introduction to widgets
- Layouts in Flutter
- Layout tutorial
- Dealing with box constraints
- Adding interactivity to your Flutter app
- Adding assets and images
- Navigation & routing
- Introduction to animations
- Animations overview
- Animations tutorial
- Hero Animations
- Staggered Animations
- Advanced UI
- Slivers
- Taps, drags, and other gestures
- Widget catalog
- Data & backend
- State management
- State management
- Start thinking declaratively
- Differentiate between ephemeral state and app state
- Simple app state management
- List of state management approaches
- JSON and serialization
- Firebase
- Accessibility & internationalization
- Accessibility
- Internationalizing Flutter apps
- Platform integration
- Writing custom platform-specific code
- Packages & plugins
- Using packages
- Developing packages & plugins
- Background processes
- Tools & techniques
- Android Studio / IntelliJ
- Visual Studio Code
- Upgrading Flutter
- Hot reload
- Code formatting
- Debugging Flutter apps
- Using OEM debuggers
- Flutter's build modes
- Testing Flutter apps
- Performance best practices
- Flutter performance profiling
- Creating flavors for Flutter
- Preparing an Android App for Release
- Preparing an iOS App for Release
- Continuous Delivery using fastlane with Flutter
- Bootstrap into Dart
- Inside Flutter
- Platform specific behaviors and adaptations
- Technical Overview
- Technical videos
- FAQ
- Flutter widget index
- Install
- Windows install
- MacOS install
- Linux install
- Set up an editor
- Write your first Flutter app, part 1
- Learn more
- Cupertino (iOS-style) widgets
- Layout widgets
- Animation and motion widgets
- Retrieve the value of a text field
- Basic widgets
- Material Components widgets
- Animate the properties of a Container
- Fade a Widget in and out
- Add a Drawer to a screen
- Displaying SnackBars
- Exporting fonts from a package
- Updating the UI based on orientation
- Using Themes to share colors and font styles
- Using custom fonts
- Working with Tabs
- Building a form with validation
- Create and style a text field
- Focus on a Text Field
- Handling changes to a text field
- Retrieve the value of a text field
- Adding Material Touch Ripples
- Handling Taps
- Implement Swipe to Dismiss
- Display images from the internet
- Fade in images with a placeholder
- Working with cached images
- Basic List
- Create a horizontal list
- Creating a Grid List
- Creating lists with different types of items
- Place a floating app bar above a list
- Working with long lists
- Report errors to a service
- Animating a Widget across screens
- Navigate to a new screen and back
- Navigate with named routes
- Pass arguments to a named route
- Return data from a screen
- Send data to a new screen
- Fetch data from the internet
- Making authenticated requests
- Parsing JSON in the background
- Working with WebSockets
- Persist data with SQLite
- Reading and Writing Files
- Storing key-value data on disk
- Play and pause a video
- Take a picture using the Camera
- An introduction to integration testing
- Performance profiling
- Scrolling
- An introduction to unit testing
- Mock dependencies using Mockito
- An introduction to widget testing
- Finding widgets
- Tapping, dragging and entering text
- Development
- Introduction to widgets
- Layout tutorial
- Dealing with box constraints
- Adding interactivity to your Flutter app
- Adding assets and images
- Navigation & routing
- Navigate to a new screen and back
- Send data to a new screen
- Return data from a screen
- Navigate with named routes
- Animating a Widget across screens
- AnimatedList
- Sample App Catalog
- Animations overview
- Animations tutorial
- Staggered Animations
- Slivers
- Taps, drags, and other gestures
- Accessibility widgets
- Assets, images, and icon widgets
- Async widgets
- Input widgets
- Interaction model widgets
- Painting and effect widgets
- Scrolling widgets
- Styling widgets
- Text widgets
- State management
- Start thinking declaratively
- Differentiate between ephemeral state and app state
- Simple app state management
- List of state management approaches
- JSON and serialization
- Accessibility
- Internationalizing Flutter apps
- Writing custom platform-specific code
- Using packages
- Fetch data from the internet
- Developing packages & plugins
- Background processes
- Android Studio / IntelliJ
- Set up an editor
- Flutter inspector
- Creating Useful Bug Reports
- Visual Studio Code
- Set up an editor
- Upgrading Flutter
- Hot reload
- Code formatting
Taps, drags, and other gestures
This document explains how to listen for, and respond to, gestures in Flutter. Examples of gestures include taps, drags, and scaling.
The gesture system in Flutter has two separate layers. The first layer has raw pointer events, which describe the location and movement of pointers (e.g., touches, mice, and styli) across the screen. The second layer has gestures, which describe semantic actions that consist of one or more pointer movements.
Pointers
Pointers represent raw data about the user’s interaction with the device’s screen. There are four types of pointer events:
PointerDownEvent
The pointer has contacted the screen at a particular location.PointerMoveEvent
The pointer has moved from one location on the screen to another.PointerUpEvent
The pointer has stopped contacting the screen.PointerCancelEvent
Input from this pointer is no longer directed towards this app.
On pointer down, the framework does a hit test on your app to determine which widget exists at the location where the pointer contacted the screen. The pointer down event (and subsequent events for that pointer) are then dispatched to the innermost widget found by the hit test. From there, the events bubble up the tree and are dispatched to all the widgets on the path from the innermost widget to the root of the tree. There is no mechanism for canceling or stopping pointer events from being dispatched further.
To listen to pointer events directly from the widgets layer, use a Listener
widget. However, generally, consider using gestures (as discussed below) instead.
Gestures
Gestures represent semantic actions (e.g., tap, drag, and scale) that are recognized from multiple individual pointer events, potentially even multiple individual pointers. Gestures can dispatch multiple events, corresponding to the lifecycle of the gesture (e.g., drag start, drag update, and drag end):
- Tap
onTapDown
A pointer that might cause a tap has contacted the screen at a particular location.onTapUp
A pointer that will trigger a tap has stopped contacting the screen at a particular location.onTap
A tap has occurred.onTapCancel
The pointer that previously triggered theonTapDown
will not end up causing a tap.
- Double tap
onDoubleTap
The user has tapped the screen at the same location twice in quick succession.
- Long press
onLongPress
A pointer has remained in contact with the screen at the same location for a long period of time.
- Vertical drag
onVerticalDragStart
A pointer has contacted the screen and might begin to move vertically.onVerticalDragUpdate
A pointer that is in contact with the screen and moving vertically has moved in the vertical direction.onVerticalDragEnd
A pointer that was previously in contact with the screen and moving vertically is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.
- Horizontal drag
onHorizontalDragStart
A pointer has contacted the screen and might begin to move horizontally.onHorizontalDragUpdate
A pointer that is in contact with the screen and moving horizontally has moved in the horizontal direction.onHorizontalDragEnd
A pointer that was previously in contact with the screen and moving horizontally is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.
- Pan
onPanStart
A pointer has contacted the screen and might begin to move horizontally or vertically. This callback causes a crash ifonHorizontalDragStart
oronVerticalDragStart
is set.onPanUpdate
A pointer that is in contact with the screen and is moving in the vertical or horizontal direction. This callback causes a crash ifonHorizontalDragUpdate
oronVerticalDragUpdate
is set.onPanEnd
A pointer that was previously in contact with screen is no longer in contact with the screen and is moving at a specific velocity when it stopped contacting the screen. This callback causes a crash ifonHorizontalDragEnd
oronVerticalDragEnd
is set.
To listen to gestures from the widgets layer, use a GestureDetector
.
If you’re using Material Components, many of those widgets already respond to taps or gestures. For example, IconButton and FlatButton respond to presses (taps), and ListView
responds to swipes to trigger scrolling. If you are not using those widgets, but you want the “ink splash” effect on a tap, you can use InkWell
.
Gesture disambiguation
At a given location on screen, there might be multiple gesture detectors. All of these gesture detectors listen to the stream of pointer events as they flow past and attempt to recognize specific gestures. The GestureDetector
widget decides which gestures to attempt to recognize based on which of its callbacks are non-null.
When there is more than one gesture recognizer for a given pointer on the screen, the framework disambiguates which gesture the user intends by having each recognizer join the gesture arena. The gesture arena determines which gesture wins using the following rules:
At any time, a recognizer can declare defeat and leave the arena. If there’s only one recognizer left in the arena, that recognizer is the winner.
At any time, a recognizer can declare victory, which causes it to win and all the remaining recognizers to lose.
For example, when disambiguating horizontal and vertical dragging, both recognizers enter the arena when they receive the pointer down event. The recognizers observe the pointer move events. If the user moves the pointer more than a certain number of logical pixels horizontally, the horizontal recognizer will declare victory and the gesture will be interpreted as a horizontal drag. Similarly, if the user moves more than a certain number of logical pixels vertically, the vertical recognizer will declare victory.
The gesture arena is beneficial when there is only a horizontal (or vertical) drag recognizer. In that case, there will be only one recognizer in the arena and the horizontal drag will be recognized immediately, which means the first pixel of horizontal movement can be treated as a drag and the user will not need to wait for further gesture disambiguation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论