消费者不使用 riverpod 重建 UI

时间:2021-01-17 13:34:04

标签: flutter dart provider flutter-provider riverpod

我正在尝试使用 riverpod 制作简单的 stateNotifier。当我单击按钮时,它会在值之间切换。我已经检查了该值,按下按钮时它会发生变化。问题是 UI 没有自行重建。我已经检查了文档,并且很确定我做对了。

主屏幕

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  @override
  void initState() {
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Consumer(
        builder: (context, watch, child) {
          final drawer = watch(drawerProvider.state);
          return Container(
            width: MediaQuery.of(context).size.width,
            child: Column(
              children: [
                Text(drawer.isOpen.toString()),
                Text(drawer.x.toString()),
                Text(drawer.y.toString()),
                Text(drawer.scale.toString()),
                FloatingActionButton(
                  onPressed: (){
                    context.read(drawerProvider).toggleDrawer();
                  }
                )
              ],
            ),
          );
        },
      ),
    );
  }
}

供应商

import 'package:flutter_riverpod/all.dart';

class Drawer{
  double x,y,scale;
  bool isOpen;
  Drawer(this.x,this.y,this.scale,this.isOpen);
}

class DrawerNotifier extends StateNotifier<Drawer>{
  DrawerNotifier() : super(Drawer(0,0,1,false));
  void toggleDrawer(){
    if(state.isOpen){
      state.x = 0;
      state.y = 0;
      state.scale = 1;
    }else{
      state.x = 0.5;
      state.y = 0.1;
      state.scale = 0.8;
    }
    state.isOpen = !state.isOpen;
  }
}

final drawerProvider = StateNotifierProvider((ref) => new DrawerNotifier());

1 个答案:

答案 0 :(得分:1)

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

@immutable
class Drawer {
  final double x;
  final double y;
  final double scale;
  final bool isOpen;

  Drawer(this.x, this.y, this.scale, this.isOpen);

  factory Drawer.initial() {
    return Drawer(0, 0, 1, false);
  }
  Drawer copyWith({
    double x,
    double y,
    double scale,
    bool isOpen,
  }) {
    return Drawer(
      x ?? this.x,
      y ?? this.y,
      scale ?? this.scale,
      isOpen ?? this.isOpen,
    );
  }

  @override
  String toString() {
    return 'Drawer(x: $x, y: $y, scale: $scale, isOpen: $isOpen)';
  }
}

class DrawerNotifier extends StateNotifier<Drawer> {
  final Drawer drawer;
  DrawerNotifier(this.drawer) : super(drawer ?? Drawer.initial());

  void toggleDrawer() {
    if (state.isOpen) {
      state = state.copyWith(x: 0, y: 0, scale: 1);
    } else {
      state = state.copyWith(x: 0.5, y: 0.1, scale: 0.8);
    }
    state = state.copyWith(isOpen: !state.isOpen);
    print("new state>> $state");
  }
}

final drawerProvider =
    StateNotifierProvider((ref) => new DrawerNotifier(Drawer.initial()));

class DrawerScreen extends StatefulWidget {
  @override
  _DrawerScreenState createState() => _DrawerScreenState();
}

class _DrawerScreenState extends State<DrawerScreen> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Consumer(
        builder: (context, watch, child) {
          final drawer = watch(drawerProvider.state);
          return Container(
            width: MediaQuery.of(context).size.width,
            child: Column(
              children: [
                Text(drawer.isOpen.toString()),
                Text(drawer.x.toString()),
                Text(drawer.y.toString()),
                Text(drawer.scale.toString()),
                FloatingActionButton(onPressed: () {
                  context.read(drawerProvider).toggleDrawer();
                })
              ],
            ),
          );
        },
      ),
    );
  }
}