Terry T
Terry T

Reputation: 119

Modal with centered title and right aligned close/X button

I recently picked up Flutter and Dart and am attempting to create an app that has a modal with three parts: a header, actual content, and a footer.

For the header I am looking to add a title (Text) center aligned and a close button right aligned.

I have the following code:

    Column(
        children: [
          Row(
            children: [
              Expanded(
                child: Text(
                  "Filters",
                  style: const TextStyle(
                    fontSize: 25,
                    fontWeight: FontWeight.bold,
                  ),
                  textAlign: TextAlign.center,
                ),
              ),
              IconButton(
                icon: const Icon(Icons.close),
                onPressed: () {
                  Navigator.pop(context);
                },
              ),
            ],
          ),
        ],
      ),
    )

Visually, this looks like so:

Result

At a glance this looks fine but if you stare at it for a bit it doesn't. The "Filters" title isn't actually centered because (I assume) of the width of the X-button. I am struggling to figure out how to deal with this.

What is the proper way to solve this?

Upvotes: 1

Views: 1027

Answers (2)

maniodev
maniodev

Reputation: 1

You can use a Stack and avoid hiding a button.

SizedBox(
  width: double.infinity,
  child: Stack(
    alignment: Alignment.center,
    children: [
      Positioned(
        right: 0,
        child: IconButton(
          icon: const Icon(Icons.close),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
      Container(
        alignment: Alignment.center,
        child: const Text(
          "Filters",
          style: TextStyle(
            fontSize: 25,
            fontWeight: FontWeight.bold,
          ),
          textAlign: TextAlign.center,
        ),
      )
    ],
  ),
),

Upvotes: 0

eamirho3ein
eamirho3ein

Reputation: 17910

You can add empty SizedBox with width as much as IconButton takes, try this:

Row(
    children: [
      SizedBox(
        width: width: 24 +
                8 +
                8, // the default size of icon + two default horizontal padding for IconButton
      ),
      Expanded(
        child: Text(
          "Filters",
          style: const TextStyle(
            fontSize: 25,
            fontWeight: FontWeight.bold,
          ),
          textAlign: TextAlign.center,
        ),
      ),
      IconButton(
        icon: const Icon(Icons.close),
        onPressed: () {
          Navigator.pop(context);
        },
      ),
    ],
  ),

or you can add on other IconButton with opacity 0 to hide the button and make title center, like this:

Row(
    children: [
      Opacity(
            opacity: 0,
            child: IconButton(
              icon: const Icon(Icons.close),
              onPressed: () {},
         ),
      ),
      Expanded(
        child: Text(
          "Filters",
          style: const TextStyle(
            fontSize: 25,
            fontWeight: FontWeight.bold,
          ),
          textAlign: TextAlign.center,
        ),
      ),
      IconButton(
        icon: const Icon(Icons.close),
        onPressed: () {
          Navigator.pop(context);
        },
      ),
    ],
  ),
          

enter image description here

Upvotes: 2

Related Questions