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

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

我什至不确定我为我的问题选择了正确的标题。 我设计了一个主屏幕,这个主屏幕有 2 个不同的小部件。我将这些小部件分成 2 个不同的 dart 文件,以避免编写脏代码。当我将所有代码写在一页上时,我就可以达到我想要的效果。但是当我分开两页时,我遇到了一个无法解决的问题。

这就是我想要的。在我的名为 DashboardWidget 的 dart 文件的第 57 行,有一个

GestureDetector 'ontap' function
。 我使用此按钮更改我的
'isMenuOpen'
变量值。当我按下此按钮并更改我的
isMenuOpen value to true
时,我希望名为 MenuWidget 的小部件来自屏幕左侧。因此,每次触发“ontap”功能时,我的仪表板小部件都会增大/缩小。另外,同时,我的 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)

我希望我已经很好地解释了自己。英语不是我的母语,我是编程新手。 预先感谢您。

menu_dashboard_page.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 MenuAndDashboardPage extends StatefulWidget {
  const MenuAndDashboardPage({super.key});

  @override
  State<MenuAndDashboardPage> createState() => _MenuAndDashboardPageState();
}

class _MenuAndDashboardPageState extends State<MenuAndDashboardPage>
    with SingleTickerProviderStateMixin {
  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(slideTransitionAnimation: slideTransitionAnimation),
            const DashboardWidget(isMenuOpen: false),
          ],
        ),
      ),
    );
  }
}

menu_widget.dart

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

class MenuWidget extends StatefulWidget {
  final Animation<Offset> slideTransitionAnimation;
  const MenuWidget({super.key, required this.slideTransitionAnimation});

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

class _MenuWidgetState extends State<MenuWidget> {
  @override
  Widget build(BuildContext context) {
    return SlideTransition(
      position: widget.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: () {},
    );
  }
}

dashboard_widget.dart

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

class DashboardWidget extends StatefulWidget {
  final bool isMenuOpen;
  const DashboardWidget({super.key, required this.isMenuOpen});

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

class _DashboardWidgetState extends State<DashboardWidget>
    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);

    super.initState();
  }

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

  @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 MenuAndDashboardPage extends StatefulWidget {
  const MenuAndDashboardPage({super.key});

  @override
  State<MenuAndDashboardPage> createState() => _MenuAndDashboardPageState();
}

class _MenuAndDashboardPageState extends State<MenuAndDashboardPage>
    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),
                    ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

android flutter dart visual-studio-code flutter-animation
1个回答
0
投票
SafeArea(
        child: Stack(
          children: [
            const DashboardWidget(isMenuOpen: false),
            MenuWidget(slideTransitionAnimation: slideTransitionAnimation),
           
          ],
        ),
      ),
    )

您可以尝试将 Dashboard Widget 替换为 MenuWidget 吗?因为在堆栈中你可以看到顶部的最后一项

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