# dotLottie Flutter Player Examples
Practical examples of using the dotLottie Flutter player, including playback control, state machines, theming, and slots.

# dotLottie Flutter Player Examples

## Basic Animation with Controls

```dart
import 'package:flutter/material.dart';
import 'package:dotlottie_flutter/dotlottie_flutter.dart';

class AnimationControlsPage extends StatefulWidget {
  @override
  State<AnimationControlsPage> createState() => _AnimationControlsPageState();
}

class _AnimationControlsPageState extends State<AnimationControlsPage> {
  DotLottieViewController? _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('dotLottie Controls')),
      body: Column(
        children: [
          DotLottieView(
            source: 'https://lottie.host/example/animation.lottie',
            sourceType: 'url',
            loop: true,
            onViewCreated: (c) => setState(() => _controller = c),
            onLoad: () => print('Loaded'),
            onComplete: () => print('Complete'),
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              IconButton(
                icon: const Icon(Icons.play_arrow),
                onPressed: () => _controller?.play(),
              ),
              IconButton(
                icon: const Icon(Icons.pause),
                onPressed: () => _controller?.pause(),
              ),
              IconButton(
                icon: const Icon(Icons.stop),
                onPressed: () => _controller?.stop(),
              ),
            ],
          ),
          ElevatedButton(
            onPressed: () => _controller?.setSpeed(2.0),
            child: const Text('2x Speed'),
          ),
          ElevatedButton(
            onPressed: () => _controller?.setMode('bounce'),
            child: const Text('Bounce Mode'),
          ),
        ],
      ),
    );
  }
}
```

## Controlling Fit and Alignment

Use the `fit` prop to control how the animation is inscribed into its bounds, just like Flutter's `Image` widget. Changing `fit` at runtime pushes the new layout to the native player without recreating the view.

```dart
import 'package:flutter/material.dart';
import 'package:dotlottie_flutter/dotlottie_flutter.dart';

class FitExamplePage extends StatefulWidget {
  @override
  State<FitExamplePage> createState() => _FitExamplePageState();
}

class _FitExamplePageState extends State<FitExamplePage> {
  DotLottieViewController? _controller;
  BoxFit _fit = BoxFit.contain;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Fit Example')),
      body: Column(
        children: [
          // A non-square container makes the BoxFit differences obvious.
          Container(
            width: 320,
            height: 180,
            decoration: BoxDecoration(
              color: Colors.grey[200],
              border: Border.all(color: Colors.blueAccent),
            ),
            child: DotLottieView(
              source: 'assets/animation.lottie',
              sourceType: 'asset',
              autoplay: true,
              loop: true,
              fit: _fit,
              onViewCreated: (c) => _controller = c,
            ),
          ),
          const SizedBox(height: 16),
          Wrap(
            spacing: 8,
            children: [
              BoxFit.contain,
              BoxFit.cover,
              BoxFit.fill,
              BoxFit.fitWidth,
              BoxFit.fitHeight,
              BoxFit.none,
            ].map((fit) {
              return FilterChip(
                label: Text(fit.name),
                selected: _fit == fit,
                onSelected: (_) => setState(() => _fit = fit),
              );
            }).toList(),
          ),
          const SizedBox(height: 16),
          // Use setLayout to change alignment without changing the fit prop.
          ElevatedButton(
            onPressed: () => _controller?.setLayout(
              BoxFit.contain,
              alignment: Alignment.topLeft,
            ),
            child: const Text('Align top-left (contain)'),
          ),
          ElevatedButton(
            onPressed: () => _controller?.setLayout(
              BoxFit.contain,
              alignment: Alignment.center,
            ),
            child: const Text('Reset to center (contain)'),
          ),
        ],
      ),
    );
  }
}
```

You can also call `setLayout()` directly on the controller to change both the fit mode and the alignment at any time:

```dart
// Pin the animation to the bottom-right corner.
await _controller?.setLayout(
  BoxFit.contain,
  alignment: Alignment.bottomRight,
);

// Fill the container completely.
await _controller?.setLayout(BoxFit.fill);
```

## Applying a Theme

```dart
DotLottieView(
  source: 'assets/themed_animation.lottie',
  sourceType: 'asset',
  autoplay: true,
  loop: true,
  themeId: 'dark-mode',
  onViewCreated: (controller) async {
    // Switch themes after 3 seconds
    await Future.delayed(const Duration(seconds: 3));
    await controller.setTheme('light-mode');
  },
)
```

## Playing a Segment

```dart
DotLottieView(
  source: 'assets/animation.lottie',
  sourceType: 'asset',
  autoplay: true,
  loop: true,
  segment: [10, 60],  // Play frames 10 through 60
)
```

## Playing a Named Marker

```dart
DotLottieView(
  source: 'assets/animation.lottie',
  sourceType: 'asset',
  autoplay: true,
  loop: false,
  marker: 'intro',
  onComplete: () => print('Intro marker finished'),
)
```

## Updating Slots Dynamically

```dart
DotLottieView(
  source: 'assets/branded_animation.lottie',
  sourceType: 'asset',
  autoplay: true,
  loop: true,
  onViewCreated: (controller) async {
    // Update brand color and headline text via JSON string
    await controller.setSlots(
      '{"primaryColor": [1.0, 0.0, 0.0, 1.0], "headlineText": {"t": "Hello Flutter!"}}'
    );
  },
)
```

## Using a State Machine

```dart
class InteractiveAnimation extends StatefulWidget {
  @override
  State<InteractiveAnimation> createState() => _InteractiveAnimationState();
}

class _InteractiveAnimationState extends State<InteractiveAnimation> {
  DotLottieViewController? _controller;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        DotLottieView(
          source: 'assets/interactive.lottie',
          sourceType: 'asset',
          stateMachineId: 'buttonFSM',
          onViewCreated: (c) => setState(() => _controller = c),
          stateMachineOnStateEntered: (state) {
            print('Entered state: $state');
          },
          stateMachineOnTransition: (from, to) {
            print('Transition: $from -> $to');
          },
        ),
        ElevatedButton(
          onPressed: () async {
            await _controller?.stateMachineFire('click');
          },
          child: const Text('Trigger Click'),
        ),
        ElevatedButton(
          onPressed: () async {
            await _controller?.stateMachineSetBooleanInput('isActive', true);
          },
          child: const Text('Set isActive = true'),
        ),
      ],
    );
  }
}
```

## Multi-Animation File

```dart
DotLottieView(
  source: 'assets/multi.lottie',
  sourceType: 'asset',
  animationId: 'scene-2',
  autoplay: true,
  loop: true,
  onViewCreated: (controller) async {
    // Switch to another animation after 5 seconds
    await Future.delayed(const Duration(seconds: 5));
    await controller.loadAnimation('scene-3');
  },
)
```

## Related Topics

- [Getting Started](/en/runtimes/distributions/flutter/v0.x/getting-started)
- [API Reference](/en/runtimes/distributions/flutter/v0.x/api-reference)
