Reputation: 59
WORK : I am Creating App for book and I am linking images and swipe to next page I am using Gesture Detector for swipe next page and I am using InteractiveViewer for zoom page
PROBLEM : The problem is when I use pinch to zoom-in its successfully work but when Drag the page for seeing more words . It detect gesture Detector and It goes to other page ..
WHAT I WANT : I want to disable the gestureDetector when I am using InteractiveViewer, Like when I am in Zoom-in mode so the gestureDetector Disable and when I Zoom out the GestureDetector enable.
import 'package:flutter/material.dart';
class Screen2 extends StatefulWidget {
const Screen2({ Key key }) : super(key: key);
@override
_Screen2State createState() => _Screen2State();
}
class _Screen2State extends State<Screen2> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: appbarr(),
body: GestureDetector(
onHorizontalDragUpdate: (details) {
// Note: Sensitivity is integer used when you don't want to mess up vertical drag
int sensitivity = 8;
int senElse = -8;
if (details.delta.dx > sensitivity) {
Navigator.pop(context);
}
else if (details.delta.dx < senElse )
{
Navigator.push(context, MaterialPageRoute(builder: (context) => Screen3()));
}
},
child: InteractiveViewer(
panEnabled: true,
minScale: 0.5,
maxScale: 5,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/2.jpg"),
fit: BoxFit.fill,
),
),
),
),
)
);
}
}
Upvotes: 4
Views: 2053
Reputation: 1419
You need to check if the is the user has zoomed in or not. If the user has zoomed in we not render a GestureDetector
. We only make use of the GestureDetector
is the user hasn't zoomed. To check whether the user has zoomed in or not, we use a TranformationController
and compare it's current value with the identity matrix.
Here is the working code:
class Screen2 extends StatefulWidget {
const Screen2({ Key? key }) : super(key: key);
@override
_Screen2State createState() => _Screen2State();
}
class _Screen2State extends State<Screen2> {
final transformationController = TransformationController();
bool get userHasZoomedIn => (Matrix4.identity() - transformationController.value).infinityNorm() > 0.000001;
@override
Widget build(BuildContext context) {
final interactiveImage = InteractiveViewer(
panEnabled: true,
minScale: 0.5,
maxScale: 5,
transformationController: transformationController,
onInteractionEnd: (details) => setState((){}),
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/2.jpg"),
fit: BoxFit.fill,
),
),
),
);
final appBar = AppBar(title: Text('Title'));
if(userHasZoomedIn){
return Scaffold(
appBar: appBar,
body: interactiveImage,
);
}
return Scaffold(
appBar: appBar,
body: GestureDetector(
onHorizontalDragUpdate: (details) {
// Note: Sensitivity is integer used when you don't want to mess up vertical drag
int sensitivity = 8;
int senElse = -8;
if (details.delta.dx > sensitivity) {
Navigator.pop(context);
}
else if (details.delta.dx < senElse )
{
Navigator.push(context, MaterialPageRoute(builder: (context) => Screen3()));
}
},
child: interactiveImage,
)
);
}
}
Note that we call setState
in the InteractionViewer.onInteractionEnd
. Another approach would be to add a listener to the TransformationController
:
transformationController.addListener(() {
setState(() {});
});
You should not do that because that will fire setState()
way too often which causes a bad user experience and high CPU and GPU load.
Upvotes: 1