Flutter GestureDetector onTap in certain page not working - flutter

Hi I managed to create a button that will show a tooltip and that tooltip will have a text content and a button, that button will redirect my app to my privacy policy page, the problem is when I redirect my app to that page using the button inside my tooltip.
All of my GestureDetector become disabled / not working even when I tried to do some simple task such as print().
Anyone know how to fix this ?
Here's my code:
ReusableTooltip(
tooltipHeader: '',
tooltipText: 'deviceContactClause',
tooltipDirection: AxisDirection.down,
tooltipChild: Container(
alignment: Alignment.center,
width: 45,
height: 40,
color: Colors.transparent,
child: SvgPicture.asset(
'assets/logo/Information.svg',
),
),
additionalWidget: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const PrivacyPolicyPage()
),
);
},
child: Container(
child: Text('seePrivacyPolicy',
),
),
),

Try this Gesture behavior
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
},
),

Related

How to change state to previous state in bloc?

I have sigIn function that get data from Api and move to another screen if request is successful and if request is not successful then show alertDialog
I change state and before fetching data I show CircularProgressIndicator to make user know that data is fetching.
But when alertDialog window pops up and I close it then CircularProgressIndicator doesn't disappear. How to remove WaitingSignInAuth and show me Scaffold with inputs
When error comes then I emit ErrorSignInAuth but why there is WaitingSignInAuth to.. Why ErrorSignInAuth doesn't replace WaitingSignInAuth or it should work differently?
This is the code:
#override
Widget build(BuildContext context) {
return BlocConsumer<AuthCubit, AuthState>(
listener: (context, state) {
if (state is WaitingSignInAuth) {
showDialog(
context: context,
builder: (context) => Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black.withOpacity(0.6),
child: const Center(
child: CircularProgressIndicator(
strokeWidth: 1,
color: Colors.black,
backgroundColor: Colors.white,
),
),
));
}
if (state is ErrorSignInAuth) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Bad request"),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text("Error")
],
),
),
actions: <Widget>[
TextButton(
child: const Text("Close"),
onPressed: () {
Navigator.pop(context); // If i press it then alertDialog diappears but not the loading circle
},
)
],
);
}
);
}
},
);
}
This is how it looks like:
The issue is, that you showDialog() twice. First is shown when WaitingSignInAuth state is fired, and the second one when you receive ErrorSignInAuth.
So Navigator.pop(context); in the "error" alert dialog closes only the showDialog that you've triggered in if (state is ErrorSignInAuth), the second dialog, which contains progress indicator is still visible.
To easy fix it, you can change your code to:
TextButton(
child: const Text("Close"),
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
)
But in my opinion thats not the best fix to your issue. IMO you don't need to show ProgressIndicator for WaitingSignInAuth in the dialog. Adjust your UI in the way, that the container with progress indicator will be displayed over it, but this doesn't need to be a dialog.

Flutter: How to navigate to another page without losing the first background?

My question is about dart language, these are my web pages:
Web page #1:
code:
return BackdropFilter(
filter: ImageFilter.blur(sigmaX: 2, sigmaY: 2),
child: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Container(...
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (ctx) => SignUpNameEmailPassword());
},
Web page #2:
Code:
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
showDialog(
context: context,
builder: (ctx) => WeSentYouAnEmail());
},
child: Container(
child: Center(
child: Icon(
Icons.arrow_forward,
size: 40,
color: Color(0xff7E7E7E),
),
),
),
),
],
),
Web page #3:
As you can see, each time I navigate to another page the background is darker, how to maintain the web page #1's background on each webpage?
Thank you in advance
Just set the second, third and so on showDialog calls with property barrierColor to Colors.transparent. Something like below:
showDialog(
context: context,
barrierColor: Colors.transparent,
builder: (ctx) => SignUpNameEmailPassword());
The issue is that each dialog is getting stacked. Before you call a new showDialog do
Navigator.pop(context);
So you remove the previous pop up and add a new one.
Please note that you should be calling navigator.pop only if the dialog is displayed elseit will pop the main screen
It seems that you push each page what makes the background darker.
You can try to navigate bewtween your pages like this.
Route route = MaterialPageRoute(builder: (context) => NextPage());
Navigator.pushReplacement(context, route);
This will push and replace the last page of the stack.

have search bar handle one tap and two taps differently

I am pretty new to flutter/dart, so this might be a silly question...
I wanted to have a search bar, that when tapped the first time, displays a series of listview tiles (like pre-canned search terms). I wanted a subsequent tap to then open the soft keyboard for user input. As it stands now, a single tap opens the listview tiles, and also opens the soft keyboard.
After some looking around, I am thinking I would need to wrap the searchbar in a GestureDetector, and handle the tap / double-tap gestures through that. What I can't quite figure out, is how to tie the GestureDetector gestures, ontap and ondoubletap, to the child widget actions... I think when the searchbar gets focus (onTap), the soft keyboard opens, so not sure if that behavior can be (easily) uncoupled...
The flutter cookbook example uses this:
ScaffoldMessenger.of(context).showSnackBar(snackBar);
but the API docs say this only manages snackbars and MaterialBanners:
"Manages SnackBars and MaterialBanners for descendant Scaffolds."
Here is the framework I have so far:
Widget searchBar() {
//final FloatingSearchBarController searchBarController = FloatingSearchBarController();
return
GestureDetector(
onTap: () =>{},
onDoubleTap: () => {},
child: FloatingSearchBar(
controller: searchBarController,
hint: "search",
openAxisAlignment: 0.0,
width: 600,
axisAlignment: 0.0,
scrollPadding: const EdgeInsets.only(top: 16, bottom: 20),
elevation: 4.0,
onQueryChanged: (query) {
},
builder: (BuildContext context, Animation<double> transition) {
return ClipRRect(
child: Material(
color: Colors.white,
child: Container(
color: Colors.white,
child: Column(
children: [
ListTile(
title: const Text('Item 1'),
onTap: () {},
),
ListTile(
title: const Text('Item 2'),
onTap: () {},
),
ListTile(
title: const Text('Item 3'),
onTap: () {},
),
],
),
),
)
);
},
)
);
Any thoughts would be greatly appreciated!

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.

Link pages to rowCell's in Flutter

I have two rowCell's inside a Row widget in my app and I want to assign them different pages. I've tried putting the rowCell's in a GestureDetector, a FlatButton but neither of them have worked (as they should be linked to the Row widget and they need separate links for separate pages.)
Here is the part of my code:
...
new Divider(
height: _height / 20,
color: Colors.grey,
),
new Row(
children: <Widget>[
rowCell(10250, 'MEETUPS'),
rowCell(1520, 'FRIENDS'),
],
),
new Divider(height: _height / 20, color: Colors.grey),
...
Any solutions?
Just wrap the rowCell with GestureDetectorthen you will get separate onTap function with the same design.
Otherwise, you can use GestureDetector inside the rowCell(). And pass a function to the rowCell() to attach to the GestureDetector.
Widget rowSell(<your parameters>, Function onTapFunction) {
return GestureDetector(
onTap: onTapFunction,
child: <Your child>
),
}
And pass the function like:
new Row(
children: <Widget>[
rowCell(10250, 'MEETUPS', (){ <on Tap code> }),
rowCell(1520, 'FRIENDS', (){ <on Tap code> }),
],
),
The GestureDetector probably isn't working because you're wrapping it around the text and in that scenario, it's rare that it will work because you the onTap space is relative to space the text covers on the screen.
Try giving some padding inside the rowCell and then wrap it in a gesture detector, it will probably break your layout but at least you will know the problem and adjust accordingly.
Please try this...
If rowCell is return widget then wrap rowCell with GestureDetector and get click of that...
...
new Divider(
height: _height / 20,
color: Colors.grey,
),
new Row(
children: <Widget>[
GestureDetector(onTap: () {}, child: rowCell(10250, 'MEETUPS')),
GestureDetector(onTap: (){},child: rowCell(1520, 'FRIENDS')),
],
),
new Divider(height: _height / 20, color: Colors.grey),
...
From the comment from above you mention, I assume your rowCell function returns an Expanded widget.
So in rowCell function, inside Expanded widget add Inkwell widget. Also add one more argument which tells the page that you want to navigate to (onTap).
Widget rowCell(int count, String title, Widget navTo){
return Expanded(
child: Inkwell(
onTap: () => _navToPage(navTo)
child: .... //Your child widget
),
);
}
void _navToPage(Widget navTo){
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => navTo,
),
);
}
new Divider(height: _height / 20, color: Colors.grey),
new Row(
children: <Widget>[
GestureDetector(onTap: () {}, child: rowCell(10250, 'MEETUPS', MeetupsPage())),
GestureDetector(onTap: (){},child: rowCell(1520, 'FRIENDS', FriendsListPage())),
],
),
new Divider(height: _height / 20, color: Colors.grey),