Flutter how to change SVG after onTap with Gesture Detector - flutter

Wanna implement same functionality that is done here with images:
Flutter how to change image after onTap with Gesture Detector
Im using this package:
https://pub.dev/packages/flutter_svg/example
Even though I'm able to do this in IconButton, I need this in GestureDetector, not in IconButton, so just to be clear, need help how to implement SVG into GestureDetector not IconButton!
I'm able to get SVG rendered on the screen but can't figure it out how to implement it in GestureDetector, to render SVG on screen, Im doing it like this:
Expanded svgTest({double blackKeyWidth}) {
return Expanded(
child: Container(
child: IconButton(
icon: SvgPicture.asset(
'assets/images/1.svg',
fit: BoxFit.fill,
allowDrawingOutsideViewBox: true,
width: 500,
),
onPressed: null //do something,
),
),
);
}
Cant figure out how to implement SVG in GestureDetector, it can't go in as Image and Gesture Detector doesn't accept icon, or Im not doing it right.
Thank

If you want to change the image on the onTap method of the iconButton then you should have to change the path of the image in onTap method using setState
String imagePath = "assets/images/1.svg";
Expanded svgTest({double blackKeyWidth}) {
return Expanded(
child: Container(
child: IconButton(
icon: SvgPicture.asset(
'${imagePath}',
fit: BoxFit.fill,
allowDrawingOutsideViewBox: true,
width: 500,
),
onPressed: (){
setState(() {
imagePath = "assets/images/2.svg";
});
},
),
),
);
}
EDITED: (For Gesture Detector You Can Simply Wrap the SVG in it)
Replace the iconbutton with the GestureDetector and Add its onTap and onTapUp methods too.
GestureDetector(
onTap: () {
setState(() {
imagePath = "assets/images/2.svg";
});
},
onTapUp: (TapUpDetails tapUpDetails) {
setState(() {
imagePath = "assets/images/1.svg";
});
},
child: SvgPicture.asset(
'${imagePath}',
//fit: BoxFit.fill,
//allowDrawingOutsideViewBox: true,
//width: 500,
),
),
For More About GestureDetector and Flutter SVG Click Here

Related

How can I apply to image both ink well ripple effect during pressing and shimmer effect during loading?

I would like an image with shimmer effect applied while loading, similar to the fancy_shimmer_image package, to also receive ripple effect from an InkWell. Is there a way to do this?
The only way i found to do that is this "trick". Use a Stack for set a widget on top of your image. And then the inkwell effect works:
Stack(
children: [
// image with shimmer effect
FancyShimmerImage(
imageUrl:
'https://cdn.pixabay.com/photo/2014/06/03/19/38/board-361516_960_720.jpg',
shimmerBaseColor: Colors.amberAccent,
shimmerHighlightColor: Colors.redAccent,
shimmerBackColor: Colors.greenAccent,
),
//use this widget on top to do the effect
Positioned.fill(
child: Material(
color: Colors.transparent,
child: InkWell(
// splashColor: Colors.lightGreenAccent,
onTap: () {
print("on tap");
},
),
),
),
],
),
use the shimmer package and cached network image
and use it like that
CachedNetworkImage(
imageUrl: prov
.cart
.cartItems[index]
.image,
placeholder:
(context, url) =>
Shimmer.fromColors(
baseColor: Colors.grey.shade300,
highlightColor: Colors.white,
enabled: true, child: Image.asset(
'assets/images/product_placeholder.png',
),
)
),

onHover effect doesn't work on TextButton nor InkWell

I am developing a Flutter website. I have some links that I want to behave as a normal link: with a different color when the user hovers over them. However, I can't manage to make the color change.
I have tried using a TextButton with the onHover property. I have also tried with an Inkwell onHover property and hoverColor. I have wrapped the InkWell with Material and my onTap function is defined. I have also tried by wrapping this on an AnimatedContainer, but nothing seems to work.
Here is my code.
TextStyle? bodyTextStyle = Theme.of(context).textTheme.bodySmall;
InkWell(
color: Colors.transparent,
child: Text(
"data policy",
style: bodyTextStyle,
),
onTap: () => Navigator.of(context).pushNamed(
Navigation(context).routes["data policy"]),
onHover: (isHovering) {
setState(() {
bodyTextStyle = isHovering
? bodyTextStyle?.copyWith(
color: Theme.of(context).colorScheme.outline)
: bodyTextStyle;
});
},
),
I prefer using InkWell rather than TextButton in order to get rid of the shadow around the text that TextButton creates.
You can follow this snippet, hoverColor from InkWell can overlap.
InkWell(
child: SizedBox(
width: 100,
height: 100,
child: Text(
"Text",
style: linkTextStyle,
)),
onTap: () {},
hoverColor: Colors.transparent, //button splash color
onHover: (isHovering) {
linkTextStyle = isHovering
? TextStyle(color: Colors.red)
: TextStyle(color: Colors.cyanAccent);
setState(() {});
},
),
Also You can check MouseRegion, elevation on buttonStyle.

