flutter_nerve 0.2.0 copy "flutter_nerve: ^0.2.0" to clipboard
flutter_nerve: ^0.2.0 copied to clipboard

A sensory-reactive UI engine for Flutter. Make your app feel the real world — react to battery, network, motion, light, and sound.

flutter_nerve #

A sensory-reactive UI engine for Flutter. Make your app feel the real world — react to battery level, network quality, motion, ambient light, and sound with zero boilerplate.

pub.flutter-io.cn CI License: MIT


Platform Support #

Sensor Android iOS Web Desktop
Battery ⚠️ partial
Network
Motion (accelerometer)
Ambient Light ⚠️ entitlement
Sound (microphone)

Quick Start #

1. Add the dependency #

dependencies:
  flutter_nerve: ^0.2.0

2. Wrap your app #

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

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

  @override
  Widget build(BuildContext context) {
    return NerveRoot(
      enableMicrophone: true,  // requests mic permission automatically
      child: MaterialApp(home: MyHomePage()),
    );
  }
}

3. Read sensor data anywhere #

// Inside any descendant widget:
final state = NerveProvider.of(context);
print(state.batteryLevel);     // 0.0 – 1.0
print(state.networkQuality);   // NetworkQuality.good / fair / poor / none
print(state.tiltX);            // -1.0 – 1.0
print(state.soundLevel);       // 0.0 – 1.0 (null if unavailable)
print(state.ambientLight);     // lux (null if unavailable)

Reactive Widgets #

NerveBuilder #

Rebuilds on every sensor update — like AnimatedBuilder but for device senses:

NerveBuilder(
  builder: (context, state, child) {
    return Opacity(
      opacity: state.batteryLevel,
      child: child,
    );
  },
  child: const BatteryIcon(),
)

ReactiveContainer #

A container whose color, scale, and blur are driven by sensor state:

ReactiveContainer(
  colorMapper: (s) => Color.lerp(Colors.red, Colors.green, s.batteryLevel)!,
  scaleMapper: (s) => 1.0 + MotionSense.magnitude(s.tiltX, s.tiltY) * 0.15,
  child: const FlutterLogo(size: 100),
)

NervePulse #

Pulses (scales) a child widget in sync with ambient sound level:

NervePulse(
  maxScale: 1.3,
  pulseOpacity: true,
  child: const Icon(Icons.mic, size: 64),
)

NerveGlow #

Animates a glowing border driven by tilt magnitude or a custom mapper:

NerveGlow(
  color: Colors.purpleAccent,
  maxBlurRadius: 24,
  child: const FlutterLogo(size: 80),
)

NerveBatteryIcon #

Custom-painted animated battery icon — color-coded, ⚡ when charging:

NerveBatteryIcon(size: 48)

NerveScaffold #

Full-screen scaffold with sensor-reactive gradient background and motion-parallax header:

NerveScaffold(
  parallaxDepth: 20,
  showNetworkBanner: true,
  body: MyContent(),
)

NerveMonitor #

Floating, draggable debug overlay showing all live sensor readings. Tap to collapse to a 🧠 icon. Use inside kDebugMode to strip from production:

NerveMonitor(
  startCollapsed: true,   // starts as a small icon
  child: MyScaffoldBody(),
)

NerveShake #

Detects shake gestures via accelerometer spikes. Fires onShake with cooldown:

NerveShake(
  threshold: 0.65,         // 0.0–1.0, how strong a shake is required
  cooldown: Duration(milliseconds: 600),
  onShake: () => setState(() => _count++),
  child: myWidget,
)

NerveSpring #

Applies a physics-spring offset to its child driven by tilt, creating a floating parallax feel:

NerveSpring(
  depth: 20,    // max pixel offset at full tilt
  child: const FlutterLogo(size: 100),
)

NerveConnectivity #

Pre-built animated banner that slides in when network is poor or gone:

NerveConnectivity(
  child: MyContent(),
  // Optional: supply your own banners
  noBanner: MyNoBannerWidget(),
  poorBanner: MyPoorBannerWidget(),
)

Testing with NerveFakes #

Test any widget without real hardware using pre-set sensor controllers:

testWidgets('shows red theme on low battery', (tester) async {
  final ctrl = NerveFakes.withBattery(0.05);
  await tester.pumpWidget(
    NerveRoot(controller: ctrl, child: MyApp()),
  );
  expect(find.text('Low Battery!'), findsOneWidget);
  ctrl.dispose();
});

// Other factories:
NerveFakes.withNetwork(NetworkQuality.none);
NerveFakes.withMotion(0.5, -0.3);
NerveFakes.withLight(200.0);
NerveFakes.withSound(0.8);
NerveFakes.withAllSenses(batteryLevel: 0.1, charging: false, soundLevel: 0.9);

Adaptive Theme #

NerveTheme.resolve() returns a ThemeData that automatically adapts to sensor readings:

Condition Effect
Battery < 15% Greyscale palette
No network Red tint
Poor network Orange warning tint
Sound level > 70% Vibrant cyan palette
Tilted > 30% Hue shift
NerveBuilder(
  builder: (context, state, _) {
    return MaterialApp(
      theme: NerveTheme.resolve(context, state),
      home: MyHomePage(),
    );
  },
)

Custom Sense Adapters #

Inject your own sensor streams via the NerveController constructor for testing or custom data sources:

final controller = NerveController(
  battery: MyCustomBatterySense(),
  sound: SoundSense.withStream(myAudioStream),
);

NerveRoot(controller: controller, child: MyApp())

Permissions #

Add the following to your app (not the package itself):

Android (android/app/src/main/AndroidManifest.xml):

<uses-permission android:name="android.permission.RECORD_AUDIO"/>

iOS (ios/Runner/Info.plist):

<key>NSMicrophoneUsageDescription</key>
<string>Used to detect ambient sound level for reactive UI effects.</string>

License #

MIT — see LICENSE.

0
likes
150
points
28
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A sensory-reactive UI engine for Flutter. Make your app feel the real world — react to battery, network, motion, light, and sound.

Repository (GitHub)
View/report issues

Topics

#sensors #reactive #ui #battery #motion

License

MIT (license)

Dependencies

battery_plus, connectivity_plus, flutter, light, record, sensors_plus

More

Packages that depend on flutter_nerve