Lưu trữ state và truy cập ở tất cả màn hình trong Flutter Bloc

Bài viết này là 1 ví dụ cụ thể về việc tính toán count số ở 1 màn hình và hiển thị nó ở 1 màn hình khác.

Đầu tiên cần khởi tạo Bloc gồm state và event:

enum CounterEvent { increment, decrement }

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0); //init state = 0

  @override
  Stream<int> mapEventToState(CounterEvent event) async* {
    switch (event) {
      case CounterEvent.increment:
        yield state + 1;
        break;
      case CounterEvent.decrement:
        yield state - 1;
        break;
    }
  }
}

Màn hình 1 hiển thị số count:

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);
    return Scaffold(
      appBar: AppBar(title: Text('First Screen')),
      body: BlocBuilder<CounterBloc, int>(
        builder: (context, count) {
          return Center(
            child: Text(
              '$count',
              style: TextStyle(fontSize: 24.0),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.navigate_next),
        onPressed: () {
          Navigator.of(context).push(
            MaterialPageRoute(
              builder: (_) => SecondScreen(),
            ),
          );
        },
      ),
    );
  }
}

Màn hình 2 cộng số:

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: BlocBuilder<CounterBloc, int>(
        builder: (context, count) {
          return Center(
            child: Text(
              '$count',
              style: TextStyle(fontSize: 24.0),
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          counterBloc.add(CounterEvent.increment);
        },
      ),
    );
  }
}

Để sử dụng bạn cần wrap lại trong 1 BlocProvider

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => CounterBloc(),
      child: MaterialApp(
        title: 'Flutter Demo',
        home: FirstScreen(),
      ),
    );
  }
}

void main() => runApp(MyApp());
Leave a Comment