How to align widget to another widget in Flutter?

5,558

Solution 1

class MyPage extends StatefulWidget {
  @override
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  bool _showIndicator = false;

  void _onButtonClicked() {
    setState(() {
      _showIndicator = !_showIndicator;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Row(
          children: <Widget>[
            const Expanded(child: SizedBox()),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 10.0),
              child: RaisedButton(
                child: Text("I am Too Big"),
                onPressed: _onButtonClicked,
              ),
            ),
            Expanded(
              child: _showIndicator
                  ? const Align(
                      alignment: Alignment.centerLeft,
                      child: CircularProgressIndicator(),
                    )
                  : const SizedBox(),
            ),
          ],
        ),
      ),
    );
  }
}

Here is my explanation:

  • The RaisedButton size is depends on its child. If you add it to Row it will automatically align to left(or start).
  • Expanded widget will fill the remaining space in Flex widget(Row & Column are child classes of Flex). If you add more than one Expanded widgets, it will split equally. So I added two Expanded to both the side of button to make it center.
  • Now We should give child for Expanded Widget.
    • For the first one(left) we don't have anything to display so I added SizedBox.
    • For the second one(right) we need CircularProgressIndicator. so I added it.
  • The Expanded widget will try to make its child to fill the space inside of it. So the CircularProgressIndicator will become Ellipse shaped. We can avoid this by using Align Widget.

Solution 2

Try this:

Updated: 


import 'package:flutter/material.dart';

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


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyAppOne(),
    );
  }
}
class MyAppOne extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyAppOne>{

  bool show = false;
  @override
  Widget build(BuildContext context){
    return Scaffold(
      body:  Stack(
          alignment: Alignment.center,
          children: <Widget>[
            Container(
              alignment: Alignment.center,
              child: RaisedButton(
                onPressed: () {
                  setState(() {
                    show =!show;
                  });
                },
                child: Text('Show'),
              ),
            ),
           Positioned(
             right: MediaQuery.of(context).size.width * .20,
             child:  Container(
              alignment: Alignment.center,
              padding: EdgeInsets.all(10.0),
              child: show ? CircularProgressIndicator() : Container(),
            ),
           )
          ],
        )
      );
  }
}

Share:
5,558
Emil Adz
Author by

Emil Adz

Education: B.S. Computer Science, 2012, HIT. Occupation: Mobile Architect &amp; Co-Founder at Digital Cherry Ever seen a dog chase its tail? Now that's an infinite loop ; ) #SOreadytohelp

Updated on December 16, 2022

Comments

  • Emil Adz
    Emil Adz over 1 year

    I have a RaisedButton widget inside of a Center widget as one of the widgets in a Column of widgets. I want to add a CircularProgressIndicator to the right side of this button and show it when the button is pressed. Yet I want to leave the button centred when the progress bar is shown. In other words I want the button always be in the center and the progress bar aligned to this button.

    I tried to use a Row here but this pushes the button and it becomes not centred any more.

    EDIT1: Looking at the result of the solution provided by @Anil Chauhan (thanks for the answer):

    Like I said before that I tried to use Row like he did, the problem is that in this case the button is not in the centred in the screen and is pushed by the progress bar. And I need it to stay in the middle of it's row.

    enter image description here

    EDIT2: @Anil Chauhan edited answer now works for a specific case in which the button is predetermined size. But if the size of the button is changed based on the language of the text (in apps that have several languages) this solution will not work.

    This is the reason the question I asked is: "How to align widget to another widget". Because if I could that I don't have to worry about the button text size any more.

    What would be the right way to handle this in Flutter?

  • Benjamin
    Benjamin over 4 years
    The same issue occurs though, they don't want the button to be offset because of the progress indicator which with your code it is.
  • Anil Chauhan
    Anil Chauhan over 4 years
    Try now I have updated the answer. For me, the button is always in the center.
  • Emil Adz
    Emil Adz over 4 years
    @AnilChauhan now it looks like it works, could you please explain what exactly are you doing here with the Positioned widget and the MediaQuery.of(context).size.width * .20 line?
  • Anil Chauhan
    Anil Chauhan over 4 years
    @EmilAdz Positioned Widget is used positioning the child of Stack widget to a particular position i.e wherever you want. I.e Positioned from the top, bottom, left, and right, MediaQuery.of(context).size.width * .20 is for getting the 20% width of the screen and used to position the widget from right to 20%.
  • Emil Adz
    Emil Adz over 4 years
    @AnilChauhan but this solution is still not good enough, because I need to handle the case that the "Show" text will be changed to say something longer in another language. In this case the button will be bigger and this solution will not work anymore. Any suggestion to handle this?
  • Emil Adz
    Emil Adz over 4 years
    This works indeed and meets my requirement of changing length text. But could you please explain why this works? How did you figure out that you need to place two Expanded widgets from both sides?
  • Crazy Lazy Cat
    Crazy Lazy Cat over 4 years
    @EmilAdz I added the explanation. Hope I did well on explaining
  • Emil Adz
    Emil Adz over 4 years
    actually you are great at explaining things, this was a great explanation. Thanks.