How to align widget to another widget in Flutter?
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 toRow
it will automatically align to left(or start). Expanded
widget will fill the remaining space inFlex
widget(Row
&Column
are child classes ofFlex
). If you add more than oneExpanded
widgets, it will split equally. So I added twoExpanded
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.
- For the first one(left) we don't have anything to display so I added
- The
Expanded
widget will try to make its child to fill the space inside of it. So theCircularProgressIndicator
will become Ellipse shaped. We can avoid this by usingAlign
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(),
),
)
],
)
);
}
}
Emil Adz
Education: B.S. Computer Science, 2012, HIT. Occupation: Mobile Architect & Co-Founder at Digital Cherry Ever seen a dog chase its tail? Now that's an infinite loop ; ) #SOreadytohelp
Updated on December 16, 2022Comments
-
Emil Adz over 1 year
I have a
RaisedButton
widget inside of aCenter
widget as one of the widgets in aColumn
of widgets. I want to add aCircularProgressIndicator
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.
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 over 4 yearsThe 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 over 4 yearsTry now I have updated the answer. For me, the button is always in the center.
-
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 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 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 over 4 yearsThis 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 over 4 years@EmilAdz I added the explanation. Hope I did well on explaining
-
Emil Adz over 4 yearsactually you are great at explaining things, this was a great explanation. Thanks.