Когда предоставлять блок в BlocBuilder()?

#flutter #bloc #flutter-bloc

Вопрос:

Я пытаюсь использовать cubit для приложения flutter counter. Я хотел знать, когда следует указать блок/локоть для параметра блока в BlocBuilder(). Я попытался предоставить его для приведенного ниже кода, но он не сработал и получил ошибку :

 Error: Could not find the correct Provider<CounterCubit> above this CounterPage Widget
 

.

 class CounterPage extends StatelessWidget {
  const CounterPage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        centerTitle: true,
      ),
      body: BlocBuilder<CounterCubit, int>(
          bloc: CounterCubit(),
          builder: (_, count) => Center(
                child: Text('$count'),
              )),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: FloatingActionButton(
              onPressed: () => context.read<CounterCubit>().increment(),
              tooltip: 'Increment',
              child: Icon(Icons.add),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: FloatingActionButton(
              onPressed: () => context.read<CounterCubit>().decrement(),
              tooltip: 'Decrement',
              child: Icon(Icons.remove),
            ),
          ),
        ],
      ),
    );
  }
}
 

Это код для cubit.

 import 'package:flutter_bloc/flutter_bloc.dart';

class CounterCubit extends Cubit<int> {
  CounterCubit() : super(0);

  void increment() => emit(state   1);
  void decrement() => emit(state - 1);
}
 

Ответ №1:

Из официальной документации:

Укажите блок только в том случае, если вы хотите предоставить блок, который будет ограничен одним виджетом и недоступен через родительский поставщик блоков и текущий контекст сборки.

 BlocBuilder<BlocA, BlocAState>(
  bloc: blocA, // provide the local bloc instance
  builder: (context, state) {
    // return widget here based on BlocA's state
  }
)
 

В вашем случае я бы рекомендовал указать ваш блок в дереве виджетов где-нибудь выше CounterPage , например так:

 BlocProvider<CounterCubit>(
  create: (BuildContext context) => CounterCubit(),
  child: CounterPage(),
);
 

Тогда внутри BlocBuilder , вам не нужно будет указывать bloc свойство:

 ...
body: BlocBuilder<CounterCubit, int>(
  builder: (_, count) => Center(
    child: Text('$count'),
  )),
...
 

Комментарии:

1. Я не понял «укажите блок только в том случае, если вы хотите предоставить блок, который будет ограничен одним виджетом и недоступен через родительский поставщик блоков и текущий контекст сборки». Когда мы можем использовать свойство bloc?

2. Так, например, внутри метода build() мы можем получить блок, подобный final bloc = context.watch<YourBloc>() , а затем передать его BlocBuilder. Технически это рабочее решение, но я никогда не использовал его таким образом.