flutter - Flutter, Flow inside Align 不响应对齐规则
问题描述
我正在尝试使用 Flutter 的 Flow 小部件,与屏幕右上角对齐,并向左平移。我尝试使用 Stack + Positioned,我尝试使用 Container + Align。Flow 总是停留在左上角。这是我正在努力的代码;
/// Flutter code sample for Flow
// This example uses the [Flow] widget to create a menu that opens and closes
// as it is interacted with, shown above. The color of the button in the menu
// changes to indicate which one has been selected.
import 'package:flutter/material.dart';
void main() => runApp(FlowApp());
class FlowApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flow Example'),
),
body: FlowMenu(),
),
);
}
}
class FlowMenu extends StatefulWidget {
@override
_FlowMenuState createState() => _FlowMenuState();
}
class _FlowMenuState extends State<FlowMenu>
with SingleTickerProviderStateMixin {
final double buttonDiameter = 40;
AnimationController menuAnimation;
IconData lastTapped = Icons.notifications;
final List<IconData> menuItems = <IconData>[
Icons.home,
Icons.new_releases,
Icons.notifications,
Icons.settings,
Icons.menu,
];
void _updateMenu(IconData icon) {
if (icon != Icons.menu) setState(() => lastTapped = icon);
}
@override
void initState() {
super.initState();
menuAnimation = AnimationController(
duration: const Duration(milliseconds: 250),
vsync: this,
);
}
Widget flowMenuItem(IconData icon) {
// final double buttonDiameter = MediaQuery.of(context).size.width / menuItems.length;
return Padding(
padding: const EdgeInsets.symmetric(vertical: 0.0),
child: RawMaterialButton(
fillColor: lastTapped == icon ? Colors.amber[700] : Colors.blue,
splashColor: Colors.amber[100],
shape: CircleBorder(),
constraints: BoxConstraints.tight(Size(buttonDiameter, buttonDiameter)),
onPressed: () {
_updateMenu(icon);
menuAnimation.status == AnimationStatus.completed
? menuAnimation.reverse()
: menuAnimation.forward();
},
child: Icon(
icon,
color: Colors.white,
size: buttonDiameter - 10,
),
),
);
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Colors.green),
child: Align(
alignment: Alignment.topRight,
child: Container(
constraints: BoxConstraints.tight(
Size((buttonDiameter) * menuItems.length, buttonDiameter+5)),
decoration: BoxDecoration(color: Colors.red),
child: Align( //why this align does not work?
alignment: Alignment.topRight,
child: Flow(
delegate: FlowMenuDelegate(menuAnimation: menuAnimation),
children: menuItems
.map<Widget>((IconData icon) => flowMenuItem(icon))
.toList(),
),
),
),
),
);
}
}
class FlowMenuDelegate extends FlowDelegate {
FlowMenuDelegate({this.menuAnimation}) : super(repaint: menuAnimation);
final Animation<double> menuAnimation;
@override
bool shouldRepaint(FlowMenuDelegate oldDelegate) {
return menuAnimation != oldDelegate.menuAnimation;
}
@override
void paintChildren(FlowPaintingContext context) {
double dx = 0.0;
for (int i = 0; i < context.childCount; ++i) {
dx = context.getChildSize(i).width * i;
context.paintChild(
i,
transform: Matrix4.translationValues(
-dx * menuAnimation.value,
0,
0,
),
);
}
}
}
结果屏幕是;
你能帮我把流量调整到右上角吗?非常感谢您阅读或回复。
附言。它说我不允许创建标签。所以这里有一个未来的列表:Flow Widget、Align Widget、Flutter
编辑
我想要达到的目标:
- 和 2. GIFs 被实现。最后一个显示了我如何未能将其与右侧对齐。
解决方案
似乎问题在于包装 RawMaterialButton 小部件的 Padding 小部件。所以我用Align替换了它,并且还稍微调整了你的动画工作代码如下
/// Flutter code sample for Flow
// This example uses the [Flow] widget to create a menu that opens and closes
// as it is interacted with, shown above. The color of the button in the menu
// changes to indicate which one has been selected.
import 'package:flutter/material.dart';
void main() => runApp(FlowApp());
class FlowApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Flow Example'),
),
body: FlowMenu(),
),
);
}
}
class FlowMenu extends StatefulWidget {
@override
_FlowMenuState createState() => _FlowMenuState();
}
class _FlowMenuState extends State<FlowMenu>
with SingleTickerProviderStateMixin {
final double buttonDiameter = 40;
AnimationController menuAnimation;
IconData lastTapped = Icons.notifications;
final List<IconData> menuItems = <IconData>[
Icons.home,
Icons.new_releases,
Icons.notifications,
Icons.settings,
Icons.menu,
];
// @override Size getSize(BoxConstraints constraints) => Size(100, 100);
// @override Size getSize(BoxConstraints constraints) => constraints.biggest / 2;
void _updateMenu(IconData icon) {
if (icon != Icons.menu) setState(() => lastTapped = icon);
}
@override
void initState() {
super.initState();
menuAnimation = AnimationController(
duration: const Duration(milliseconds: 250),
vsync: this,
);
}
Widget flowMenuItem(IconData icon) {
// final double buttonDiameter = MediaQuery.of(context).size.width / menuItems.length;
return Container(
decoration: BoxDecoration(
color: Colors.white
),
child: Align(
// padding: const EdgeInsets.symmetric(vertical: 0.0),
alignment: Alignment.topRight,
child: RawMaterialButton(
fillColor: lastTapped == icon ? Colors.amber[700] : Colors.blue,
splashColor: Colors.amber[100],
shape: CircleBorder(),
constraints: BoxConstraints.tight(Size(buttonDiameter, buttonDiameter)),
onPressed: () {
_updateMenu(icon);
menuAnimation.status == AnimationStatus.completed
? menuAnimation.reverse()
: menuAnimation.forward();
},
child: Icon(
icon,
color: Colors.white,
size: buttonDiameter - 10,
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Colors.green),
child: Align(
alignment: Alignment.topRight,
child: Container(
constraints: BoxConstraints.tight(
Size(buttonDiameter * (menuItems.length+1), buttonDiameter+5)),
decoration: BoxDecoration(color: Colors.red),
child: Align(
alignment: Alignment.topRight,
child: Flow(
delegate: FlowMenuDelegate(menuAnimation: menuAnimation),
children: menuItems
.map<Widget>((IconData icon) => flowMenuItem(icon))
.toList(),
),
),
),
),
);
}
}
class FlowMenuDelegate extends FlowDelegate {
FlowMenuDelegate({this.menuAnimation}) : super(repaint: menuAnimation);
final Animation<double> menuAnimation;
@override
bool shouldRepaint(FlowMenuDelegate oldDelegate) {
return menuAnimation != oldDelegate.menuAnimation;
}
// @override Size getSize(BoxConstraints constraints) => constraints.biggest / 2;
@override
void paintChildren(FlowPaintingContext context) {
double dx = 0.0;
for (int i = 0; i < context.childCount; ++i) {
dx = 40.0 * i;
context.paintChild(
i,
transform: Matrix4.translationValues(
-dx * menuAnimation.value,
0,
0,
),
);
}
}
}
推荐阅读
- python - 将 Sagemaker 清单注释转换为 Pascal VOC XML/CSV
- transactional-replication - 创建启用了 CDC 的 SQL 托管实例的事务复制
- task-parallel-library - TPL Dataflow ,完成一个 Block ,重新创建一个 BLock
- javascript - 在 React 应用中 manifest.json 有什么用?
- javascript - 我的联系表格 7 表格未将输入值发送到输出电子邮件
- javascript - React setState 不适用于 if 语句
- postgresql - 混合 SRID 触发阻止 qgis 提交更改
- java - LS 在 LSSerializer 中代表什么?在 org.w3c.dom.ls.LSSerializer 中说
- reactjs - 反应详尽的deps规则,从自定义钩子中标记缺少的依赖项
- regex - 带有-replace正则表达式的Powershell脚本不起作用