siri_wave 2.3.0 copy "siri_wave: ^2.3.0" to clipboard
siri_wave: ^2.3.0 copied to clipboard

A Flutter package that lets you create visually stunning Siri-style waveforms.

example/lib/main.dart

import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
import 'package:siri_wave/siri_wave.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) => MaterialApp(
    debugShowCheckedModeBanner: false,
    home: const HomePage(),
    darkTheme: ThemeData(brightness: Brightness.dark),
    themeMode: ThemeMode.dark,
    title: 'siri_wave Demo',
  );
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

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

class _HomePageState extends State<HomePage> {
  double amplitude = 1;
  Color color = Colors.white;
  Color color1 = const Color(0xFFAD394C);
  Color color2 = const Color(0xFF30DC9B);
  Color color3 = const Color(0xFF0F52A9);
  SiriWaveformController controller = IOS9SiriWaveformController();
  double frequency = 6;
  final selection = [false, true];
  bool showSupportBar = true;
  double speed = .2;

  SiriWaveformStyle get style =>
      selection[0] ? SiriWaveformStyle.ios_7 : SiriWaveformStyle.ios_9;

  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(centerTitle: kIsWeb, title: const Text('siri_wave Demo')),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Spacer(),
          CustomSlider(
            onChanged: (value) {
              controller.amplitude = value;
              setState(() => amplitude = value);
            },
            label: 'Amplitude',
            value: amplitude,
          ),
          CustomSlider(
            onChanged: (value) {
              controller.speed = value;
              setState(() => speed = value);
            },
            label: 'Speed',
            value: speed,
          ),
          if (style == SiriWaveformStyle.ios_9) ...[
            CustomSwitch(
              onChanged: (value) {
                setState(() => showSupportBar = value);
              },
              value: showSupportBar,
            ),
            Wrap(
              alignment: WrapAlignment.center,
              spacing: 10,
              children: [
                ColorPickerWidget(
                  title: 'Color 1',
                  onChanged: (value) {
                    setState(() => color1 = value);
                    (controller as IOS9SiriWaveformController).color1 = value;
                  },
                  color: color1,
                ),
                ColorPickerWidget(
                  title: 'Color 2',
                  onChanged: (value) {
                    setState(() => color2 = value);
                    (controller as IOS9SiriWaveformController).color2 = value;
                  },
                  color: color2,
                ),
                ColorPickerWidget(
                  title: 'Color 3',
                  onChanged: (value) {
                    setState(() => color3 = value);
                    (controller as IOS9SiriWaveformController).color3 = value;
                  },
                  color: color3,
                ),
              ],
            ),
          ] else ...[
            FrequencySlider(
              onChanged: (value) {
                (controller as IOS7SiriWaveformController).frequency =
                    value.round();
                setState(() => frequency = value);
              },
              value: frequency,
            ),
            ColorPickerWidget(
              onChanged: (value) {
                setState(() => color = value);
                (controller as IOS7SiriWaveformController).color = value;
              },
              color: color,
            ),
          ],
          WaveformStyleToggleButtons(
            onPressed: (index) {
              if (selection[index]) return;
              for (var i = 0; i < selection.length; i++) {
                selection[i] = i == index;
              }
              controller =
                  index == 0
                      ? IOS7SiriWaveformController()
                      : IOS9SiriWaveformController();
              setState(() {});
            },
            selection: selection,
          ),
          const Spacer(),
          const CustomDivider(),
          SiriWaveformWidget(
            controller: controller,
            showSupportBar: showSupportBar,
            style: style,
          ),
          const CustomDivider(),
        ],
      ),
    ),
  );
}

class CustomSlider extends StatelessWidget {
  const CustomSlider({
    required this.onChanged,
    required this.label,
    required this.value,
    super.key,
  });

  final ValueChanged<double> onChanged;

  final String label;
  final double value;

  @override
  Widget build(BuildContext context) => Column(
    children: [
      Text(label, style: Theme.of(context).textTheme.titleLarge),
      Padding(
        padding: const EdgeInsets.symmetric(vertical: 5),
        child: SizedBox(
          width: 360,
          child: Slider(value: value, onChanged: onChanged),
        ),
      ),
    ],
  );
}

class CustomSwitch extends StatelessWidget {
  const CustomSwitch({required this.onChanged, required this.value, super.key});

  final ValueChanged<bool> onChanged;
  final bool value;

  @override
  Widget build(BuildContext context) => AnimatedSize(
    curve: Curves.fastOutSlowIn,
    duration: const Duration(milliseconds: 400),
    child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Show support bar', style: Theme.of(context).textTheme.titleLarge),
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 5),
          child: Switch(value: value, onChanged: onChanged),
        ),
      ],
    ),
  );
}

