如何使用 bloc pacakage 在 flutter 中更改列表项中的小部件。我应该在整个 ListView.builder 上使用 BlockBuilder 还是监听器,还是只在单个项目上使用。如果您分享示例或教程,那就太好了。例如,如果我有一个复选框,我需要在单击它时更改其状态。这些是我的 Bloc 课程 Bloc
const String SERVER_FAILURE_MESSAGE = 'Server Failure';
const String CACHE_FAILURE_MESSAGE = 'Cache Failure';
class MarkAttendanceBloc extends Bloc<MarkAttendanceEvent, MarkAttendanceState> {
final MarkStudentPresent markStudentPresent;
final MarkStudentAbsent markStudentAbsent;
MarkAttendanceBloc({@required this.markStudentPresent,@required this.markStudentAbsent});
@override
MarkAttendanceState get initialState => MarkedInitial();
@override
Stream<MarkAttendanceState> mapEventToState(MarkAttendanceEvent event) async* {
yield MarkedLoading();
if(event is MarkAbsentEvent){
final remotelyReceived = await markStudentAbsent(MarkStudentParams(classId: event.classId, courseId: event.courseId,studentId: event.studentId));
yield* _eitherLoadedOrErrorState(remotelyReceived);
}
else if(event is MarkPresentEvent){
final remotelyReceived = await markStudentPresent(MarkStudentParams(classId: event.classId, courseId: …Run Code Online (Sandbox Code Playgroud) 我包裹我的脚手架,dart BlocProvider<ABloc,AState>
但是当我使用showDialog func 和showDialog时,我想从上下文访问 ABloc 或者BlocBuilder
不包含 bloc 并抛出错误,有没有办法在这种情况下访问 bloc (在我的对话框中,我显示提交的文本以获取用户名,所以我想访问 bloc)
class MyHomePageState extends StateLessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
lazy: false,
create: (context) => EditColorBloc(context.bloc<RetrieveColorBloc>()),
child: MainScafold());
}
}
Run Code Online (Sandbox Code Playgroud)
class MainScafold extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("sina"),
),
floatingActionButton:FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => showDialog(
context: context,
builder: (ctx) {
// show dialog and use
// context o BlocBuilder to …Run Code Online (Sandbox Code Playgroud) UPDATE找到 onChange 覆盖方法后,似乎没有发出更新的状态 #confused
更新 2进一步调试显示,当更新的状态尝试发出时,StreamController 似乎已关闭。
出于某种原因,我的应用程序中的 1 个 BlocBuilders 在 Cubit 发射后拒绝重绘,并且在我的一生中我无法弄清楚为什么,运行或调试时没有错误,状态数据正在更新并传递到发射中。
目前,它是一个钩子小部件,但我已经尝试将其设置为无状态、有状态,在 context.bloc 上调用 cubit 方法。
我试过让它成为消费者,没有任何东西让它进入监听,甚至尝试搞乱 listenWhen 和 buildWhen 并且没有任何迹象表明为什么这不是构建。
它呈现加载状态,这就是它结束的地方。
小部件:
class LandingView extends HookWidget {
@override
Widget build(BuildContext context) {
final hasError = useState<bool>(false);
return Scaffold(
key: const Key(LANDING_VIEW_KEY),
body: BlocProvider<CoreCubit>(
create: (_) => sl<CoreCubit>()..fetchDomainOptions(),
child: BlocBuilder<CoreCubit, CoreState>(
builder: (context, state) {
switch (state.status) {
case CoreStatus.loaded:
return LandingViewLoaded();
case CoreStatus.error:
return LandingViewError();
case CoreStatus.loading:
default:
return AppIcon();
}
},
), …Run Code Online (Sandbox Code Playgroud) 我有一个标签视图,其中有热门、最近和即将推出的类别。他们在 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) 在Dart,我理解super这样的工作原理:
class Foo {
Foo(int a, int b) {
//Code of constructor
}
}
class Bar extends Foo {
Bar(int a, int b) : super(a, b);
}
Run Code Online (Sandbox Code Playgroud)
我真的不明白在 的(或)类super中使用时发生了什么。cubitblocsflutter_bloc
例如,我不明白CounterCubit类何时扩展Cubit:CounterCubit extends Cubit<CounterState>并且该类CounterState可以用作cubit.
class CounterState {
int counterValue;
CounterState({@required this.counterValue});
}
class CounterCubit extends Cubit<CounterState> {
CounterCubit() : super(CounterState(counterValue: 0));
}
Run Code Online (Sandbox Code Playgroud) 我想将初始状态设置为使用shared_preferences持久保存的值。该值是我的应用程序的语言,我在 main.dart 文件中使用state.language.
import 'storageUtils.dart';
class LanguageState {
//TODO: set initial language to language stored with shared_preference
LanguageState({this.language = LanguagePreference.getLanguage()});
final String language;
LanguageState copyWith({
String? language,
}) {
return LanguageState(language: language ?? this.language);
}
}
Run Code Online (Sandbox Code Playgroud)
这些是我storageUtils.dart用来更改和获取语言的:
class LanguagePreference {
static late SharedPreferences _preferences;
static Future init() async =>
_preferences = await SharedPreferences.getInstance();
static Future changeLanguage(String language) async =>
await _preferences.setString("language", language);
static String getLanguage() => _preferences.getString("language") ?? "en";
}
Run Code Online (Sandbox Code Playgroud)
但由于 getLanguage 函数不是常量,我无法使用 getLanguage 函数的动态值初始化状态。是否有另一种方法可以用函数的动态值初始化语言状态 …
当我们使用访问 Bloc 对象时,如果当前上下文的祖先小部件BlocProvider.of<OrderBloc>(context)不存在,它将返回异常。OrderBloc返回的异常如下:
No ancestor could be found starting from the context that was passed to BlocProvider.of<OrderBloc>().
Run Code Online (Sandbox Code Playgroud)
但当祖先小部件上不存在时,我希望返回null而不是异常。OrderBloc考虑以下场景:
var orderBloc = BlocProvider.of<OrderBloc>(context);
return Container(child: orderBloc == null
? Text('-')
: BlocBuilder<OrderBloc, OrderState>(
bloc: orderBloc,
builder: (context, state) {
// build something if orderBloc exists.
},
),
);
Run Code Online (Sandbox Code Playgroud) void main() async {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => LanguageCubit(),
child: BlocBuilder<LanguageCubit, Locale>(builder: (context, lang) {
return MaterialApp(
locale: lang,
title: 'Localizations Sample App',
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('en', ''), // English, no country code
const Locale('es', ''), // Spanish, no country code
const Locale('tr', ''),
const Locale('it', ''),
],
home: Home(),
);
}),
);
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试 flutter,并且在 github 上提出了许多项目,这些项目声明了存储库并将它们传递给 UI 端的块。为什么这是正确的方法而不是在后端(在集团上)?
例子:
class MyApp extends StatelessWidget {
final authenticationRepository = AuthenticationRepository();
final accountRepository = AccountRepository();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
debugShowCheckedModeBanner: false,
home: MultiRepositoryProvider(
providers: [
RepositoryProvider(create: (_) => authenticationRepository),
RepositoryProvider(create: (_) => accountRepository),
],
child: BlocProvider(
create: (_) => AuthenticationBloc(
authenticationRepository: authenticationRepository,
accountRepository: accountRepository,
),
child: Container(); // I removed the content here
),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢
我正在构建一个登录页面,并且已经创建了打算用作完全动态 TextField 小部件的内容。
我现在需要创建该小部件的 2 个实例(电子邮件和密码输入)并发送hintText、errorText 的参数,然后发送我的LoginBloc 和验证方法,这些参数对于每个输入当然是不同的。
我的问题是 Dart 不允许我使用小部件接收的块作为类型,因此代码不起作用。
我可以做什么来解决这个问题?或者我完全做错了,有更好的方法吗?
登录页面:
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 50),
child: Text(
AppLocalizations.of(context).initiateSession,
style: Theme.of(context).textTheme.headline6,
),
),
BlocProvider(
create: (context) {
return LoginBloc();
},
child: BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
if (state.status.isSubmissionFailure) {
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(
const SnackBar(
content: Text('Authentication Failure')),
);
}
},
child: Align(
alignment: …Run Code Online (Sandbox Code Playgroud)