1

I want to use AnimationController in the StatelessWidget class with Cubit or Bloc in a flutter, if anyone can help me with an example link to explain?

3 Answers3

1

I think the general practice is to avoid using presentation layer components in Blocs. I would use Bloc to manage my state value, but run the animation components in a stateful widget.

Blocs

part 'side_bloc.freezed.dart';

typedef StateEmitter = Emitter<SideState>;

class SideBloc extends Bloc<SideEvent, SideState> {
  SideBloc() : super(const SideState(20)) {
    on<SideIncrement>(onIncrement);
    on<SideDecrement>(onDecrement);
  }

  void onIncrement(SideIncrement event, StateEmitter emit) {
    emit(state.copyWith(side: state.side + 10));
  }

  void onDecrement(SideDecrement event, StateEmitter emit) {
    if (state.side <= 10) {
      return;
    }
    emit(state.copyWith(side: state.side - 10));
  }
}

@freezed
class SideEvent with _$SideEvent {
  const factory SideEvent.increment() = SideIncrement;

  const factory SideEvent.decrement() = SideDecrement;
}

@freezed
class SideState with _$SideState {
  const factory SideState(int side) = _SideState;
}

Animated component

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<int> _animation;
  late CurvedAnimation _curvedAnimation;

  @override
  void initState() {
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
    );
    _curvedAnimation = CurvedAnimation(
      parent: _controller,
      curve: Curves.elasticOut,
    );
    _animation = IntTween(begin: 20, end: 20).animate(_curvedAnimation);
    _controller.forward();

    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _animateTo(int value) {
    int old = _animation.value;
    _controller.reset();
    _animation = IntTween(begin: old, end: value).animate(
      _curvedAnimation,
    );
    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: BlocListener<SideBloc, SideState>(
        listener: (context, state) {
          _animateTo(state.side);
        },
        child: AnimatedBuilder(
          animation: _animation,
          builder: (context, child) {
            return SizedSquare(side: _animation.value);
          },
        ),
      ),
      floatingActionButton: const SideChangeButtons(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        FloatingActionButton(
          onPressed: () =>
              context.read<SideBloc>().add(const SideEvent.increment()),
          child: const Icon(Icons.add),
        ),
        const SizedBox(height: 8),
        FloatingActionButton(
          onPressed: () =>
              context.read<SideBloc>().add(const SideEvent.decrement()),
          child: const Icon(Icons.remove),
        ),
      ],
    );
  }
}

class SizedSquare extends StatelessWidget {
  final int side;

  const SizedSquare({
    Key? key,
    required this.side,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox.fromSize(
        size: Size.square(side.toDouble()),
        child: Container(color: Colors.red),
      ),
    );
  }
}
Ajil O.
  • 6,562
  • 5
  • 40
  • 72
0

AnimationController works with TickerProviderStateMixin which means that you MUST use a statefulWidget somewhere in your widget tree.

Hamid
  • 11
  • 1
0

You can check this github issue https://github.com/felangel/bloc/issues/2293. In here core bloc developers indicates that stateful widget is best practice to use when it comes to using controllers. If you use stateless widget and controller you might cause memory leak. Also If you set and init your controller inside bloc/cubit it goes against bloc principles which you mix presentation layer logic into business layer logic.