Я хотел бы иметь возможность смахнуть вниз, чтобы закрыть, но с Hero-Animation
.
Я пробовал использовать GestureDetector
вот так:
body: GestureDetector(
onVerticalDragDown: (details) {
Navigator.pop(context);
},
child:
Анимация с этим выглядит нормально, но проблема в том, что она poping
практически при любом жесте. Я бы хотел, чтобы он появлялся только в том случае, если пользователь действительно проводит пальцем вниз.
Также должно быть какое-то свойство finished
, чтобы анимация отменялась, если пользователь не полностью проводит пальцем вниз. Возможно ли это, и если да, то как? Я ничего не нашел по этому поводу ..
Желаемый результат должен выглядеть так:
Как видите, я могу провести вниз, а также отменить pop
, не полностью проведя пальцем вниз.
Текущая анимация:
При нажатии кнопки закрытия анимация работает нормально. Однако, если я начну перетаскивать, анимация должна начаться, а если я ее закончу, она должна pop
, или я также могу отменить анимацию, и анимация вернется к нормальному экрану.
Это мой код, если это полный код, если это помогает:
Widget build(BuildContext context) {
return Scaffold(
body: GestureDetector(
onVerticalDragDown: (details) {
Navigator.pop(context);
},
child: Stack(
children: [
Hero(
tag: month.name + 'background',
// transitionOnUserGestures: true,
child: Container(
// color: CustomColors.darkCustom,
decoration: BoxDecoration(
color: CustomColors.darkCustom,
borderRadius: BorderRadius.circular(30.0),
),
),
),
Positioned(
right: 30,
top: 15,
child: SafeArea(
child: Hero(
// transitionOnUserGestures: true,
tag: month.name + 'close',
child: Container(
height: 45,
width: 45,
child: RawMaterialButton(
fillColor: CustomColors.lightGreyCustom,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
// elevation: 10,
shape: CircleBorder(),
onPressed: () {
Navigator.of(context).pop();
},
child: SvgPicture.asset('assets/images/close.white.svg',
height: 25, width: 25),
),
),
),
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SafeArea(
bottom: false,
child: SizedBox(height: 20),
),
Row(
children: [
Padding(
padding:
const EdgeInsets.only(left: 45, top: 45, bottom: 35),
child: Hero(
// transitionOnUserGestures: true,
tag: month.name + 'text',
// sized box to prevent flickering bug
child: SizedBox(
height: 40,
width: 200,
// material is need for Hero + Text
child: Material(
color: Colors.transparent,
child: Text(
month.name,
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontFamily: Fonts.glossAndBloom,
),
),
),
),
),
),
],
),
Hero(
tag: month.name + 'frame',
child: Container(
height: Constants.width(context) - 60,
width: Constants.width(context) - 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
border: Border.all(color: Colors.white, width: 5),
),
),
),
],
)
],
),
),
);
}
В Swift мне удалось добиться анимации с помощью этого кода:
@objc private func handlePan(gestureRecognizer:UIPanGestureRecognizer) {
// calculate the progress based on how far the user moved
let translation = panGR.translation(in: nil)
let progress = translation.y / 2 / view.bounds.height
switch panGR.state {
case .began:
// begin the transition as normal
self.dismissView()
break
case .changed:
Hero.shared.update(progress)
default:
// finish or cancel the transition based on the progress and user's touch velocity
if progress + panGR.velocity(in: nil).y / view.bounds.height > 0.3 {
self.dismissView()
Hero.shared.finish()
} else {
Hero.shared.cancel()
}
}
}