How to set the duration of onLongPress - flutter

I know onLongPress would trigger after a certain period of time (like 500 ms or so). But what I want to do is to trigger some action when user presses the button for like 3 seconds. Actually I want to set the duration for onLongPress.
ElevatedButton(
onPressed: () => print('ok I\'m just fine'),
onLongPress: () => print('Trigger me when user presses me for like 3 seconds'),
style: ElevatedButton.styleFrom(
primary: Colors.red,
elevation: 4,
),

How I did it:
onLongPress: () {
Timer(Duration(milliseconds: (longPressIncrementDuration > 500) ? longPressIncrementDuration - 500 : 0), //enter function here//);
// I subtract 500 ms from required time limit as longpress on flutter activates after 500ms
},

You can solve your problem this way, use onPanCancel and onPanDown of GestureDetector with timer.
class _MyHomePageState extends State<MyHomePage> {
Timer _timer;
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: GestureDetector(
onPanCancel: () => _timer?.cancel(),
onPanDown: (_) => {
_timer = Timer(Duration(seconds: 3), () { // time duration
// your function here
})
},
),
);
}
}
let me know if it work for you.

I made a package today where you can set the duration on GestureDetector. if you wan you can try it out https://pub.dev/packages/custom_long_tap

GestureDetector(
onTapDown: (_) { //Detect when you click the element
_timer = Timer(
const Duration(seconds: 5),
() {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ListOrder(),
),
);
},
);
print('tapping');
},
onTapUp: (_) { // Detect and cancel when you lift the click
_timer!.cancel();
print('cancel');
},
child: const Icon(Icons.person_search),
),

Related

how do i set the button to play Interstitial ad first instead it sync with other action

how do i set the button on the first press, it shown the ad, after closing the ad its still back to the previous menu and the second tap, it load other action.
thanks in advance.
void showPopUpButton(BuildContext context) {
showDialog(
context: context,
builder: (context) => Dialog(
backgroundColor: Colors.transparent,
child: IconButton(
icon: Image.asset('lib/images/last.png'),
iconSize: 260,
onPressed: () async {
_showInterstitialAd();
setState(() {});
initRandomImage();
Navigator.pop(context);
final player = AudioPlayer();
await player.play(AssetSource('Sound1.wav'),
volume: 1.0);
},
),
),
);
}
Try including your IconButton inside a StatefulWidget and inside the StatefulWidget, keep the record of whether the ad has been already displayed or not, before navigating to the actual action as below:
Your function:
void showPopUpButton(BuildContext context) {
showDialog(
context: context,
builder: (context) => Dialog(
backgroundColor: Colors.transparent,
child: DialogButtonWidget(),
),
);
}
The DialogButtonWidget:
class DialogButtonWidget extends StatefulWidget {
const DialogButtonWidget({Key? key}) : super(key: key);
#override
State<DialogButtonWidget> createState() => _DialogButtonWidgetState();
}
class _DialogButtonWidgetState extends State<DialogButtonWidget> {
bool _interstitialAdDisplayed = false;
#override
Widget build(BuildContext context) {
return IconButton(
icon: Image.asset('lib/images/last.png'),
iconSize: 260,
onPressed: () async {
if (!_interstitialAdDisplayed) {
_showInterstitialAd();
setState(() {
_interstitialAdDisplayed = true;
});
} else {
initRandomImage();
Navigator.pop(context);
final player = AudioPlayer();
await player.play(AssetSource('Sound1.wav'), volume: 1.0);
}
},
);
}
}

How to stop the loader after 5 seconds

I'm trying to display the loader on whole screen on button click and after 5 seconds displaying a dialogue box an want to stop the loader. here is my code
setState(() {
_isLoading = true;
});
_isLoading
? showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: Center(
child: CircularProgressIndicator(
color: Apptheme.primaryColor,
),
),
);
})
: null;
await Future.delayed(const Duration(seconds: 5), () {
AppDialogs()
.showInfoDialogue(context, "Sorry all drivers are busy!", () {
Navigator.pop(context);
});
});
setState(() {
_isLoading = false;
});
calling this code on button click, it shows the dialogue box after 5 seconds but not stop the loader. kindly help where i'm doing wrong.
Once you call showDialog the loader is mounted on the screen and it will not disappear, if you have a simple setup calling .pop() on the navigator will remove your loader before you show the dialog. Modification required:
await Future.delayed(const Duration(seconds: 5), () {
Navigator.of(context).pop();
AppDialogs().showInfoDialogue(context, "Sorry all drivers are busy!", () {
Navigator.pop(context);
});
});
You can define thai cde in instate event
Future.delqyed(duration:Duration(seconds:5),(){showdialog((BuildContext context,Widget child)=>Dialog());
});
You can try this

In flutter, how do I dynamically update an alert dialog's action list?

I am trying to dynamically update an alert dialog's action list when something takes place in the alert dialog. Essentially, by default the dialog has a "Cancel" action button. But once the user does something in the dialog, I want it to have a "Cancel" and an "Accept" button. I have tried using a StatefulBuilder, which is how I am getting the rest of the dialog to update state. However, it is not working with the action buttons.
I've tried conditionally rendering the button, as well as generating a list to use for the dialog actions, and using setState to add to the list when an action takes place. Neither works, although other state updates within the dialog's content work with the StatefulBuilder. The dialog opens with only the "Cancel" action, and will not update to include the "Accept" action as well.
await showDialog<void>(
context: context,
builder: (BuildContext context) {
int? selectedRadio = 0;
return AlertDialog(
content: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Column(
mainAxisSize: MainAxisSize.min,
children: List<Widget>.generate(4, (int index) {
return Radio<int>(
value: index,
groupValue: selectedRadio,
onChanged: (int? value) {
setState(() => selectedRadio = value);
},
);
}),
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
selectedRadio == 1 ? TextButton(
child: Text('Accept'),
onPressed: () {
Navigator.of(context).pop();
},
) : SizedBox.Shrink(),
],
);
},
),
);
},
);
Try putting the AlertDialog inside the StatefulBuilder
return StatefulBuilder(
builder: (context, setState) {
return AlertDialog(
Create a StatefulWidget to display your AlertDialog, and manage selectedRadio there. Also take advantage of Dart's collection if to handle the conditional button:
class MyDialog extends StatefulWidget {
const MyDialog({Key? key}) : super(key: key);
#override
State<MyDialog> createState() => _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
int selectedRadio = 0;
#override
Widget build(BuildContext context) {
return AlertDialog(
actions: <Widget>[
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
if (selectedRadio == 1)
TextButton(
child: Text('Accept'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
content: Column(
mainAxisSize: MainAxisSize.min,
children: List<Widget>.generate(4, (int index) {
return Radio<int>(
value: index,
groupValue: selectedRadio,
onChanged: (int? value) {
setState(() => selectedRadio = value!);
},
);
}),
));
}
}
After this, you can display your dialog for example like this:
TextButton(
child: Text('Pressme'),
onPressed: () async => await showDialog<void>(
context: context,
builder: (BuildContext context) {
return const MyDialog();
},
))

How to activate / deactivate floating button with timer in flutter?

I need to show floating button for users and i want them to use it only one time per hour in flutter. So how can i do it? can anyone guide me to add countdown or timer method for floating button?
This is my floating button code
Widget _floating(BuildContext context,bool isVerified){
if (isVerified)
return FloatingActionButton(
//TODO: customise according to your needs
onPressed:() async{
},
tooltip: 'Increment',
child: Icon(Icons.add),
);
else
return Container();
}
}
Try this,
Set Defaults,
bool _buttonVisibility = false;
DateTime lastClicked;
FAB,
if (lastClicked == null) {
setState(() => _buttonVisibility = true);
}
floatingActionButton: Visibility(
visible: _buttonVisibility,
child: FloatingActionButton(
child: Icon(Icons.plus_one),
onPressed: () {
setState(() {
lastClicked = DateTime.now();
_buttonVisibility = false;
// change this seconds with `hours:1`
new Timer(Duration(seconds: 5),
() => setState(() => _buttonVisibility = true));
});
},
),
),
You can try to use the widget AnimatedPositioned Widget with Timer() to show and hide the button with something like:
import
import 'dart:async';
then in the StatefulWidget:
// Inside your StatefulWidget
[...]
Timer t;
double position = -300.0; // or any of your value
#override
void initState() {
super.initState();
t = Timer(const Duration(hours: 1), () {
_position = 0;
}
}
[...]
Widget myAnimatedFloatingActionButton(){
AnimatedPositioned(
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
left: _position,
child: FloatingActionButton(),
);
}
[...]
And in your onPressed() reset the Timer.
Of course, adapt the _position and Timer initial value to your needs

Autoclose dialog in Flutter

I want to autoclose dialog a few seconds after opening. The solution that I found is to call Navigator.of(context).pop(); delayed and it works. But the problem occurs if I closed it manually (by clicking outside) before the execution of the Navigator.pop command. Then Navigator.pop just closes the app and I see just a black screen.
I need a way to destroy this delay on closing the dialog or to find another workaround.
showDialog(
context: context,
builder: (BuildContext builderContext) {
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).pop();
});
return AlertDialog(
backgroundColor: Colors.red,
title: Text('Title'),
content: SingleChildScrollView(
child: Text('Content'),
),
);
}
);
You can use a Timer to achieve this. You can cancel the timer whenever you want.
Declare a timer property in your class:
Timer _timer;
And change your showDialog code like:
showDialog(
context: context,
builder: (BuildContext builderContext) {
_timer = Timer(Duration(seconds: 5), () {
Navigator.of(context).pop();
});
return AlertDialog(
backgroundColor: Colors.red,
title: Text('Title'),
content: SingleChildScrollView(
child: Text('Content'),
),
);
}
).then((val){
if (_timer.isActive) {
_timer.cancel();
}
});
In this case, you are using the wrong context.
Try to change the context you are using in the "pop"
You have this BuildContext builderContext, use that builderContext like:
Navigator.of(builderContext).pop();
You can use different way of executing pop() request using Timer
_timer = Timer(Duration(seconds: _timerTimeoutInterval), () {
Navigator.of(context).pop();
});
And in case you want to cancel the timer you can call this:
if (_timer != null && _timer.isActive) {
_timer.cancel();
}