dart 如何在Flutter中的另一个页面上使用在不同页面上定义的SlideTransition

g6ll5ycj  于 5个月前  发布在  Flutter
关注(0)|答案(1)|浏览(81)

我甚至不确定我为我的问题选择了正确的标题。我设计了一个只有一个主页的主页,这个主页有两个不同的小部件。我把这些小部件分成两个不同的dart文件,以避免写脏代码。当我把所有的代码写在一个页面上时,我可以达到我想要的。但是当我把两个页面分开时,我有一个问题,我不能解决。

这是我想要的。在我的dart文件DashboardWidget的第57行,有一个GestureDetector 'ontap' function。我用这个按钮改变了我的'isMenuOpen'变量值。当我按下这个按钮并改变了我的isMenuOpen value to true & false时,我想通过这个值改变两个不同文件中的两个不同动画。所以每次“ontap”功能被触发时,我的DashboardWidget动画在前进/后退之间切换。同时,我的MenuWidget动画也在前进/后退之间切换。

[This is the image I want]https://i.stack.imgur.com/LQEZN.png)的数据类型
[And this is the screen I see.]https://i.stack.imgur.com/QdUfN.png)的一个字符串
我希望我已经很好的解释了。英语不是我的第一语言,我是编程新手。提前谢谢你。

首页.dart

import 'package:flutter/material.dart';
import 'package:flutter_slidermenu_and_dashboard/constants/constants.dart';
import 'package:flutter_slidermenu_and_dashboard/widgets/dashboard_widget.dart';
import 'package:flutter_slidermenu_and_dashboard/widgets/menu_widget.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      backgroundColor: Constants.dashboardBackground,
      body: SafeArea(
        child: Stack(
          children: [
            DashboardWidget(),
            MenuWidget(),
          ],
        ),
      ),
    );
  }
}

字符串

菜单小部件.dart

import 'package:flutter/material.dart';
import 'package:flutter_slidermenu_and_dashboard/constants/constants.dart';

class MenuWidget extends StatefulWidget {
  
  const MenuWidget({super.key});

  @override
  State<MenuWidget> createState() => _MenuWidgetState();
}

class _MenuWidgetState extends State<MenuWidget>
    with SingleTickerProviderStateMixin {
  late Animation<Offset> slideTransitionAnimation;
  late AnimationController animationController;
  @override
  void initState() {
    animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
    slideTransitionAnimation =
        Tween(begin: const Offset(-1, 0), end: const Offset(0, 0)).animate(
      CurvedAnimation(parent: animationController, curve: Curves.easeIn),
    );
    animationController.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SlideTransition(
      position: slideTransitionAnimation,
      child: Padding(
        padding: const EdgeInsets.only(left: 12.0, right: 240),
        child: Align(
          alignment: Alignment.centerLeft,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              buildMenuItem('Dashboard', Icons.wallet_outlined),
              buildMenuItem('Messages', Icons.message_outlined),
              buildMenuItem('Utility Bills', Icons.document_scanner),
              buildMenuItem('Fon Transfer', Icons.compare_arrows_outlined),
              buildMenuItem('Branches', Icons.home_work_outlined),
            ],
          ),
        ),
      ),
    );
  }

  Widget buildMenuItem(String title, IconData icon) {
    return ListTile(
      selectedTileColor: Colors.white,
      contentPadding: const EdgeInsets.all(0),
      leading: Icon(icon, color: Constants.iconColor),
      title: Text(title, style: Constants.menuTextStyle),
      onTap: () {},
    );
  }
}

Jmeter 板小部件.dart

import 'package:flutter/material.dart';
import 'package:flutter_slidermenu_and_dashboard/constants/constants.dart';

class DashboardWidget extends StatefulWidget {
  const DashboardWidget({super.key});

  @override
  State<DashboardWidget> createState() => _DashboardWidgetState();
}

