Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Flutter riverpod – why I must use hot reload to get UI updated?

I use flutter riverpod for managing state. Function lightUpPlayTitle() is executed on tap with ref.read(titleBlurProvider.notifier).lightUpPlayTitle(), I can see in console it was from prints, but UI is updated only after hot reload. Why I must use hot reload to get UI updated? What mistake did I do?

full code

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Image.asset('assets/matches_background.jpeg'),
          const TitlesWidget()
        ],
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          TitleWidget(
            text: 'Play',
            index: 0,
            callOnTap: () {
              Navigator.pushReplacement(
                  context,
                  MaterialPageRoute(
                      builder: ((context) => const PositionedPage())));
            },
          ),
          TitleWidget(
            text: 'Leads',
            index: 1,
            callOnTap: () {},
          )
        ],
      ),
    );
  }
}

class TitleWidget extends ConsumerWidget {
  TitleWidget(
      {super.key,
      required this.text,
      required this.callOnTap,
      required this.index});
  String text;
  Function callOnTap;

  int index = 0;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final double opacity = ref.watch(titleBlurProvider)[index];
    return Consumer(
      builder: (context, ref, child) => Stack(
        children: [
          Opacity(
            opacity: opacity,
            child: ImageFiltered(
              imageFilter: ImageFilter.blur(sigmaX: 3, sigmaY: 3),
              child: Text(
                text,
                style: const TextStyle(
                    fontSize: 80,
                    fontWeight: FontWeight.bold,
                    color: Colors.white),
                textAlign: TextAlign.center,
              ),
            ),
          ),
          GestureDetector(
            onLongPress: () => debugPrint(opacity.toString()),
            onTap: () =>
                ref.read(titleBlurProvider.notifier).lightUpPlayTitle(),
            child: Opacity(
              opacity: 0.8,
              child: Text(
                text,
                style: const TextStyle(
                    fontSize: 80,
                    fontWeight: FontWeight.bold,
                    color: Colors.white),
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

final titleBlurProvider = StateNotifierProvider<TitleBlur, List<double>>(
  (ref) => TitleBlur(),
);

class TitleBlur extends StateNotifier<List<double>> {
  TitleBlur() : super([0, 0]);

  startRegularBlur() {
    Timer.periodic(const Duration(), (timer) {});
  }

  lightUpPlayTitle() {
    debugPrint('light up');

    while (state[0] < 1) {
      Future.delayed(const Duration(milliseconds: 500));
      state[0] = state[0] + 0.1;
      if (state[0] > 1) state[0] = 1;
      debugPrint(state[0].toString());
    }
  }
}


I tried moving Consumer to the top of widget tree but it didn't help me

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You are mutating the list by changing the element in this line:

state[0] = state[0] + 0.1;

The state of a StateNotifier should be immutable, so you have to clone the list and add the modification. You can do it like this:

state = [state[0] + 0.1, ...state.sublist(1)]

See about immutability of the state of StateNotifier and how to modify the state here: https://riverpod.dev/docs/providers/state_notifier_provider


But please note that StateNotifier is an old concept and is no longer recommended. The docs I linked above is in the "old" providers section. Please refer to the rest of Riverpod documentation for guides on the latest way to manage states using Riverpod.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading