Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Place a CircularProgressIndicator inside RaisedButton mantaining size

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:

enter image description here

When I Add Padding it grows the button:

enter image description here

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:

enter image description here enter image description here

I want the height to stay the same, automatically, without magic values inside a SizedBox.

like image 536
Michel Feinstein Avatar asked Aug 07 '19 02:08

Michel Feinstein


3 Answers

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.

like image 119
Michel Feinstein Avatar answered Sep 28 '22 05:09

Michel Feinstein


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"))

This gives you the following Blue button with circular progress indicator

like image 22
James Avatar answered Sep 28 '22 04:09

James


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):

enter image description here

enter image description here

like image 28
Darshan Avatar answered Sep 28 '22 04:09

Darshan