Problem
So I have a GestureDetector widget inside SingleChildScrollView (The scroll view is to accommodate smaller screens). The GestureDetector is listening for pan updates.
When the SingleChildScrollView is "in use" the GestureDetector cannot receive pan updates as the "dragging" input from the user is forwarded to the SingleChildScrollView.
What I want
Make the child GestureDetector have priority over the SingleChildScrollView when dragging on top of the GestureDetector -- but still have functionality of scrolling SingleChildScrollView outside GestureDetector.
Example
If you copy/paste this code into dart pad you can see what I mean. When the gradient container is large the SingleChildScrollView is not active -- you are able to drag the blue box and see the updates in the console. However, once you press the switch button the container becomes smaller and the SingleChildScrollView becomes active. You are now no longer able to get pan updates in the console only able to scroll the container.
Sidenote: It seems that if you drag on the blue box quickly you are able to get drag updates but slowly dragging it just scrolls the container. I'm not sure if that's a bug or a feature but I'm not able to reproduce the same result in my production app.
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
const MyWidget({Key? key}) : super(key: key);
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool enabled = false;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: enabled ? 200 : 400,
child: SingleChildScrollView(
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment(0.8, 0.0),
colors: <Color>[Color(0xffee0000), Color(0xffeeee00)],
tileMode: TileMode.repeated,
),
),
height: 400,
width: 200,
child: Center(
child: GestureDetector(
onPanUpdate: (details) => print(details),
child: Container(
height: 100,
width: 100,
color: Colors.blue,
child: Center(
child: Text(
"Drag\nme",
textAlign: TextAlign.center,
),
),
),
),
),
),
),
),
ElevatedButton(
onPressed: () => setState(() {
enabled = !enabled;
}),
child: Text("Switch"))
],
);
}
}