是否可以从点击屏幕的位置开始显示带有动画的AlertDialog?

问题描述 投票:0回答:1

是否可以从点击屏幕的位置开始显示

AlertDialog
,类似于
animations
包中的Container transform?在这种情况下,容器最初不会显示,应该通过从空白区域接收带有
onTap
GestureDetector
来触发。然后,我想显示如上所述的动画对话框。

flutter dart animation flutter-animation
1个回答
1
投票

我客气了,Flutter 的动画包没有像 Material Motion 那样内置 Container Transform。但是,您可以创建一个从点击屏幕的位置开始的自定义动画对话框。

要实现此目的,您可以按照以下一般步骤操作:

  1. GestureDetector
    包裹主要内容以检测空白区域上的点击。
  2. 检测到点击后,记录点击的位置(即
    Offset
    )。
  3. 在记录的位置显示隐藏或空的容器,并使用动画(例如,
    AnimatedContainer
    )以所需的动画显示对话框的内容。
  4. 您可以使用像
    animations
    这样的动画库或Flutter内置的
    AnimationController
    AnimationBuilder
    来控制动画。

以下是如何执行此操作的简化示例:

import 'package:flutter/material.dart';

class AnimatedDialogExample extends StatefulWidget {
  @override
  _AnimatedDialogExampleState createState() => _AnimatedDialogExampleState();
}

class _AnimatedDialogExampleState extends State<AnimatedDialogExample>
    with SingleTickerProviderStateMixin {
  AnimationController _animationController;
  Offset _tapPosition;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 500),
    );
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  void _onTap(BuildContext context, TapDownDetails details) {
    setState(() {
      _tapPosition = details.globalPosition;
    });
    _animationController.forward(from: 0.0);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (details) => _onTap(context, details),
      child: Scaffold(
        appBar: AppBar(
          title: Text('Animated Dialog Example'),
        ),
        body: Center(
          child: Text('Tap on an empty area to trigger the dialog.'),
        ),
        floatingActionButton: _buildAnimatedDialog(),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      ),
    );
  }

  Widget _buildAnimatedDialog() {
    return AnimatedBuilder(
      animation: _animationController,
      builder: (context, child) {
        final animationValue = _animationController.value;
        final dialogOpacity = Curves.easeInOut.transform(animationValue);
        final dialogScale = Tween<double>(begin: 0.0, end: 1.0)
            .transform(animationValue);

        final screenHeight = MediaQuery.of(context).size.height;
        final screenWidth = MediaQuery.of(context).size.width;
        final dialogSize = 200.0; // Adjust this size as per your requirement

        return Positioned(
          top: _tapPosition.dy - (dialogSize / 2) + (dialogSize / 2) * dialogScale,
          left: _tapPosition.dx - (dialogSize / 2) + (dialogSize / 2) * dialogScale,
          child: Opacity(
            opacity: dialogOpacity,
            child: Transform.scale(
              scale: dialogScale,
              child: Container(
                width: dialogSize,
                height: dialogSize,
                color: Colors.blue,
                child: Center(
                  child: Text('Your Dialog Content'),
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

void main() {
  runApp(MaterialApp(
    home: AnimatedDialogExample(),
  ));
}

在此示例中,当用户点击空白区域时会触发

_onTap
方法。
_tapPosition
存储点击的位置,然后
_animationController
用于设置对话框的不透明度和比例的动画。对话框将出现并从点击位置开始增长,从而创建由点击手势触发对话框的效果。

© www.soinside.com 2019 - 2024. All rights reserved.