mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-06-13 10:42:12 +00:00
feedback on click
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
Some checks are pending
Flutter analyze & test / flutter_analyze_and_test (push) Waiting to run
This commit is contained in:
parent
92b615959b
commit
9224c77eca
1 changed files with 65 additions and 5 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/physics.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
|
||||||
|
|
@ -18,8 +19,62 @@ class ContextMenu extends StatefulWidget {
|
||||||
State<ContextMenu> createState() => _ContextMenuState();
|
State<ContextMenu> createState() => _ContextMenuState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ContextMenuState extends State<ContextMenu> {
|
class _ContextMenuState extends State<ContextMenu>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
Offset? _tapPosition;
|
Offset? _tapPosition;
|
||||||
|
late final AnimationController _controller;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_controller =
|
||||||
|
AnimationController(
|
||||||
|
vsync: this,
|
||||||
|
lowerBound: double.negativeInfinity,
|
||||||
|
upperBound: double.infinity,
|
||||||
|
value: 0,
|
||||||
|
)..addListener(() {
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_controller.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTapDown(TapDownDetails details) {
|
||||||
|
_tapPosition = details.globalPosition;
|
||||||
|
_controller.animateTo(
|
||||||
|
1,
|
||||||
|
duration: const Duration(milliseconds: 60),
|
||||||
|
curve: Curves.easeOut,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTapUp(TapUpDetails details) {
|
||||||
|
_bounce();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onTapCancel() {
|
||||||
|
_bounce();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _bounce() {
|
||||||
|
const spring = SpringDescription(
|
||||||
|
mass: 1,
|
||||||
|
stiffness: 400,
|
||||||
|
damping: 15,
|
||||||
|
);
|
||||||
|
final simulation = SpringSimulation(
|
||||||
|
spring,
|
||||||
|
_controller.value,
|
||||||
|
0,
|
||||||
|
_controller.velocity,
|
||||||
|
);
|
||||||
|
_controller.animateWith(simulation);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _getIcon(dynamic icon) {
|
Widget _getIcon(dynamic icon) {
|
||||||
return Padding(
|
return Padding(
|
||||||
|
|
@ -45,6 +100,7 @@ class _ContextMenuState extends State<ContextMenu> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unawaited(HapticFeedback.heavyImpact());
|
unawaited(HapticFeedback.heavyImpact());
|
||||||
|
_bounce();
|
||||||
|
|
||||||
await showMenu(
|
await showMenu(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -82,12 +138,16 @@ class _ContextMenuState extends State<ContextMenu> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final scale = 1.0 - (_controller.value * 0.02);
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onLongPress: _showCustomMenu,
|
onLongPress: _showCustomMenu,
|
||||||
onTapDown: (details) {
|
onTapDown: _onTapDown,
|
||||||
_tapPosition = details.globalPosition;
|
onTapUp: _onTapUp,
|
||||||
},
|
onTapCancel: _onTapCancel,
|
||||||
child: widget.child,
|
child: Transform.scale(
|
||||||
|
scale: scale,
|
||||||
|
child: widget.child,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue