#flutter #dart
Вопрос:
У меня небольшая проблема с получением информации из блока. Я только начал изучать flutter_bloc из библиотеки блоков, и мне удалось следовать руководству cubit и обновить свой экран, а также наблюдать за изменениями состояния в консоли. Я решил перенести приложение на использование блока вместо cubit и запутался в том, что видел в консоли. Когда происходит изменение состояния или передается событие, я вижу CounterBloc Instance of 'Decrement'
вместо просто Decrement
. Я решил переопределить toString
методы, чтобы показать просто Decrement
, но должен быть лучший способ, верно? Это было не так, когда я использовал локоть.
Это мое контрсобытие.дротик
part of 'counter_bloc.dart'; @immutable abstract class CounterEvent {} class Increment extends CounterEvent { // @override // String toString() =gt; 'Increment'; } class Decrement extends CounterEvent { // @override // String toString() =gt; 'Decrement'; }
counter_state.дротик
part of 'counter_bloc.dart'; @immutable abstract class CounterState { final int counter; const CounterState(this.counter); // @override // String toString() =gt; 'CounterState(counter: $counter)'; } class CounterInitial extends CounterState { const CounterInitial(int counter) : super(counter); }
counter_bloc.дротик
import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; part 'counter_event.dart'; part 'counter_state.dart'; class CounterBloc extends Bloclt;CounterEvent, CounterStategt; { CounterBloc() : super(const CounterInitial(0)) { onlt;Incrementgt;(_onIncrement); onlt;Decrementgt;(_onDecrement); } void _onIncrement(Increment event, Emitterlt;CounterStategt; emit) { emit(CounterInitial(state.counter 1)); } void _onDecrement(Decrement event, Emitterlt;CounterStategt; emit) { emit(CounterInitial(state.counter - 1)); } }
counter_observer.dart
// import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; // import 'package:flutter_counter/bloc/counter_bloc.dart'; // import 'package:flutter_counter/bloc/counter_bloc.dart'; /// {@template counter_observer} /// [BlocObserver] for the counter application which /// observes all state changes. /// {@endtemplate} class CounterObserver extends BlocObserver { @override void onEvent(Bloc bloc, Object? event) { super.onEvent(bloc, event); debugPrint('${bloc.runtimeType} $event'); } @override void onChange(BlocBase bloc, Change change) { super.onChange(bloc, change); debugPrint('${bloc.runtimeType} $change'); } @override void onTransition(Bloc bloc, Transition transition) { super.onTransition(bloc, transition); debugPrint('${bloc.runtimeType} $transition'); } @override void onError(BlocBase bloc, Object error, StackTrace stackTrace) { super.onError(bloc, error, stackTrace); debugPrint('${bloc.runtimeType} $error $stackTrace'); } }
counter_view.dart
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_counter/bloc/counter_bloc.dart'; // import 'package:flutter_counter/counter/counter.dart'; /// {@template counter_view} /// A [StatelessWidget] which reacts to the provided /// [CounterCubit] state and notifies it in response to user input. /// {@endtemplate} class CounterView extends StatelessWidget { const CounterView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final textTheme = Theme.of(context).textTheme; return Scaffold( appBar: AppBar( title: const Text('Counter'), ), body: Center( child: BlocBuilderlt;CounterBloc, CounterStategt;( builder: (context, state) { return Text( '${state.counter}', style: textTheme.headline2, ); }, ), ), floatingActionButton: Column( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, children: lt;Widgetgt;[ FloatingActionButton( key: const Key('counterView_increment_floatingActionButton'), child: const Icon(Icons.add), onPressed: () =gt; context.readlt;CounterBlocgt;().add(Increment()), ), const SizedBox(height: 8), FloatingActionButton( key: const Key('counterView_decrement_floatingActionButton'), child: const Icon(Icons.remove), onPressed: () =gt; context.readlt;CounterBlocgt;().add(Decrement()), ), ], ), ); } }
The cubit I stopped using
import 'package:bloc/bloc.dart'; /// {@template counter_cubit} /// A [Cubit] which manages an [int] as its state. /// {@endtemplate} class CounterCubit extends Cubitlt;intgt; { /// {@macro counter_cubit} CounterCubit() : super(0); /// Add 1 to the current state. void increment() =gt; emit(state 1); /// Subtract 1 from the current state. void decrement() =gt; emit(state - 1); }
main.dart
import 'package:bloc/bloc.dart'; import 'package:flutter/material.dart'; import 'app.dart'; import 'counter_observer.dart'; void main() { Bloc.observer = CounterObserver(); runApp(const CounterApp()); }
Edit: I tried testing after overriding toString
and it looks like this problem is somehow affecting it.
✓ CounterBloc initial state is 0 Expected: CounterInitial:lt;CounterState(counter: 1)gt; Actual: [CounterInitial:CounterState(counter: 1)]
counter_bloc_test.dart
import 'package:bloc_test/bloc_test.dart'; import 'package:flutter_counter/bloc/counter_bloc.dart'; import 'package:test/test.dart'; void main() { group('CounterBloc', () { late CounterBloc counterBloc; setUp(() { counterBloc = CounterBloc(); }); test('initial state is 0', () { expect(counterBloc.state, const CounterInitial(0)); }); blocTest( 'emits [1] when CounterEvent.increment is added', build: () { return counterBloc; }, act: (CounterBloc bloc) { return bloc.add(Increment()); }, expect: () { return const CounterInitial(1); }, ); blocTest( 'emits [-1] when CounterEvent.decrement is added', build: () { return counterBloc; }, act: (CounterBloc bloc) { return bloc.add(Decrement()); }, expect: () { return const CounterInitial(-1); }, ); }); }