voo_watch_ui 0.2.2 copy "voo_watch_ui: ^0.2.2" to clipboard
voo_watch_ui: ^0.2.2 copied to clipboard

Cross-platform UI DSL for smartwatches. Define your watch UI in Dart and render it identically on Apple Watch (native SwiftUI) and Wear OS (Flutter).

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:voo_watch_ui/voo_watch_ui.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const _App());
}

class _App extends StatelessWidget {
  const _App();

  @override
  Widget build(BuildContext context) => MaterialApp(
    title: 'voo_watch_ui example',
    theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.indigo),
    home: const WatchUiThemeBinding(child: _Home()),
    debugShowCheckedModeBanner: false,
  );
}

class _Home extends StatefulWidget {
  const _Home();

  @override
  State<_Home> createState() => _HomeState();
}

class _HomeState extends State<_Home> {
  int _count = 0;
  bool _toggle = true;
  double _intensity = 0.5;
  String _lastTap = '— none —';

  @override
  void initState() {
    super.initState();
    final ui = VooWatchUi.instance
      ..onEvent('increment', (_) => setState(() {
            _count += 1;
            _lastTap = 'increment';
          }))
      ..onEvent('decrement', (_) => setState(() {
            _count = (_count - 1).clamp(0, 999);
            _lastTap = 'decrement';
          }))
      ..onEvent('toggle', (payload) => setState(() {
            _toggle = payload['value'] as bool? ?? !_toggle;
            _lastTap = 'toggle → $_toggle';
          }))
      ..onEvent('intensity', (payload) => setState(() {
            _intensity = (payload['value'] as num?)?.toDouble() ?? _intensity;
            _lastTap = 'intensity → ${_intensity.toStringAsFixed(2)}';
          }));
    // Push the initial tree once the renderer is wired up.
    WidgetsBinding.instance.addPostFrameCallback((_) => ui.render(_buildTree()));
  }

  WatchView _buildTree() => WatchView.column(
        crossAxisAlignment: WatchCrossAxisAlignment.stretch,
        children: <WatchView>[
          WatchView.text('Counter', style: WatchTextStyle.headline),
          const WatchSizedBox(height: 4),
          WatchView.card(
            child: WatchView.padding(
              padding: const WatchEdgeInsets.all(12),
              child: WatchView.row(
                mainAxisAlignment: WatchMainAxisAlignment.spaceBetween,
                children: <WatchView>[
                  WatchView.iconButton(icon: 'minus', onTap: 'decrement'),
                  WatchView.text('$_count', style: WatchTextStyle.title),
                  WatchView.iconButton(icon: 'plus', onTap: 'increment'),
                ],
              ),
            ),
          ),
          const WatchSizedBox(height: 12),
          WatchView.row(
            mainAxisAlignment: WatchMainAxisAlignment.spaceBetween,
            children: <WatchView>[
              WatchView.text('Notifications', style: WatchTextStyle.body),
              WatchView.toggle(value: _toggle, onChanged: 'toggle'),
            ],
          ),
          const WatchSizedBox(height: 8),
          WatchView.text('Intensity', style: WatchTextStyle.caption),
          WatchView.slider(value: _intensity, onChanged: 'intensity', activeColor: WatchColor.accent),
          const WatchSizedBox(height: 12),
          WatchView.progressIndicator(value: _intensity, kind: WatchProgressKind.linear, color: WatchColor.success),
          const WatchSizedBox(height: 12),
          WatchView.chip(label: 'Tap: $_lastTap', color: WatchColor.muted),
        ],
      );

  @override
  Widget build(BuildContext context) {
    final tree = _buildTree();
    // Rebuild the watch tree on every state change. `render` coalesces calls
    // within a 32ms window so a slider drag won't flood the bridge.
    VooWatchUi.instance.render(tree);

    const renderer = WatchUiFlutterRenderer();
    return Scaffold(
      appBar: AppBar(title: const Text('voo_watch_ui')),
      body: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            const Padding(
              padding: EdgeInsets.all(12),
              child: Text(
                'Phone preview (the same renderer Wear OS uses):',
                style: TextStyle(fontWeight: FontWeight.w600),
              ),
            ),
            Center(
              child: Container(
                width: 240,
                height: 280,
                decoration: BoxDecoration(
                  color: const Color(0xFF000000),
                  borderRadius: BorderRadius.circular(28),
                  border: Border.all(color: Colors.white24, width: 2),
                ),
                clipBehavior: Clip.antiAlias,
                child: Padding(
                  padding: const EdgeInsets.all(8),
                  child: Theme(
                    data: ThemeData(
                      useMaterial3: true,
                      brightness: Brightness.dark,
                      colorSchemeSeed: Colors.indigo,
                    ),
                    child: renderer.render(tree),
                  ),
                ),
              ),
            ),
            const Spacer(),
            Padding(
              padding: const EdgeInsets.all(12),
              child: Wrap(
                alignment: WrapAlignment.center,
                spacing: 8,
                children: <Widget>[
                  FilledButton.tonalIcon(
                    onPressed: () => VooWatchUi.instance.haptic(WatchHapticKind.success),
                    icon: const Icon(Icons.vibration),
                    label: const Text('Haptic: success'),
                  ),
                  FilledButton.tonalIcon(
                    onPressed: () => VooWatchUi.instance.haptic(WatchHapticKind.warning),
                    icon: const Icon(Icons.vibration),
                    label: const Text('Haptic: warning'),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}
2
likes
0
points
295
downloads

Publisher

verified publishervoostack.com

Weekly Downloads

Cross-platform UI DSL for smartwatches. Define your watch UI in Dart and render it identically on Apple Watch (native SwiftUI) and Wear OS (Flutter).

Homepage
Repository (GitHub)
View/report issues

Topics

#flutter #watch #watchos #wear-os #sdui

License

unknown (license)

Dependencies

args, flutter, meta, path, voo_watch, voo_wear

More

Packages that depend on voo_watch_ui