pomoworko.com
pomoworko.com

Reputation: 1016

How to toggle between play and pause icons in Flutter button?

I have a FloatingActionButton that changes its icon to a pause icon when clicked. How can I toggle the icon back to the play icon when the button is clicked again?

Code:

Row(
  mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      AnimatedBuilder(
          animation: controller,
          builder: (context, child) {
            return FloatingActionButton.extended(
                onPressed: () {
                  if (controller.isAnimating)
                    controller.stop();
                  else {
                    controller.reverse(
                        from: controller.value == 0.0
                            ? 1.0
                            : controller.value);
                  }
            },
                icon: Icon(
                  controller.isAnimating
                    ? Icons.pause
                    : Icons.play_arrow  ,
                  color: Color(0xffF2F2F2),),

                label: Text(
                  controller.isAnimating ? "Pause" : "Play",));

          }),
      SizedBox(width: 20,),
      AnimatedBuilder(
          animation: controller,
          builder: (context, child) {
            return FloatingActionButton.extended(
              onPressed: () {
                if (controller.isAnimating)
                  controller.reset();
              },
              icon: Icon(Icons.refresh,
                color: Color(0xffF2F2F2),),

              label: Text("Refresh",),);

          }),
    ],
  )

Explanation:

I want to be able to switch seamlessly between a play icon (Icons.play_arrow) and a pause icon (Icons.pause) on my button with each click.

Upvotes: 1

Views: 121

Answers (1)

MendelG
MendelG

Reputation: 20118

Create a variable _isPlaying = false and then update it accordingly. Additionally, call myController.forward() instead of reverse(). I'm no master of animations, so I might of gotten this wrong (you might have to tweak this a bit). But it does seem to work:

import 'package:flutter/material.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  MyWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  var _animationController;
  var _isPlaying = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        AnimatedBuilder(
            animation: _animationController,
            builder: (context, child) {
              return FloatingActionButton.extended(
                  onPressed: () {
                    setState(() {
                      _isPlaying = !_isPlaying;
                    });
                    if (_animationController.isAnimating)
                      _animationController.stop();
                    else {
                      _animationController.forward(
                          from: _animationController.value == 0.0
                              ? 1.0
                              : _animationController.value);
                    }
                  },
                  icon: Icon(
                    _isPlaying ? Icons.pause : Icons.play_arrow,
                    color: Color(0xffF2F2F2),
                  ),
                  label: Text(
                    _animationController.isAnimating ? "Pause" : "Play",
                  ));
            }),
        SizedBox(
          width: 20,
        ),
        AnimatedBuilder(
            animation: _animationController,
            builder: (context, child) {
              return FloatingActionButton.extended(
                onPressed: () {
                  setState(() {
                    _isPlaying = !_isPlaying;
                  });
                },
                icon: Icon(
                  Icons.refresh,
                  color: Color(0xffF2F2F2),
                ),
                label: Text(
                  "Refresh",
                ),
              );
            }),
      ],
    ));
  }

  @override
  void initState() {
    // TODO: implement initState
    _animationController = AnimationController(
      vsync: this,
      duration: Duration(seconds: 1),
    );
    super.initState();
  }
}

Upvotes: 2

Related Questions