Riverpod StateNotifier 不适用于悬停逻辑
Posted
技术标签:
【中文标题】Riverpod StateNotifier 不适用于悬停逻辑【英文标题】:Riverpod StateNotifier not working with hover logic 【发布时间】: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 中。请让我知道如何解决这个问题。提前致谢!
【问题讨论】:
【参考方案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) => hoverItem == item
,对吗?以上是关于Riverpod StateNotifier 不适用于悬停逻辑的主要内容,如果未能解决你的问题,请参考以下文章
如何覆盖 Riverpod StateNotifier 的状态以进行测试
实施 ChangeNotifier 与 StateNotifier