如何在父项目的中心下方的项目中制作Flutter视图?

时间:2019-04-25 07:16:27

标签: flutter flutter-layout

我正在尝试在Flutter中创建一个看起来像这样的视图。但是,在Flutter中没有相对位置的概念。 这是我想要实现的。

enter image description here

红色矩形位于屏幕中央,绿色矩形位于红色矩形的正下方。

在Android中,我可以使用“约束布局”轻松完成此操作,

<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中提出一个好的解决方案吗?

4 个答案:

答案 0 :(得分:1)

@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,
            ),
          ],
        )),
      ),
    );
  }
}

enter image description here

希望有帮助!

答案 1 :(得分:0)

Flutter Positioned类是您的朋友。

位置小部件必须是堆栈的后代,并且从位置小部件到其封闭堆栈的路径必须仅包含StatelessWidgets或StatefulWidgets(不能包含其他类型的小部件,例如RenderObjectWidgets)。 / p>

答案 2 :(得分:0)

尝试

enter image description here

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"),
      )
    ],
  ),
)

您可以删除height / width参数,以便根据其中的内容进行调整。

答案 3 :(得分:0)

执行此操作的一种方法是:如果将一列居中并给其水平填充对称的水平填充,则将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,
                  ),
                ),
              ],
            ),
          ),
        ),
      )