繁体   English   中英

Riverpod StateNotifier 不适用于 hover 逻辑

[英]Riverpod StateNotifier not working with hover logic

我正在尝试使用 Riverpod 和它的 StateNotifier 来控制我的导航栏。 下面是我的代码:

状态通知文件

import 'package:flutter_riverpod/flutter_riverpod.dart';

final navigationControllerRP =
    StateNotifierProvider<NavigationControllerRP, NavigationControllerElement>(
        (ref) => NavigationControllerRP());

class NavigationControllerRP
    extends StateNotifier<NavigationControllerElement> {
  NavigationControllerRP() : super(NavigationControllerElement("Home", ""));

  void changeActiveTo(String item) {
    state = NavigationControllerElement(item, "");
    state = state;
  }

  void changeHoverTo(String item) {
    if (item != state.activeItem) {
      state = NavigationControllerElement(state.activeItem, item);
      state = state;
    }
  }

  bool isActive(String item) {
    return state.activeItem == item;
  }

  bool isHover(String item) {
    return state.hoverItem == item;
  }
}

class NavigationControllerElement {
  var activeItem = "";
  var hoverItem = "";

  NavigationControllerElement(this.activeItem, this.hoverItem);
}

通知程序的使用文件

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:get/get.dart';
import 'package:platform/constants/controllers.dart';
import 'package:platform/constants/style.dart';
import 'package:platform/controllers/navigation.dart';
import 'package:platform/widgets/custom_text.dart';

class NavBarElement extends ConsumerWidget {
  /// Creates a navbar element which can be displayed at the top of the page.
  final String title;
  final String url;
  final String route;

  NavBarElement({
    required this.title,
    required this.url,
    required this.route,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return InkWell(
      highlightColor: Colors.transparent,
      hoverColor: Colors.transparent,
      child: Padding(
          padding: EdgeInsets.all(20.0),
          child: Consumer(
            builder: (BuildContext context, WidgetRef ref, Widget? child) {
              return Column(
                children: [
                  CustomText(
                    text: this.title,
                    size: 16,
                    color: ref
                            .watch(navigationControllerRP.notifier)
                            .isActive(this.title)
                        ? Color.fromRGBO(70, 70, 70, 1)
                        : Colors.grey,
                    weight: FontWeight.w500,
                  ),
                  SizedBox(
                    height: 7,
                  ),
                  ref
                          .watch(navigationControllerRP.notifier)
                          .isActive(this.title)
                      ? Container(width: 50, height: 1, color: Colors.black)
                      : Container(),
                  ref.watch(navigationControllerRP.notifier).isHover(this.title)
                      ? Container(width: 50, height: 1, color: Colors.red)
                      : Container(),
                ],
              );
            },
          )),
      onTap: () {
        ref.watch(navigationControllerRP.notifier).changeActiveTo(this.title);

        // navigationController.changeActiveTo(this.route);
        Get.toNamed(route);
      },
      onHover: (value) {
        value
            ? ref
                .watch(navigationControllerRP.notifier)
                .changeHoverTo(this.title)
            : ref.watch(navigationControllerRP.notifier).changeHoverTo("none");
      },
    );
  }
}

我的 activeItem 逻辑工作正常,但 hoverItem 逻辑似乎不起作用。 每次我在导航栏元素上使用 hover 时,它似乎都在更新 state ,即为我的 NavigationControllerElement object 设置 hoverItem 但它没有反映在 UI 中。 请让我知道如何解决这个问题。 提前致谢!

您使用 StateNotifier 的方式不正确。 StateNotifier不应该在state之外有任何可听的东西

特别是,您做错的事情是在 UI 使用的StateNotifier上添加 getter/方法:

class Model{...}

class MyNotifier extends StateNotifier<Model> {
  ...

  bool isActive(Item item) => state.activeItem == item; // DON'T DO THIS
}

然后用作:

final isActive: ref.watch(myProvider.notifier).isActive(myItem);

相反,这应该在您的 state class 上:

class Model{
  bool isActive(Item item) => activeItem == item;
}

class MyNotifier extends StateNotifier<Model> {
}

然后用作:

final isActive: ref.watch(myProvider).isActive(myItem);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM