我什至不确定我为我的问题选择了正确的标题。 我设计了一个主屏幕,这个主屏幕有 2 个不同的小部件。我将这些小部件分成 2 个不同的 dart 文件,以避免编写脏代码。当我将所有代码写在一页上时,我就可以达到我想要的效果。但是当我分开两页时,我遇到了一个无法解决的问题。
这就是我想要的。在我的名为 DashboardWidget 的 dart 文件的第 57 行,有一个
GestureDetector 'ontap' function
。
我使用此按钮更改我的 'isMenuOpen'
变量值。当我按下此按钮并更改我的 isMenuOpen value to true
时,我希望名为 MenuWidget 的小部件来自屏幕左侧。因此,每次触发“ontap”功能时,我的仪表板小部件都会增大/缩小。另外,同时,我的 MenuWidget 将从屏幕上出现/消失。
[This is the image I want]
()
[And this is the screen I see.]
()
我希望我已经很好地解释了自己。英语不是我的母语,我是编程新手。 预先感谢您。
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),
],
),
),
);
}
}
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: () {},
);
}
}
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),
),
],
),
)
],
),
),
),
);
}
}
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),
),
],
),
)
],
),
),
),
);
}
}
SafeArea(
child: Stack(
children: [
const DashboardWidget(isMenuOpen: false),
MenuWidget(slideTransitionAnimation: slideTransitionAnimation),
],
),
),
)
您可以尝试将 Dashboard Widget 替换为 MenuWidget 吗?因为在堆栈中你可以看到顶部的最后一项