I am trying to create a view that looks like this in Flutter. But, there is no concept of relative position in Flutter. Here is what I want to achieve.
The red rectangle is in the center of the screen, and the green rectangle is right below the red one.
In Android, I can easily do this with 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>
Can anyone suggest a good solution to this in Flutter?
@cynw
Since both widgets are Texts and you don't know their heights until they are rendered, we have to calculate the height and re-render (rebuild) the widget.
In my approach below, I add a SizedBox above the big Text to push it down to make sure it is laid out at the center. The bad thing in this approach is we have to re-build the widget.
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,
),
],
)),
),
);
}
}
Hope it help!