我试图在Flutter中创建一个看起来像这样的视图。但是,Flutter中没有相对位置的概念。这就是我想要实现的目标。
红色矩形位于屏幕中央,绿色矩形位于红色矩形正下方。
在Android中,我可以使用Constraint Layout轻松完成此操作,
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/view"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#ff0000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#00ff00"
app:layout_constraintEnd_toEndOf="@+id/view"
app:layout_constraintTop_toBottomOf="@+id/view" />
</android.support.constraint.ConstraintLayout>
任何人都可以在Flutter中建议一个好的解决方案吗?
@cynw
由于两个小部件都是文本,并且在渲染之前您不知道它们的高度,我们必须计算高度并重新渲染(重建)小部件。
在下面的方法中,我在大文本上方添加一个SizedBox以将其向下推,以确保它在中心布局。这种方法的坏处是我们必须重新构建小部件。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
SystemChrome.setEnabledSystemUIOverlays([]);
runApp(MyStatefulApp());
}
class MyStatefulApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MyStatefulAppState();
}
}
class _MyStatefulAppState extends State<MyStatefulApp> {
GlobalKey _smallTextKey = GlobalKey();
double _bigTextMarginTop = 0;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback(_afterLayout);
}
_afterLayout(_) {
_getSizes();
}
_getSizes() {
final RenderBox renderBoxRed =
_smallTextKey.currentContext.findRenderObject();
final smallTextSize = renderBoxRed.size;
setState(() {
_bigTextMarginTop = smallTextSize.height;
});
}
@override
Widget build(BuildContext context) {
print('Margin = $_bigTextMarginTop');
return MaterialApp(
title: 'Flutter',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
SizedBox(
height: _bigTextMarginTop,
),
Text(
'Hello',
style: TextStyle(
fontSize: 120,
backgroundColor: Colors.red,
color: Colors.white),
),
Text(
'Hello',
style: TextStyle(
fontSize: 40,
backgroundColor: Colors.green,
color: Colors.white),
key: _smallTextKey,
),
],
)),
),
);
}
}
希望它有所帮助!
颤抖的Positioned班是你的朋友。
定位窗口小部件必须是Stack的后代,并且从定位窗口小部件到其封闭堆栈的路径必须只包含StatelessWidgets或StatefulWidgets(不是其他类型的小部件,如RenderObjectWidgets)。
试试这个
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width * 0.7,
height: MediaQuery.of(context).size.width * 0.7,
color: Colors.red,
child: Text("Some text"),
),
Container(
color: Colors.green,
child: Text("text here"),
)
],
),
)
您可以删除高度/宽度参数,以便根据其中的内容进行调整。
这样做的一种方法是:如果您将列居中并给它水平填充对称水平填充,则在彼此之下构建2个Container,并定位它们。
home: Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
color: Colors.black,
height: 300,
width: 300,
),
Align(
alignment: Alignment.bottomRight,
child: Container(
color: Colors.red,
height: 30,
width: 30,
),
),
],
),
),
),
)