上下文:这里的页面可以TabView在所有这些选项卡使用的选项卡之间导航flutter_bloc(版本 6.0.1)。
问题:当滑动到任何选项卡时,状态不会被保留,整个小部件树正在重建,如下面的 gif 所示
这是build()方法:
@override
Widget build(BuildContext context) {
super.build(context);
return DefaultTabController(
initialIndex: 0,
length: 3,
child: Scaffold(
backgroundColor: Colors.white,
appBar: _buildAppBarWithTabs(),
body: TabBarView(
children: <Widget>[
defaultViewforCategory(1), //Women
defaultViewforCategory(3), //Men
defaultViewforCategory(2), //Kids
],
),
),
);
}
Run Code Online (Sandbox Code Playgroud)
下面是函数的实现 defaultViewforCategory()
Widget defaultViewforCategory(int mainCategoryId) {
return PageStorage(
bucket: bucket,
key: PageStorageKey(mainCategoryId),
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 1200),
child: ListView(
scrollDirection: Axis.vertical,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 150),
child: Container(
height: 800,
child: …Run Code Online (Sandbox Code Playgroud) 我有一个听另一个集团的集团。将flutter_bloc包更新为 后version 6.0.2,侦听器在初始状态下将不再调用。
class BlocA extends Bloc {
final BlocB blocB = ...;
...
blocA.blocB.listen((state) {
DO SOMTTHING...
});
...
}
Run Code Online (Sandbox Code Playgroud)
我找到了这个解决方案:
class BlocB extends Bloc<..., ...> with BehaviorSubjectBloc {
...
}
mixin BehaviorSubjectBloc<TEvent, TState> on Bloc<TEvent, TState> {
@override
StreamSubscription<TState> listen(
void Function(TState state) onData, {
Function onError,
void Function() onDone,
bool cancelOnError,
}) {
onData(this.state);
return super.listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
);
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道有没有更好的解决方案?
为什么当我们需要使用带有 flutter_bloc 的 Equatable 类时?,还有我们需要的道具呢?这是在颤振中以块模式创建状态的示例代码,请我需要详细的答案。先感谢您
abstract class LoginStates extends Equatable{}
class LoginInitialState extends LoginStates{
@override
List<Object> get props => [];
}
Run Code Online (Sandbox Code Playgroud) 所以,我在Cubit类中做了一个函数,它是从API获取数据。现在,如果我按下按钮,我就可以获得数据。我想让该函数在页面/屏幕打开时自动调用。供您参考,此页面是用户打开应用程序时将启动的第一个页面。这是我的一些代码。
class UsersCubit extends Cubit<UsersState> {
UsersCubit() : super(UsersInitial());
UserRepository _userRepository = UserRepository();
void getAllUsers() async{
emit(UsersLoading());
try{
ResponseUsers _data = await _userRepository.getUsers();
emit(UsersSuccess(_data));
} catch(e){
emit(UsersError(e.toString()));
}
}
}
Run Code Online (Sandbox Code Playgroud)
class UsersPage extends StatefulWidget {
const UsersPage({Key? key}) : super(key: key);
@override
_UsersPageState createState() => _UsersPageState();
}
class _UsersPageState extends State<UsersPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Users")),
body: BlocProvider(
create: (context) => UsersCubit(),
child: BlocConsumer<UsersCubit, UsersState>(
listener: (context, state) {
if(state is UsersLoading){
print("getting users …Run Code Online (Sandbox Code Playgroud) 我正在开发一个使用肘节来管理状态的应用程序。很多时候,当我需要发出 API 请求时,我需要获取当前的本地化信息(处理可能的异常),然后将其发送到后端。所以我想我应该使用肘来请求并获取当前的本地化。
我的问题是我应该如何处理?我可以gpsLocalizationCubit从另一肘处打电话吗?我应该使用 bloc 侦听器进行调用gpsLocalizationCubit并成功调用吗?requestCubit但是,那么我应该如何管理对于获取本地化和 API 请求都应该可见的加载屏幕呢?另一个问题是我在单个视图中有多个类似的请求(需要使用当前本地化)。
我的 Bloc 状态没有更新,我发现问题可能是Map<String, Map<String, String>未正确比较的属性。如果我错了,请纠正我,但状态会在其他属性更改时更新,而不是在imageUrls属性更新时更新。
这些是我的状态对象
abstract class PropertiesState extends Equatable {
const PropertiesState();
}
class PropertiesLoaded extends PropertiesState {
final int count;
final List<Property> properties;
final Map<String, Map<String, String>> imageUrls;
const PropertiesLoaded({
this.count,
this.properties,
this.imageUrls,
});
@override
List<Object> get props => [count, properties, imageUrls];
}
Run Code Online (Sandbox Code Playgroud)
imageUrls 字段可以有任何字符串键/值对。我无法找到有关如何执行此操作的任何信息。
谢谢您的帮助!
我有一个标签视图,其中有热门、最近和即将推出的类别。他们在 api 上都有相同的响应。我正在尝试使用 flutter_bloc 从 api 获取数据。之前我使用 rxdart 主题,并为每种类型的数据创建了一个主题。现在使用 flutter bloc 我想实现同样的目标。我想做的是在选项卡之间切换。以前我使用behaviorsubject 将数据保存到下一个事件,但现在我想过渡到块模式。如何使用 flutter_bloc 获得相同类型的结果?或者我需要为每种类型创建块?最后,如何从 api 获取数据,以便在切换选项卡时保持状态?我的 Rxdart 实现:
class DataBloc {
final DataRepo _repository = DataRepo();
final BehaviorSubject<Data> _recent = BehaviorSubject<Data>();
final BehaviorSubject<Data> _popular = BehaviorSubject<Data>();
final BehaviorSubject<Data> _upcoming = BehaviorSubject<Data>();
getData(String type) async {
Data response = await _repository.getData(type);
if (type == "recent") {
_recent.sink.add(response);
} else if (type == "upcoming") {
_upcoming.sink.add(response);
} else {
_popular.sink.add(response);
}
}
dispose() {
_recent?.close();
_popular?.close();
_upcoming?.close();
}
BehaviorSubject<Data> get recent …Run Code Online (Sandbox Code Playgroud) 我有一个集团层次结构,在子集团中mapEvenToState我使用了super.mapEventToState. 在 bloc 包的较新版本中,mapEventToState已弃用。
我应该用什么来代替super.mapEventToState?我知道on<Event>,但是相当于什么super.mapEventToState?
我正在使用flutter_bloc包。如果我有一个状态是小部件列表的块,这是一个不好的做法吗?我使用这个块从列表中推送(添加)和弹出(删除)小部件/迷你屏幕。我将此列表用作弹出菜单的主体,其中有类似嵌入式导航的内容。列表的最后一个成员是显示在弹出窗口中的小部件。
每次我按下或弹出时,我都会发出一个新的状态。该块很有用,因为这样我就可以从弹出窗口中显示的小部件/迷你屏幕中的任何位置调用推送或弹出。如果我的用例很清楚或者您需要更多详细信息,请告诉我。谢谢。
以下是相关代码片段:
自定义堆栈(其中E类型为Widget):
class PopoverStack<E> {
PopoverStack() : _storage = <E>[];
final List<E> _storage;
void push(E element) {
_storage.add(element);
}
void pop() {
_storage.removeLast();
}
E get last => _storage.last;
bool get isEmpty => _storage.isEmpty;
bool get isNotEmpty => !isEmpty;
PopoverStack.of(PopoverStack<E> stack) : _storage = List<E>.of(stack._storage);
}
Run Code Online (Sandbox Code Playgroud)
Bloc for stack(PopoverPage是一个抽象类小部件将扩展):
class PopoverCardStackBloc extends Cubit<PopoverStack<PopoverPage>> {
PopoverCardStackBloc(PopoverStack<PopoverPage> popoverStack) : super(popoverStack);
void push(PopoverPage element) {
emit(PopoverStack.of(state..push(element)));
}
void pop() {
emit(PopoverStack.of(state..pop()));
}
} …Run Code Online (Sandbox Code Playgroud) 使用 flutter_bloc 和 go_router 实现基于身份验证更改的导航。
我需要做的是,如果用户经过身份验证,则应将其重定向到主屏幕,并能够导航身份验证流程...(HomeScreen,TestScreen1,TestScreen2)
如果用户在任何时候未经身份验证,则应将其重定向到登录屏幕,如果未知,则应重定向到启动屏幕。
我已经解决了许多 stackoverflow 问题和 github 问题,但没有一个提供我们如何实现这一目标的最佳实践。
问题:
提供以下资产:
Tried to listen to a value exposed with provider, from outside of the widget tree.
This is likely caused by an event handler (like a button's onPressed) that called
Provider.of without passing `listen: false`.
To fix, write:
Provider.of<$T>(context, listen: false);
It is unsupported because may pointlessly rebuild the widget associated to the
event handler, when the widget tree …Run Code Online (Sandbox Code Playgroud)