class _DashboardWidgetState extends State<DashboardWidget>
    with SingleTickerProviderStateMixin {
  bool isMenuOpen = false;
  late Animation<double> scaleAnimation;
  late AnimationController animationController;

  @override
  void initState() {
    animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
    scaleAnimation = Tween(begin: 1.0, end: 0.7).animate(animationController);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedPositioned(
      left: isMenuOpen ? 0.4 * Constants.getScreenWidth(context) : 0,
      top: 0,
      right: isMenuOpen ? -0.3 * Constants.getScreenWidth(context) : 0,
      bottom: 0,
      duration: const Duration(milliseconds: 500),
      child: ScaleTransition(
        scale: scaleAnimation,
        child: Material(
          borderRadius:
              isMenuOpen ? BorderRadius.circular(25) : BorderRadius.zero,
          elevation: isMenuOpen ? 12 : 0,
          color: Constants.dashboardBackground,
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.only(left: 12, top: 8, right: 12),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    GestureDetector(
                      onTap: () {
                        setState(() {
                          if (isMenuOpen) {
                            animationController.reverse();
                          } else {
                            animationController.forward();
                          }
                          isMenuOpen = !isMenuOpen;
                        });
                      },
                      child: const Icon(Icons.menu, color: Colors.white),
                    ),
                    const Text('Dashboard'),
                    const Icon(Icons.add_circle_outline_outlined,
                        color: Colors.white),
                  ],
                ),
              ),
              Container(
                margin: const EdgeInsets.only(top: 8),
                height: 200,
                child: PageView(
                  scrollDirection: Axis.horizontal,
                  children: [
                    Container(
                      color: Colors.amber,
                      width: 100,
                      margin: const EdgeInsets.symmetric(horizontal: 12),
                    ),
                    Container(
                      color: Colors.black,
                      width: 100,
                      margin: const EdgeInsets.symmetric(horizontal: 12),
                    ),
                    Container(
                      color: Colors.blueGrey,
                      width: 100,
                      margin: const EdgeInsets.symmetric(horizontal: 12),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

这是我在一个页面上的所有代码的版本。正如我所说,这样应用程序就可以按照我想要的方式工作了。但是当我将名为menuWidget和dashboardWidget的方法移动到不同的dart文件中时,名为menuWidget的小部件就不工作了。

import 'package:flutter/material.dart';
import 'package:flutter_slidermenu_and_dashboard/constants/constants.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage>
    with SingleTickerProviderStateMixin {
  bool isMenuOpen = false;
  late AnimationController animationController;
  late Animation<double> scaleAnimation;
  late Animation<Offset> slideTransitionAnimation;

  @override
  void initState() {
    animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
    scaleAnimation = Tween(begin: 1.0, end: 0.7).animate(animationController);
    slideTransitionAnimation =
        Tween(begin: const Offset(-1, 0), end: const Offset(0, 0)).animate(
      CurvedAnimation(parent: animationController, curve: Curves.easeIn),
    );
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Constants.dashboardBackground,
      body: SafeArea(
        child: Stack(
          children: [
            menuWidget(),
            dashboardWidget(),
          ],
        ),
      ),
    );
  }

  menuWidget() {
    return SlideTransition(
      position: slideTransitionAnimation,
      child: Padding(
        padding: const EdgeInsets.only(left: 12.0, right: 240),
        child: Align(
          alignment: Alignment.centerLeft,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              buildMenuItem('Dashboard', Icons.wallet_outlined),
              buildMenuItem('Messages', Icons.message_outlined),
              buildMenuItem('Utility Bills', Icons.document_scanner),
              buildMenuItem('Fon Transfer', Icons.compare_arrows_outlined),
              buildMenuItem('Branches', Icons.home_work_outlined),
            ],
          ),
        ),
      ),
    );
  }

  Widget buildMenuItem(String title, IconData icon) {
    return ListTile(
      selectedTileColor: Colors.white,
      contentPadding: const EdgeInsets.all(0),
      leading: Icon(icon, color: Constants.iconColor),
      title: Text(title, style: Constants.menuTextStyle),
      onTap: () {},
    );
  }

  dashboardWidget() {
    return AnimatedPositioned(
      left: isMenuOpen ? 0.4 * Constants.getScreenWidth(context) : 0,
      top: 0,
      right: isMenuOpen ? -0.3 * Constants.getScreenWidth(context) : 0,
      bottom: 0,
      duration: const Duration(milliseconds: 500),
      child: ScaleTransition(
        scale: scaleAnimation,
        child: Material(
          borderRadius:
              isMenuOpen ? BorderRadius.circular(25) : BorderRadius.zero,
          elevation: isMenuOpen ? 12 : 0,
          color: Constants.dashboardBackground,
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.only(left: 12, top: 8, right: 12),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    GestureDetector(
                      onTap: () {
                        setState(() {
                          if (isMenuOpen) {
                            animationController.reverse();
                          } else {
                            animationController.forward();
                          }
                          isMenuOpen = !isMenuOpen;
                        });
                      },
                      child: const Icon(Icons.menu, color: Colors.white),
                    ),
                    const Text('Dashboard'),
                    const Icon(Icons.add_circle_outline_outlined,
                        color: Colors.white),
                  ],
                ),
              ),
              Container(
                margin: const EdgeInsets.only(top: 8),
                height: 200,
                child: PageView(
                  scrollDirection: Axis.horizontal,
                  children: [
                    Container(
                      color: Colors.amber,
                      width: 100,
                      margin: const EdgeInsets.symmetric(horizontal: 12),
                    ),
                    Container(
                      color: Colors.black,
                      width: 100,
                      margin: const EdgeInsets.symmetric(horizontal: 12),
                    ),
                    Container(
                      color: Colors.blueGrey,
                      width: 100,
                      margin: const EdgeInsets.symmetric(horizontal: 12),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

更新

我在寻找问题的根源方面取得了一些进展。

GestureDetector(
                      onTap: () {
                        setState(() {
                          if (isMenuOpen) {
                            animationController.reverse();
                          } else {
                            animationController.forward();
                          }
                          isMenuOpen = !isMenuOpen;
                        });
                      },
                      child: const Icon(Icons.menu, color: Colors.white),
                    )


正如您所见,“animationController.forward();”命令仅在DashboardWidget类中。当我将其移动到不同的页面时,MenuWidget类中没有动画启动器命令。为了解决此问题,我在MenuWidget类的initState行中启动了另一个“animationController.forward();”命令。

@override
  void initState() {
    animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 500),
    );
    slideTransitionAnimation =
        Tween(begin: const Offset(-1, 0), end: const Offset(0, 0)).animate(
      CurvedAnimation(parent: animationController, curve: Curves.easeIn),
    );
    animationController.forward();
    super.initState();
  }


现在,我可以在屏幕上看到名为MenuWidget的小部件。但它现在保持稳定。我想使用DashboardWidget类中的“ontap”命令使此动画动态。因此,每次“isMenuOpen”值更改时,我的动画将在“forward”和“reverse”命令之间切换。我不知道在哪里编写这些命令(forward、reverse)。

zazmityj

zazmityj1#

SafeArea(
        child: Stack(
          children: [
            const DashboardWidget(isMenuOpen: false),
            MenuWidget(slideTransitionAnimation: slideTransitionAnimation),
           
          ],
        ),
      ),
    )

字符串
你能试着把你的 Jmeter 板控件和菜单控件交换一下吗?因为在堆栈中你可以看到最上面的最后一个项目

相关问题