【问题标题】:Riverpod StateNotifier not working with hover logicRiverpod StateNotifier 不适用于悬停逻辑
【发布时间】:2022-01-17 10:28:14
【问题描述】:

我正在尝试使用 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 逻辑似乎不工作。每次我将鼠标悬停在导航栏元素上时,它似乎都在更新状态,即为我的 NavigationControllerElement 对象设置 hoverItem 但它不会反映在 UI 中。请让我知道如何解决这个问题。提前致谢!

【问题讨论】:

    标签: flutter dart state riverpod


    【解决方案1】:

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

    特别是,您做错了什么是在 StateNotifier 上添加 getter/methods 以供 UI 使用:

    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);
    

    相反,这应该在您的状态类中:

    class Model{
      bool isActive(Item item) => activeItem == item;
    }
    
    class MyNotifier extends StateNotifier<Model> {
    }
    

    然后用作:

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

    【讨论】:

    • 所以如果我想将它应用到 hoverItem,我只需添加一个函数 bool isActive(Item item) =&gt; hoverItem == item,对吗?
    猜你喜欢
    • 2021-04-21
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 2011-09-10
    • 2016-02-15
    相关资源
    最近更新 更多