AbsorbPointer doesn't absorb tap event

As far as I know, due to this question Flutter AbsorbPointer vs IgnorePointer difference , AbsorbPointer will absorb tap event and other widgets below it will not receive tap event, but when I use AbsorbPointer like this. it still pass tap event to its parent:
GestureDetector(
onTap: () {
print('123'); // This still call when I tap on red container
},
child: Container(
color: Colors.green,
width: 300,
height: 300,
child: Center(
child: AbsorbPointer(
absorbing: true,
child: GestureDetector(
onTap: () {
print('567');
},
child: Container(
color: Colors.red,
width: 100,
height: 100,
),
),
),
),
),
)
So my question is does AbsorbPointer only work with widget same level in Stack and doesn't work with its parent?
In your code absorbing property having true value. which means your red container is not clickable. so parent green container have tapped. Incase if you change absorbing property to false, red container can able to tap.

Flutter rotate icon on button press with animation

I have a button with a icon inside of it. Right now I am using two different icons and change them onTap:
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
_isDropdownOpened = !_isDropdownOpened;
}
...
},
child:
_isDropdownOpened
? SvgPicture.asset(
'images/icons/arrow_down_primary.svg',
width: scaleWidth(12),
)
: SvgPicture.asset(
'images/icons/arrow_up_primary.svg',
width: scaleWidth(12),
),
),
);
This is working but I would like to have a RotationTransition. How can I rotate my icon onTap with animation, so I don't need two different SVGs?
use RotatedBox widget and change its rotation in your setState
you can do like this
child: RotatedBox(
quarterTurns: _isDropdownOpened? 2:0,
child: SvgPicture.asset(
'images/icons/arrow_down_primary.svg',
width: scaleWidth(12),
),
)
if you want to apply animation to the rotation as well consider looking to this

How to add a double tap gesture to video player without loosing the focus of controls?

I tried it by wrapping the
return ClipRRect(
borderRadius: BorderRadius.circular(30.0),
child: Chewie(
controller: _chewieController,
)
with
return Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(30.0),
child: Chewie(
controller: _chewieController,
),
),
Positioned.fill(child: GestureDetector(
onDoubleTap: (){
print('its double tapped ');
},
child: Container(
color: Colors.transparent,
height: double.infinity,
width: double.infinity,
),))
],
);
Now I am able to doubleTap, but with a single tap, controllers don't appear, Is there any way I can achieve both things.
With a doubleTap, I can call the like function and with onTap to show the controllers.
the package used above chewie 0.12.0
I don't know how Chewie is built but if there is GestureDetector you could change it to something like this:
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => setState(() => // show_controls,),
onDoubleTap:() => setState(() => // like behaviour,),
child: VideoWidget // or whatever is there
}
So you can have both listeners on one widget. I think that way onTap will be with some slight delay to check if it is not onDoubleTap. That way you don't have to put overlay on top of your widget.
If for some reason you want to have this overlay... then the interesting attribute here is behaviour as it decides if elements behind will receive events.
https://api.flutter.dev/flutter/rendering/PlatformViewHitTestBehavior-class.html
Update
Try changing into
GestureDetector(
behavior: HitTestBehavior.translucent,
onDoubleTap: (){
print('its double tapped ');
}
OR
In the github project, this line:
https://github.com/flutter/plugins/blob/master/packages/video_player/video_player/example/lib/main.dart#L290
It seems that the controls only show when video is in pause state. Its about this value controller.value.isPlaying.
Why not to control it in your own GestureDetector ?
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => setState(() => _controller.pause() ,), //changing here
onDoubleTap:() => setState(() => // like behaviour,),
child: VideoWidget // or whatever is there
}
Anyway, hope it you will find answer
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (_) {
setState(() {
isMute = !isMute;
_chewieController.setVolume(isMute ? 0 : 1);
});
},
onDoubleTap: (){
print('liked');
},
child: ClipRRect(
borderRadius: BorderRadius.circular(30.0),
child: Chewie(
controller: _chewieController,
),
),
);
on simple onTap on video, it shows the controller, onTap here is not getting override hence
onTapDown is used as an alternative to onTap to mute the video.