class FrequencySlider extends StatelessWidget {
  const FrequencySlider({
    required this.onChanged,
    required this.value,
    super.key,
  });

  final ValueChanged<double> onChanged;
  final double value;

  @override
  Widget build(BuildContext context) => AnimatedSize(
    curve: Curves.fastOutSlowIn,
    duration: const Duration(milliseconds: 400),
    child: Column(
      children: [
        Text('Frequency', style: Theme.of(context).textTheme.titleLarge),
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 5),
          child: SizedBox(
            width: 360,
            child: Slider(
              value: value,
              divisions: 40,
              min: -20,
              max: 20,
              onChanged: onChanged,
            ),
          ),
        ),
      ],
    ),
  );
}

class ColorPickerWidget extends StatelessWidget {
  const ColorPickerWidget({
    required this.onChanged,
    required this.color,
    this.title = 'Color',
    super.key,
  });

  final ValueChanged<Color> onChanged;
  final Color color;
  final String title;

  @override
  Widget build(BuildContext context) => AnimatedSize(
    curve: Curves.fastOutSlowIn,
    duration: const Duration(milliseconds: 400),
    child: Column(
      children: [
        Text(title, style: Theme.of(context).textTheme.titleLarge),
        Padding(
          padding: const EdgeInsets.symmetric(vertical: 15),
          child: ElevatedButton(
            onPressed: () async {
              await showDialog<void>(
                context: context,
                builder:
                    (context) => AlertDialog(
                      titlePadding: EdgeInsets.zero,
                      contentPadding: EdgeInsets.zero,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(9),
                      ),
                      content: SingleChildScrollView(
                        child: ColorPicker(
                          pickerColor: color,
                          onColorChanged: onChanged,
                          pickerAreaHeightPercent: .7,
                          displayThumbColor: true,
                          paletteType: PaletteType.hsl,
                          pickerAreaBorderRadius: BorderRadius.circular(8),
                        ),
                      ),
                    ),
              );
            },
            child: const Text('Change color'),
          ),
        ),
      ],
    ),
  );
}

class WaveformStyleToggleButtons extends StatelessWidget {
  const WaveformStyleToggleButtons({
    required this.onPressed,
    required this.selection,
    super.key,
  });

  final ValueChanged<int> onPressed;
  final List<bool> selection;

  @override
  Widget build(BuildContext context) => Column(
    children: [
      Text('Style', style: Theme.of(context).textTheme.titleLarge),
      const SizedBox(height: 15),
      ToggleButtons(
        onPressed: onPressed,
        borderColor: Theme.of(context).primaryColorLight,
        borderRadius: BorderRadius.circular(16),
        isSelected: selection,
        selectedBorderColor: Theme.of(context).colorScheme.primary,
        children: const [
          Padding(padding: EdgeInsets.all(16), child: Text('iOS 7')),
          Padding(padding: EdgeInsets.all(16), child: Text('iOS 9')),
        ],
      ),
    ],
  );
}

class CustomDivider extends StatelessWidget {
  const CustomDivider({super.key});

  @override
  Widget build(BuildContext context) => SizedBox(
    width: kIsWeb ? 600 : 360,
    child: Divider(color: Theme.of(context).colorScheme.primary, thickness: 1),
  );
}

class SiriWaveformWidget extends StatelessWidget {
  const SiriWaveformWidget({
    required this.controller,
    required this.style,
    this.showSupportBar = true,
    super.key,
  });

  final SiriWaveformController controller;
  final bool showSupportBar;
  final SiriWaveformStyle style;

  @override
  Widget build(BuildContext context) =>
      style == SiriWaveformStyle.ios_7
          ? SiriWaveform.ios7(
            controller: controller as IOS7SiriWaveformController,
            options: const IOS7SiriWaveformOptions(
              height: kIsWeb ? 300 : 180,
              width: kIsWeb ? 600 : 360,
            ),
          )
          : SiriWaveform.ios9(
            controller: controller as IOS9SiriWaveformController,
            options: IOS9SiriWaveformOptions(
              height: kIsWeb ? 300 : 180,
              showSupportBar: showSupportBar,
              width: kIsWeb ? 600 : 360,
            ),
          );
}
copied to clipboard
128
likes
160
points
3.93k
downloads
screenshot

Publisher

verified publisherhalildurmus.dev

Weekly Downloads

2024.09.13 - 2025.03.28

A Flutter package that lets you create visually stunning Siri-style waveforms.

Repository (GitHub)
View/report issues
Contributing

Topics

#wave #waveform #siri

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on siri_wave