如何通过减去按钮的高度和按钮上方和下方的填充来使用Positioned小部件使子小部件居中?
蓝色方块通常居中对齐。
MediaQuery.of(context).size.height / 2 - 正方形高度
Positioned(
// (MediaQuery.of(context).size.height / 2 - 100.0) -> по центру вообще
top: (MediaQuery.of(context).size.height / 2 - 100.0),
left: _animation.value,
//left: 0.0,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.indigoAccent,
),
),
红色方块通常使用Align小部件居中。注意,它就在蓝色方块的下方。我做它纯粹是为了比较。
对齐:对齐中心,
Align(
alignment: Alignment.center,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.pink,
),
),
我试图将绿色正方形对齐,而不是在中心,而是在白色背景的中心,减去带有黄色背景的容器。将正方形与中心对齐,我添加了缩进 (8.0 + 8.0) 和按钮的高度 (36.0),但它仍然不能确定。绿色方块顶部的白色背景距离比绿色方块底部的白色背景距离略大,我什至用尺子测量了它。
顶部:(MediaQuery.of(context).size.height / 2 - 100.0) + 8.0 + 36.0 + 8.0,
Positioned(
// (MediaQuery.of(context).size.height / 2 - 100.0) -> по центру вообще
// 8.0 -> padding сверху кнопки
// 36.0 -> высота кнопки
// 8.0 -> padding снизу кнопки
top: (MediaQuery.of(context).size.height / 2 - 100.0) + 8.0 + 36.0 + 8.0,
right: 0.0,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green,
),
),
也许我在计算中犯了一个错误,对齐绿色方块?下面是一张照片和完整的代码。谢谢你。
main.dart
import 'dart:ui';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Name App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Name Page'),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
AnimationController _controller;
Tween _tween;
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(seconds: 3),
)..addListener(() {
setState(() {
});
});
_tween = Tween<double>(begin: 0.0, end: window.physicalSize.width / 2 - 100.0);
_animation = _tween.animate(_controller);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
void _funStart() {
setState(() {
_controller.forward();
});
}
void _funStop() {
setState(() {
_controller.stop();
});
}
void _funBack() {
setState(() {
_controller.reverse();
});
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Align(
alignment: Alignment.topLeft,
child: Container(
padding: const EdgeInsets.all(8.0),
color: Colors.orangeAccent,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 1,
child: RaisedButton(
onPressed: () { _funStart(); },
splashColor: Colors.blue.withOpacity(0.5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
child: Text(
'start'.toUpperCase(),
style: TextStyle(
color: Colors.deepPurple,
fontSize: 16.0,
),
),
),
),
SizedBox(width: 8.0,),
Expanded(
flex: 1,
child: RaisedButton(
onPressed: () { _funStop(); },
splashColor: Colors.blue.withOpacity(0.5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
child: Text(
'stop'.toUpperCase(),
style: TextStyle(
color: Colors.deepPurple,
fontSize: 16.0,
),
),
),
),
SizedBox(width: 8.0,),
Expanded(
flex: 1,
child: RaisedButton(
onPressed: () { _funBack(); },
splashColor: Colors.blue.withOpacity(0.5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
child: Text(
'back'.toUpperCase(),
style: TextStyle(
color: Colors.deepPurple,
fontSize: 16.0,
),
),
),
),
],
),
),
),
Positioned(
// (MediaQuery.of(context).size.height / 2 - 100.0) -> по центру вообще
top: (MediaQuery.of(context).size.height / 2 - 100.0),
left: _animation.value,
//left: 0.0,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.indigoAccent,
),
),
Align(
alignment: Alignment.center,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.pink,
),
),
Positioned(
// (MediaQuery.of(context).size.height / 2 - 100.0) -> по центру вообще
// 8.0 -> padding сверху кнопки
// 36.0 -> высота кнопки
// 8.0 -> padding снизу кнопки
top: (MediaQuery.of(context).size.height / 2 - 100.0) + 8.0 + 36.0 + 8.0,
right: 0.0,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green,
),
),
],
);
}
}

是的,蓝色和绿色矩形的计算都是错误的。
MediaQuery.of(context).size- 这与父小部件的大小无关,它在这里不起作用。您需要
LayoutBuilder,例如您问题中的代码:结果:
PS 切勿使用任何硬编码数字,如选项 3 所示。将添加一些新的缩进,一切都会崩溃。例如,
Safe Area。UPD。如果您完全以白色部分为中心,而不是
Stack,那么第一个选项是将带有按钮的线的高度添加到计算中。选项二是将它们拆分为Column:结果: