Flutter 颤振:覆盖';页面视图';使用child'滚动手势;手势检测器
我在应用程序中使用“底部导航栏”和“页面视图”组合进行导航。用户可以滑动到下一页或使用导航栏 在我的一个页面上,我想使用一个手势检测器来处理垂直和水平平移手势 我找不到一种方法用嵌套的GestureDetector覆盖页面视图的手势检测。这意味着只处理垂直平移手势,因为水平平移手势被页面视图占据 如何在不完全禁用页面浏览量的情况下,仅禁用/覆盖该页面或小部件的页面浏览量手势检测? 我已经创建了我的应用程序的简化版本来隔离这个问题,并在下面附上了这个问题的视频 任何帮助都将不胜感激 以下是my main.dart中的代码:Flutter 颤振:覆盖';页面视图';使用child'滚动手势;手势检测器,flutter,dart,Flutter,Dart,我在应用程序中使用“底部导航栏”和“页面视图”组合进行导航。用户可以滑动到下一页或使用导航栏 在我的一个页面上,我想使用一个手势检测器来处理垂直和水平平移手势 我找不到一种方法用嵌套的GestureDetector覆盖页面视图的手势检测。这意味着只处理垂直平移手势,因为水平平移手势被页面视图占据 如何在不完全禁用页面浏览量的情况下,仅禁用/覆盖该页面或小部件的页面浏览量手势检测? 我已经创建了我的应用程序的简化版本来隔离这个问题,并在下面附上了这个问题的视频 任何帮助都将不胜感激 以下是my
import 'package:flutter/material.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: GestureIssueExample(),
);
}
}
class GestureIssueExample extends StatefulWidget {
GestureIssueExample({Key key}) : super(key: key);
@override
_GestureIssueExampleState createState() => _GestureIssueExampleState();
}
class _GestureIssueExampleState extends State<GestureIssueExample> {
int _navigationIndex;
double _xLocalValue;
double _yLocalValue;
PageController _pageController;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: null,
bottomNavigationBar: _buildBottomNavigationBar(),
backgroundColor: Colors.white,
body: PageView(
controller: _pageController,
onPageChanged: _onNavigationPageChanged,
children: [
//Just a placeholder to represent a page to the left of the "swipe cards" widget
_buildSamplePage("Home"),
//Center child of 'PageView', contains a GestureDetector that handles Pan Gestures
//Thanks to the page view however, only vertical pan gestures are detected, while both horizontal and vertical gestures
//need to be handled...
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"Local X: ${_xLocalValue.toString()}\nLocal Y: ${_yLocalValue.toString()}"),
GestureDetector(
onPanStart: (details) => setState(
() {
this._xLocalValue = details.localPosition.dx;
this._yLocalValue = details.localPosition.dy;
},
),
onPanUpdate: (details) => setState(
() {
this._xLocalValue = details.localPosition.dx;
this._yLocalValue = details.localPosition.dy;
},
),
child: Container(
width: MediaQuery.of(context).size.width * 0.9,
height: 100.0,
color: Colors.red,
alignment: Alignment.center,
child: Text("Slidable Surface",
style: TextStyle(color: Colors.white)),
),
),
],
),
),
//Just a placeholder to represent a page to the right of the "swipe cards" widget
_buildSamplePage("Settings"),
],
),
);
}
@override
void initState() {
super.initState();
this._navigationIndex = 0;
this._pageController = PageController(
initialPage: _navigationIndex,
);
}
Widget _buildSamplePage(String text) {
// This simply returns a container that fills the page,
// with a text widget in its center.
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.grey[900],
alignment: Alignment.center,
child: Text(
text,
style: TextStyle(
color: Colors.white, fontSize: 30.0, fontWeight: FontWeight.bold),
),
);
}
Widget _buildBottomNavigationBar() {
//Returns the bottom navigation bar for the scaffold
return BottomNavigationBar(
backgroundColor: Colors.grey[900],
selectedItemColor: Colors.redAccent,
unselectedItemColor: Colors.white,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home_outlined), label: "Home"),
BottomNavigationBarItem(
icon: Icon(Icons.check_box_outline_blank), label: "Cards"),
BottomNavigationBarItem(
icon: Icon(Icons.settings_outlined), label: "Settings"),
],
currentIndex: _navigationIndex,
onTap: _onNavigationPageChanged,
);
}
void _onNavigationPageChanged(int newIndex) {
//Set the new navigation index for the nav bar
setState(() => this._navigationIndex = newIndex);
//Animate to the selected page
_pageController.animateToPage(
newIndex,
curve: Curves.easeInOut,
duration: Duration(microseconds: 100),
);
}
}
导入“包装:颤振/材料.省道”;
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:GestureIssueExample(),
);
}
}
类GestureIssueExample扩展StatefulWidget{
GestureIssueExample({Key}):super(Key:Key);
@凌驾
_GestureIssueExampleState createState()=>\U GestureIssueExampleState();
}
类_GestureIssueExampleState扩展状态{
国际导航索引;
双左值;
双重价值;
页面控制器_页面控制器;
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:null,
bottomNavigationBar:_buildBottomNavigationBar(),
背景颜色:Colors.white,
正文:页面视图(
控制器:_pageController,
onPageChanged:_onNavigationPageChanged,
儿童:[
//只是一个占位符,表示“刷卡”小部件左侧的页面
_buildSamplePage(“主页”),
//“PageView”的中心子级包含一个处理平移手势的手势检测器
//但是,由于页面视图,仅检测到垂直平移手势,而同时检测到水平和垂直手势
//需要处理。。。
容器(
宽度:MediaQuery.of(context).size.width,
高度:MediaQuery.of(context).size.height,
子:列(
mainAxisAlignment:mainAxisAlignment.center,
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
正文(
“本地X:${uXLocalValue.toString()}\n本地Y:${{uXLocalValue.toString()}”),
手势检测器(
onPanStart:(详细信息)=>setState(
() {
这是.xLocalValue=details.localPosition.dx;
这是._yLocalValue=details.localPosition.dy;
},
),
onPanUpdate:(详细信息)=>setState(
() {
这是.xLocalValue=details.localPosition.dx;
这是._yLocalValue=details.localPosition.dy;
},
),
子:容器(
宽度:MediaQuery.of(context).size.width*0.9,
高度:100.0,
颜色:颜色,红色,
对齐:对齐.center,
子项:文本(“可滑动曲面”,
样式:TextStyle(颜色:Colors.white)),
),
),
],
),
),
//只是一个占位符,表示“刷卡”小部件右侧的页面
_buildSamplePage(“设置”),
],
),
);
}
@凌驾
void initState(){
super.initState();
这是。_navigationIndex=0;
这是。_pageController=pageController(
初始页:_导航索引,
);
}
Widget\u buildSamplePage(字符串文本){
//这只是返回一个填充页面的容器,
//中心有一个文本小部件。
返回容器(
宽度:MediaQuery.of(context).size.width,
高度:MediaQuery.of(context).size.height,
颜色:颜色。灰色[900],
对齐:对齐.center,
子:文本(
文本,
样式:TextStyle(
颜色:Colors.white,fontSize:30.0,fontWeight:fontWeight.bold),
),
);
}
小部件_buildBottomNavigationBar(){
//返回脚手架的底部导航栏
返回底部导航栏(
背景颜色:颜色。灰色[900],
selectedItemColor:Colors.redAccent,
unselectedItemColor:Colors.white,
项目:[
BottomNavigationBarItem(图标:图标(Icons.home),标签:“home”),
底部导航气压计(
图标:图标(图标。复选框\轮廓\空白),标签:“卡片”),
底部导航气压计(
图标:图标(图标。设置),标签:“设置”),
],
当前索引:_导航索引,
onTap:_onNavigationPageChanged,
);
}
void _onNavigationPageChanged(int newIndex){
//为导航栏设置新的导航索引
设置状态(()=>this.\u导航索引=newIndex);
//设置选定页面的动画
_pageController.animateToPage(
新索引,
曲线:Curves.easeInOut,
持续时间:持续时间(微秒:100),
);
}
}
你能试试这样的方法吗:
将此行添加到您的页面视图中
:
PageView(
...
物理:_navigationIndex==1?NeverScrollableScrollPhysics():AlwaysScrollableScrollPhysics(),
...
)
注意:编号
1
是因为带有gesturedetometer
的页面位于索引1
你好,Andrej,谢谢你的回答!我已经试过了