Flutter: Ensure Text is perfectly centred when there are more items on one side?

In a Row, how can I ensure that the Text with "Hello" in it is perfectly centered and not a bit to the left when the right most inner Row widget has more items than the left most inner Row widget?

Notice in the screenshot that the "Hello" is slight to the left.

I tried using a Stack but that seems to not work well if the text is longer than the available space as it causes the text to then overlap the side-colored widgets.

I am using the following code:

Center(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: [
      Row(
        children: [
          Container(
            width: 45,
            height: 45,
            color: Colors.red,
          ),
        ],
      ),
      Text(
        "Hello",
        textAlign: TextAlign.center,
      ),
      Row(
        children: [
          Container(
            width: 45,
            height: 45,
            color: Colors.purple,
          ),
          Container(
            width: 45,
            height: 45,
            color: Colors.green,
          ),
        ],
      )
    ],
  ),
)

Upvotes: 1

Views: 91

Answers (4)

OMi Shah
OMi Shah

Reputation: 6186

Wrap both the Rows and the Text widget, children of the first Row widget, with the Expanded widget and set the mainAxisAlignmnet of the right Row to MainAxisAlignment.end.

Center(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: [
      Expanded(
        child: Row(
          children: [
            Container(
              width: 45,
              height: 45,
              color: Colors.red,
            ),
          ],
        ),
      ),
      const Expanded(
        child: Text(
          "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
          textAlign: TextAlign.center,
        ),
      ),
      Expanded(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Container(
              width: 45,
              height: 45,
              color: Colors.purple,
            ),
            Container(
              width: 45,
              height: 45,
              color: Colors.green,
            ),
          ],
        ),
      ),
    ],
  ),
)

Output:


If either of the sides will have more widget's then you can use the Wrap widget instead of the inner Row widgets which will wrap the overflowing items to the next line.

Center(
  child: Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: [
      Expanded(
        child: Wrap(
          children: [
            Container(
              width: 45,
              height: 45,
              color: Colors.red,
            ),
          ],
        ),
      ),
      const Expanded(
        child: Text(
          "Ex qui tempor dolore ex aliquip ex consectetur proident excepteur eu. Velit non sint laboris sit. Ut minim proident irure non ullamco deserunt qui. Quis eu tempor consequat amet irure consequat irure elit. Culpa id in laboris reprehenderit veniam voluptate tempor minim eu reprehenderit sit.",
          textAlign: TextAlign.center,
        ),
      ),
      Expanded(
        child: Wrap(
          alignment: WrapAlignment.end,
          children: [
            Container(
              width: 45,
              height: 45,
              color: Colors.purple,
            ),
            Container(
              width: 45,
              height: 45,
              color: Colors.green,
            ),
            Container(
              width: 45,
              height: 45,
              color: Colors.orange,
            ),
            Container(
              width: 45,
              height: 45,
              color: Colors.red,
            ),
          ],
        ),
      ),
    ],
  ),
)

Output:

Upvotes: 2

Gwhyyy
Gwhyyy

Reputation: 9206

I wrote a specific code that might suit your case, here is the result first:

enter image description here

basically, the idea of it is to get the width of both rows in corners, then search for the max within between them, then set the Text() width to the screen width size, minus that max multiplied by two, this ensures that it will be exactly in the center and not overlapping the widgets:

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:get/get.dart';

import 'controllers/controller.dart';
import 'dart:math' as math;

double firstRowWidth = 0;
double secondRowWidth = 0;
double max = 0;

class TestPage extends StatefulWidget {
  TestPage({super.key});

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  final testController = Get.put(TestController());

  @override
  void initState() {
    SchedulerBinding.instance.addPersistentFrameCallback((timeStamp) {
      SchedulerBinding.instance.addPostFrameCallback((_) {
        setState(() {
          max = math.max(secondRowWidth, firstRowWidth);
        });
      });
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Stack(
          alignment: Alignment.center,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                row2(),
                row1(),
              ],
            ),
            Positioned(
              width: MediaQuery.of(context).size.width - (max * 2),
              child: Text(
                "Hello" * 20,
                textAlign: TextAlign.center,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class row1 extends StatelessWidget {
  const row1({super.key});

  @override
  Widget build(BuildContext context) {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      firstRowWidth = context.size!.width;
    });
    return Row(
      children: [
        Container(
          width: 45,
          height: 45,
          color: Colors.purple,
        ),
        Container(
          width: 45,
          height: 45,
          color: Colors.green,
        ),
      ],
    );
  }
}

class row2 extends StatelessWidget {
  const row2({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      secondRowWidth = context.size!.width;
    });
    return Row(
      children: [
        Container(
          width: 45,
          height: 45,
          color: Colors.red,
        ),
      ],
    );
  }
}

Hope this helps !

Upvotes: 2

eamirho3ein
eamirho3ein

Reputation: 17940

If you don't have other widget width you can use stack widget:

Stack(
    alignment: Alignment.center,
    children: [
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Row(
            children: [
              Container(
                width: 45,
                height: 45,
                color: Colors.red,
              ),
            ],
          ),
          Row(
            children: [
              Container(
                width: 45,
                height: 45,
                color: Colors.purple,
              ),
              Container(
                width: 45,
                height: 45,
                color: Colors.green,
              ),
            ],
          )
        ],
      ),
      Text(
        "Hello",
        textAlign: TextAlign.center,
      ),
    ],
  ),

If your text is long, I recommend @OMiShah answer and wrap your text with expanded widget.

enter image description here

Upvotes: 1

Gwhyyy
Gwhyyy

Reputation: 9206

try the following, I made it with the Stack widget: enter image description here

Center(
  child: Stack(
    alignment: Alignment.center,
    children: [
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Row(
            children: [
              Container(
                width: 45,
                height: 45,
                color: Colors.red,
              ),
            ],
          ),
          Row(
            children: [
              Container(
                width: 45,
                height: 45,
                color: Colors.purple,
              ),
              Container(
                width: 45,
                height: 45,
                color: Colors.green,
              ),
            ],
          )
        ],
      ),
      Text(
        "Hello",
        textAlign: TextAlign.center,
      ),
    ],
  ),
);

Upvotes: 0

Related Questions