Reputation: 14296
I want to place a CircularProgressIndicator
inside a RaisedButton
, but when I do it, the CircularProgressIndicator
doesn't fit the button and sticks out of it.
I want to shrink the CircularProgressIndicator
, so that it fits inside the RaisedButton
, I know I can do it using a SizedBox
but I want it to be automatic, not that I give it the size that I want. I tried FittedBox
but all its options make no difference at all.
this is my button's code:
RaisedButton(
onPressed: () => print('hi'),
shape: StadiumBorder(),
color: Theme.of(context).primaryColor,
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 12, top: 6, bottom: 6),
child: CircularProgressIndicator(
backgroundColor: Colors.white,
strokeWidth: 2,
),
),
Text('Loading'),
],
),
),
And this is how it looks like:
When I Add Padding
it grows the button:
Are there any ways to achieve this automatically?
EDIT:
Just to make it clear, the end effect that I want is this:
Before and after the user presses the button:
I want the height to stay the same, automatically, without magic values inside a SizedBox
.
Upvotes: 12
Views: 6825
Reputation: 2895
This is totally possible. You wrap the CircularProgressIndicator
inside a SizedBox
to constrain it to that size. Also using MainAxisSize.Min
in the Row
prevents the button from trying to expand to infinite size.
ElevatedButton(
onPressed: (){},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue)),
child: isLoading
? Padding(
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text("Loading"),
SizedBox(
width: 5,
),
SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.white),
backgroundColor: Colors.blue,
strokeWidth: 3,
),
)
],
),
)
: Text("Not Loading"))
Upvotes: 8
Reputation: 14296
Looking at the CircularProgressIndicator
source code, I can find there's a hardcoded minimum size of 36.0 height/width, so there's no way of getting smaller than that automatically.
Upvotes: 3
Reputation: 3408
you can use mainAxisAlignment: MainAxisAlignment.spaceBetween
to make space between your widgets in Row
.
You can wrap your Row
widget to a Padding
widget to make padding for whole content in your button as well.
Padding(
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CircularProgressIndicator(
backgroundColor: Colors.white,
strokeWidth: 2,
),
Text('Loading'),
],
),
)
Upvotes: -1
Reputation: 11679
I re-created your case and was able to see the CircularProgressIndicator
properly inside the RaisedButton
maintaining it's size.
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Progress Button',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Progress Button'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () => print('hi'),
shape: StadiumBorder(),
color: Theme.of(context).primaryColor,
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 12, top: 6, bottom: 6),
child: CircularProgressIndicator(
backgroundColor: Colors.white,
strokeWidth: 2,
),
),
Text('Loading'),
],
),
),
],
),
),
);
}
}
Output (both platforms):
Upvotes: 1