본문 바로가기
📱Mobile/🔥Flutter

[Flutter] provider + [Change Notifier] 를 사용한 Provider Pattern example

by 후누스 토르발즈 2021. 1. 6.
반응형

 

https://pub.dev/packages/flutter_bloc

 

이때까지 다양한 BLOC 패턴으로 코드를 작성해보았다. 

하지만 BLOC의 로직 분할을 위한 다수의 클래스 생성으로 인해 복잡성 문제가 있기 때문에 2019년 Google에서 적극 추천한 Provider Pattern을 사용해보도록 하겠다.

구글에서 만든것은 아니고 커뮤니티에서 올라온것이라는데 구글에서 적극 추천을 한 것이라고 한다.

또한 BLOC가 다수의 클래스로 복잡하기 때문에 아에 쓰지 않는것은 아니다.

어느정도 규모가 있는 프로젝트는 BLOC패턴을 사용하여 정확한 로직분리를 하는것이 분명히 더 좋을것으로 보인다.

 

소규모에 Provider, 중규모에 Provider, Bloc, 대규모에 Bloc 가 맞지 않을까 싶다.

 

 

provider package

 

트리이다.

 

 

 

main.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_provider/count/counter.dart';
import 'package:provider/provider.dart';
import 'count/count.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Counter()),
      ],
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    print('MyHomePage build');
    return Scaffold(
      appBar: AppBar(
        title: const Text('Example'),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: const <Widget>[
            Text('You have pushed the button this many times:'),
            Count(),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => context.read<Counter>().increment(),
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}


 

 

count.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_provider/count/counter.dart';
import 'package:provider/provider.dart';

class Count extends StatelessWidget {
  const Count({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text(
        '${context.watch<Counter>().count}', style: Theme.of(context).textTheme.headline4);
  }
}

 

counter.dart

import 'package:flutter/cupertino.dart';

class Counter with ChangeNotifier {
  int _count = 0;

  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

 

 

 

 

floatingActionButton 클릭하면 Counter를 읽어드리고 increment 함수를 실행한다.

 

그럼 Counter 에서 

Counter

실행하여 notifyListeners(); 를 실행하게된다.

 

그럼 최상위에서 MultiProvider에 넣어놨던 providers: [] 안의 ChangeNotifierProvider에 알려주게된다.

그럼 그 값이 바뀌고 Count(위젯) 에서 watch 하고있기 때문에 바로 값이 바뀌게 된다.

 

작성하면서 주의할점은 const를 빼먹지말것, context.watch 나 read 에서 가끔 import 목록이 안뜨는 경우가 있는데 그럴땐 직접 import 'package:provider/provider.dart'; 해줘야한다.

 

그림상으로 보면 최상위 runApp() 에서 바로 MultiProvider() 로 감쌌기 때문에 모든 자식 위젯들이 접근할 수 있다.

 

 

반응형