chayanforyou

rive: ^0.14.5

Apr 8th, 2026
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 3.03 KB | None | 0 0
  1. import 'package:easy_refresh/easy_refresh.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:rive/rive.dart';
  4. import 'package:sizer/sizer.dart';
  5.  
  6. class SunriseIndicator extends StatefulWidget {
  7.   final IndicatorState state;
  8.   final bool reverse;
  9.  
  10.   const SunriseIndicator({
  11.     super.key,
  12.     required this.state,
  13.     required this.reverse,
  14.   });
  15.  
  16.   @override
  17.   State<SunriseIndicator> createState() => _SunriseIndicatorState();
  18. }
  19.  
  20. class _SunriseIndicatorState extends State<SunriseIndicator> {
  21.   // Only this needs manual dispose — RiveWidgetBuilder handles the rest
  22.   late final FileLoader _fileLoader = FileLoader.fromAsset(
  23.     'assets/rive/pull_refresh.riv',
  24.     riveFactory: Factory.rive,
  25.   );
  26.  
  27.   ViewModelInstanceNumber? _pullAmount;
  28.   ViewModelInstanceTrigger? _loadingTrigger;
  29.   ViewModelInstanceTrigger? _finishTrigger;
  30.  
  31.   double get _offset => widget.state.offset;
  32.  
  33.   double get _actualTriggerOffset => widget.state.actualTriggerOffset;
  34.  
  35.   @override
  36.   void initState() {
  37.     super.initState();
  38.     widget.state.notifier.addModeChangeListener(_onModeChange);
  39.   }
  40.  
  41.   @override
  42.   void dispose() {
  43.     widget.state.notifier.removeModeChangeListener(_onModeChange);
  44.     _fileLoader.dispose(); // Only thing you need to dispose manually
  45.     super.dispose();
  46.   }
  47.  
  48.   void _onLoaded(RiveLoaded state) {
  49.     // RiveWidgetBuilder gives you the controller via onLoaded callback
  50.     final vmi = state.controller.dataBind(DataBind.auto());
  51.     _pullAmount = vmi.number('pullAmount');
  52.     _loadingTrigger = vmi.trigger('loadingTrigger');
  53.     _finishTrigger = vmi.trigger('finishTrigger');
  54.   }
  55.  
  56.   void _onModeChange(IndicatorMode mode, double offset) {
  57.     switch (mode) {
  58.       case IndicatorMode.ready:
  59.         _loadingTrigger?.trigger();
  60.         break;
  61.       case IndicatorMode.processed:
  62.         _finishTrigger?.trigger();
  63.         break;
  64.       case IndicatorMode.done:
  65.         _pullAmount?.value = 0;
  66.         break;
  67.       default:
  68.         break;
  69.     }
  70.   }
  71.  
  72.   @override
  73.   void didUpdateWidget(covariant SunriseIndicator oldWidget) {
  74.     super.didUpdateWidget(oldWidget);
  75.     print(_pullAmount);
  76.     if (_pullAmount != null) {
  77.       _pullAmount!.value = _offset < _actualTriggerOffset
  78.           ? (_offset / _actualTriggerOffset * 100).clamp(0.0, 100.0)
  79.           : 100.0;
  80.     }
  81.   }
  82.  
  83.   @override
  84.   Widget build(BuildContext context) {
  85.     return SizedBox(
  86.       height: 27.h,
  87.       width: 100.w,
  88.       child: RiveWidgetBuilder(
  89.         fileLoader: _fileLoader,
  90.         artboardSelector: ArtboardSelector.byName('Artboard'),
  91.         stateMachineSelector: StateMachineSelector.byName('Main'),
  92.         onLoaded: _onLoaded,
  93.         // Wire up data binding here
  94.         builder: (context, state) => switch (state) {
  95.           RiveLoading() => const SizedBox.shrink(),
  96.           RiveFailed() => const SizedBox.shrink(), // or show an error
  97.           RiveLoaded() => RiveWidget(
  98.             controller: state.controller,
  99.             fit: Fit.fitWidth,
  100.           ),
  101.         },
  102.       ),
  103.     );
  104.   }
  105. }
  106.  
Advertisement
Add Comment
Please, Sign In to add comment