dart 我们如何在Flutter中创建这样的动画弹出菜单

izkcnapc  于 2023-06-19  发布在  Flutter
关注(0)|答案(1)|浏览(158)

我正在开发一个Flutter应用程序,我希望将一个视觉上吸引人的动画类似于WhatsApp中看到的动画。我附上了一个参考剪辑。x1c 0d1x具体来说,我感兴趣的是在消息气泡展开或折叠时复制图标和名称的平滑过渡、调整大小和滑动。如果您能提供一些代码片段或为我指出创建此效果的正确方向,那就太好了。
提前感谢您的帮助!

aelbi1ox

aelbi1ox1#

你可以在动画容器的帮助下做到这一点,有一个函数,当按下按钮时返回动画容器。下面是一个动画容器的示例代码,其中的一些动画可能会对您有所帮助。

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
    
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});


  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  int _counter = 0;

  bool _isCrossVisible = false;
  late AnimationController _animationController;
  late Animation<double> _rotationAnimation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    );
    // _rotationAnimation = Tween<double>(
    //   begin: 0,
    //   end: 0.5,
    // ).animate(_animationController);
  }

  void _toggleAnimation() {

    Future.delayed(Duration(milliseconds: 300), (){
      setState(() {
        showWidgets = true;
      });
    });
    setState(() {

      if(showWidgets) {
        showWidgets = false;
      }
      _isCrossVisible = !_isCrossVisible;
      if (_isCrossVisible) {
        _animationController.forward();
      } else {
        _animationController.reverse();
      }

    });

  }

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

  int _cIndex = 0;

  void _incrementTab(index) {
    setState(() {
      _cIndex = index;
    });
  }
  bool showWidgets = false;

  @override
  Widget build(BuildContext context) {


  
    return Scaffold(
      appBar: AppBar(
        
        title: Text(widget.title),
      ),
      body: Center(
        
        child: Column(
         
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      bottomNavigationBar: Container(
          height: 80,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.only(
                topRight: Radius.circular(40), topLeft: Radius.circular(40)),
            boxShadow: [
              BoxShadow(color: Colors.black38, spreadRadius: 0, blurRadius: 10),
            ],
          ),
          child: ClipRRect(
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(30.0),
              topRight: Radius.circular(30.0),
            ),
            child: BottomNavigationBar(
              items: <BottomNavigationBarItem>[
                BottomNavigationBarItem(icon: Icon(Icons.favorite), label: ""),
                BottomNavigationBarItem(icon: Icon(Icons.favorite), label: "")
              ],
            ),
          )),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,

      floatingActionButton: Positioned(
        bottom: 80,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            AnimatedContainer(
              duration: const Duration(milliseconds: 300),
              curve: Curves.easeInOut,
              width: _isCrossVisible ? 200.0 : 0.0,
              height: _isCrossVisible ? 200.0 : 0.0,
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.circular(28.0),
              ),
              child: Container(
                margin: EdgeInsets.only(left: 15 ,right: 15),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    showWidgets?Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(
                          "Mood chech-in",
                          style: TextStyle(color: Colors.white),
                        ),
                        Container(
                          height: 40,
                          width: 40,
                          decoration: BoxDecoration(
                            color: Colors.blueAccent.withOpacity(0.5),
                            borderRadius: BorderRadius.circular(15.0),
                          ),
                          child: Center(child:
                            Icon(Icons.ac_unit, color: Colors.white,)),
                        ),
                      ],
                    ): Container(),
                    showWidgets? Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text("Voice note", style: TextStyle(color: Colors.white)),
                        Container(
                          height: 40,
                          width: 40,
                          decoration: BoxDecoration(
                           color: Colors.blueAccent.withOpacity(0.5),
                            borderRadius: BorderRadius.circular(15.0),
                          ),

                          child: Center(child:
                          Icon(Icons.waves_sharp, color: Colors.white,)),
                        ),
                      ],
                    ): Container(),
                    showWidgets?Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text("Add photo", style: TextStyle(color: Colors.white)),
                        Container(
                          height: 40,
                          width: 40,
                          decoration: BoxDecoration(
                            color: Colors.blueAccent.withOpacity(0.5),
                            borderRadius: BorderRadius.circular(15.0),
                          ),
                          child: Center(child:
                          Icon(Icons.photo, color: Colors.white,)),
                        ),
                      ],
                    ): Container(),
                  ],
                ),
              ),
            ),
            Container(
              margin: EdgeInsets.only(bottom: 25),
              height: 70,
              width: 70,
              child: IconButton(
                icon: AnimatedBuilder(
                  animation: _animationController,
                  builder: (context, child) {
                    return Transform.rotate(
                      angle: _animationController.value * 0.5 * 3.1415,
                      child: child,
                    );
                  },
                  child: Icon(
                    _isCrossVisible ? Icons.close : Icons.add,
                    size: 30,
                    color: Colors.white,
                  ),
                ),
                onPressed: _toggleAnimation,
              ),
              decoration: BoxDecoration(
                color: Colors.blue,
                borderRadius: BorderRadius.circular(28.0),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

相关问题