Flutter 颤振,对齐内的流动不响应对齐规则
我正在尝试使用flifter的Flow小部件,对齐屏幕的右上角,并向左平移。我尝试使用Stack+Positioned,我尝试使用Container+Align。 流量始终保持在左上角。 这是我正在努力的代码Flutter 颤振,对齐内的流动不响应对齐规则,flutter,alignment,flow,Flutter,Alignment,Flow,我正在尝试使用flifter的Flow小部件,对齐屏幕的右上角,并向左平移。我尝试使用Stack+Positioned,我尝试使用Container+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, show
/// 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的颤振代码示例
//本例使用[Flow]小部件创建打开和关闭的菜单
//正如上面所示,它与交互。菜单中按钮的颜色
//更改以指示选择了哪一个。
进口“包装:颤振/材料.省道”;
void main()=>runApp(FlowApp());
类FlowApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
appBar:appBar(
标题:常量文本(“流示例”),
),
正文:FlowMenu(),
),
);
}
}
类FlowMenu扩展StatefulWidget{
@凌驾
_FlowMenuState createState()=>\u FlowMenuState();
}
类_flowmenstate扩展状态
使用SingleTickerProviderStateMixin{
最终双按钮流量计=40;
动画控制器菜单化;
IconData lastTapped=Icons.notifications;
最终列表菜单项=[
我的家,
Icons.new_发布,
图标、通知、,
图标。设置,
图标菜单,
];
void\u updateMenu(Iconda图标){
如果(图标!=Icons.menu)设置状态(()=>lasttapted=icon);
}
@凌驾
void initState(){
super.initState();
menuAnimation=动画控制器(
持续时间:常数持续时间(毫秒:250),
vsync:这个,,
);
}
小部件flowMenuItem(图标数据图标){
//最后一个双按钮参数=MediaQuery.of(context).size.width/menuItems.length;
返回填充(
填充:常量边集。对称(垂直:0.0),
子项:RawMaterialButton(
fillColor:lastTapped==图标?颜色。琥珀色[700]:颜色。蓝色,
splashColor:颜色。琥珀色[100],
形状:CircleBorder(),
约束:BoxConstraints.tight(大小(buttonDiameter,buttonDiameter)),
已按下:(){
_更新(图标);
menuAnimation.status==AnimationStatus.completed
?菜单化。反向()
:menuAnimation.forward();
},
子:图标(
偶像
颜色:颜色,白色,
尺寸:钮扣直径-10,
),
),
);
}
@凌驾
小部件构建(构建上下文){
返回容器(
宽度:MediaQuery.of(context).size.width,
装饰:盒子装饰(颜色:颜色。绿色),
子对象:对齐(
对齐:alignment.topRight,
子:容器(
约束:BoxConstraints.tight(
尺寸((buttonDiameter)*menuItems.length,buttonDiameter+5)),
装饰:盒子装饰(颜色:Colors.red),
子项:Align(//为什么此Align不起作用?
对齐:alignment.topRight,
孩子:流(
代表:FlowMenuDelegate(菜单化:菜单化),
儿童:menuItems
.map((Iconda图标)=>flowMenuItem(图标))
.toList(),
),
),
),
),
);
}
}
类FlowMenuDelegate扩展了FlowDelegate{
FlowMenuDelegate({this.menuAnimation}):超级(重新绘制:menuAnimation);
最终动画菜单;
@凌驾
bool应重新绘制(FlowMenuDelegate oldDelegate){
return menuAnimation!=oldDelegate.menuAnimation;
}
@凌驾
void paintChildren(FlowPaintingContext上下文){
双dx=0.0;
for(int i=0;i
生成的屏幕是
你能帮我把流量调整到右上角吗?非常感谢您的阅读或回复
它说我不允许创建标签。下面是未来的列表:Flow小部件、Align小部件、Flatter
编辑
我正在努力实现的目标:
问题似乎在于包装RawMaterialButton小部件的填充小部件。 所以我用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,
),
);
}
}
}
///Flow的颤振代码示例
//本例使用[Flow]小部件创建打开和关闭的菜单
//正如上面所示,它与交互。菜单中按钮的颜色
//更改以指示选择了哪一个。
进口“包装:颤振/材料.省道”;
void main()=>runApp(FlowApp());
类FlowApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
家:脚手架(
appBar:appBar(
标题:常量文本(“流示例”),
),
正文:FlowMenu(),
),
);
}
}
类FlowMenu扩展StatefulWidget{
@凌驾
_FlowMenuState createState()=>\u FlowMenuState();
}
类_flowmenstate扩展状态
使用SingleTickerProviderStateMixin{
最终双按钮流量计=40;
动画控制器菜单化;
IconData lastTapped=Icons.notifications;
最终列表菜单项=[
我的家,
Icons.new_发布,
图标、通知、,
图标。设置,
图标菜单,
];
//@override Size getSize(BoxConstraints)=>Size(100100);
//@override Size getSize(BoxConstraints constraints)=>constraints.max/2;
void\u updateMenu(Iconda图标){
如果(图标!=Icons.menu)设置状态(()=>lasttapted=icon);
}
@凌驾
void initState(){
super.initState();
menuAnimation=动画控制器(
持续时间:常数持续时间(毫秒:250),
vsync:这个,,
);
}
小部件流