1

In my layout I have two Widgets in a row, a text and a button.

How can I achieve something like below, where only the Text is centered, and the icon is simply next to it?

---------------------------
           Text *          
---------------------------

Using Row would center all the contents and would output something like

---------------------------
          Text *           
---------------------------

Tried: Row(children:[widget1, widget2], mainAxisAlignment: MainAxisAlignment.center); But this centers both items, causing the text to look off-centered.

Mark
  • 11
  • 2

2 Answers2

1

You can use CompositedTransformTarget and CompositedTransformFollower as mentioned on comment section by pskink.

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

  @override
  Widget build(BuildContext context) {
    final LayerLink _layerLink = LayerLink();

    return Scaffold(
      body: Column(
        children: [
          Stack(
            children: [
              Align(
                child: CompositedTransformTarget(
                  link: _layerLink,
                  child: Container(
                    color: Colors.red,
                    width: 100,
                    height: 60,
                    alignment: Alignment.center,
                    child: Text("btn"),
                  ),
                ),
              ),
              CompositedTransformFollower(
                link: _layerLink,
                targetAnchor: Alignment.centerRight,
                followerAnchor: Alignment.centerLeft,
                child: Container(
                  color: Colors.cyanAccent,
                  width: 12,
                  height: 12,
                  alignment: Alignment.center,
                  child: Text("*"),
                ),
              ),
            ],
          )
        ],
      ),
    );
  }
}

There are few tricks I can think of,

  • You can use Stack widget with Position.

  • including another widget on right by applying opacity(invisible) on current snippet.

  • using transform will be handle if you know the width of the widget.

Transform.translate(
  offset: Offset(20 / 2, 0), //20 is the * box size
  child: Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Container(
        color: Colors.red,
        width: 100,
        height: 60,
        alignment: Alignment.center,
        child: Text("btn"),
      ),
      Container(
        color: Colors.green,
        width: 20,
        height: 20,
        child: Center(child: Text("*")),
      ),
    ],
  ),
),

enter image description here

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
  • 1
    no tricks needed: use `CompositedTransformTarget` and `CompositedTransformFollower` - both inside a `Stack` or similar multi child container (also `CustomMultiChildLayout` can be used but it requires additional delegate class to be implemented) – pskink Jan 27 '23 at 08:07
  • So many widgets thanks but one more thing, is it possible to set the `CompositedTransformFollower` centerRight without setting offset. – Md. Yeasin Sheikh Jan 27 '23 at 18:22
  • My text is dynamic, it can even go over two lines meaning that I'm wrapping it in a Flexible(). Is there a way to achieve it without transform and stack, but using row properties? – Mark Jan 27 '23 at 18:41
  • 1
    see `followerAnchor` / `targetAnchor` – pskink Jan 27 '23 at 18:49
  • 1
    one note: `followerAnchor` should be center left and you don't need any offset: basically target's center right point will be the same as follower's center left point - try to experiment with different follower anchors and it will clear any doubts – pskink Jan 28 '23 at 18:37
-1

Place text and second widget inside row then put the row inside container with alignment center and use SizedBox for spacing between widget instead of Padding Widget.

Container(
      color: Colors.green,
      alignment: Alignment.center,
      height: 100,
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: const [
          Text("Text"),
          SizedBox(width: 10),
          Text("*"),
        ],
      ),
    );

enter image description here

Fuad All
  • 871
  • 11
  • 13
  • Unfortunatly it doesn't solve OP's issue, centered widget is not really centered in your exemple (it get's slightly to the left) – Jeremy Luisetti May 15 '23 at 20:11