skip to Main Content

I am having difficulty figuring how to get a Row, which contains wrapped text, to appear centered in a Column.

The issue seems to be that Flexible (or Expanded for that matter) causes the Text widget to consume the entire remaining horizontal space in the Row. This seems fine for text layout purposes, i.e., determining the needed height for the text. However, it also seems to me that is should be possible that once the text has been laid out, the bounds of its widget can be "shrunk" to require only the minimum width necessary. (Notice the difference of width/space within the red bounding box in the images below.)

Is it possible to achieve this in Flutter? What am I overlooking?

I have searched high and low on SO and haven’t found this specific question.

The closest related might be this but it’s difficult to be certain the way that question was asked. (And it did not receive any answers.)

What I am seeing

undesired appearance

What I would like to see

desired appearance

What I have tried

  • Several permutations of Flexible and Expanded, around the Text, Row, and Column in various combinations
  • Several different values for fit and flex (with Flexible)
  • IntrinsicWidth parent on Column
  • softWrap

Code

(Based on the "Counter" sample from DartPad.)

// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
        decoration: BoxDecoration(
          border: Border.all(color: Colors.blueAccent),
        ),
        width: 300,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text(
                  'u{1F603}',
                  style: TextStyle(
                    fontSize: 24.0,
                  ),
                ),
                Flexible(
                  child: Container(
                    decoration: BoxDecoration(
                      border: Border.all(color: Colors.red),
                    ),                    
                    child: const Text(
                      'Some text that ends up taking_two_lines',
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: 18.0,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

3

Answers


  1. Chosen as BEST ANSWER

    Welp, as I was typing up this question, I discovered the solution, so I may as well write it up for others.

    The trick was to use the textWidthBasis argument of Text and set it to TextWidthBasis.longestLine.


  2. If you has parent widget set yours to center too

    In my case i set My Colum(mainAlignment to center and it is work for me)

    Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.blueAccent),
            ),
            alignment: Alignment.center,
            width: 300,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    const Text(
                      'u{1F603}',
                      style: TextStyle(
                        fontSize: 24.0,
                      ),
                    ),
                    Flexible(
                      child: Container(
                        decoration: BoxDecoration(
                          border: Border.all(color: Colors.red),
                        ),
                        child: const Text(
                          'Some text that ends up taking_two_lines',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 18.0,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
    
    Login or Signup to reply.
  3. Try below code hope its help to you I have try same as your expected design

    Your Widget:

    Scaffold(
      appBar: AppBar(
        actions: [
          const Center(
            child: Padding(
              padding: EdgeInsets.all(8),
              child: Text(
                'Flutter',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 18.0,
                ),
              ),
            ),
          ),
        ],
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              const SizedBox(
                width: 50,
              ),
              const Text(
                'u{1F603}',
                style: TextStyle(
                  fontSize: 24.0,
                ),
              ),
              Expanded(
                child: const Text(
                  'Some text that ends up taking_two_lines',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 18.0,
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    ),
    

    Result Screen-> image

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search