티스토리 뷰

반응형

플러터의 상태 관리 패키지인 Provider에서 제공하는 ChangeNotifierProvider와 Navgator로 화면 이동한 후에 상태 변화를 확인하기 위해 예제 코드를 만들어 보았다.

 

다음 이미지처럼 FirstPage에서 SecondPage로 이동하고, SecondPage에서 상태를 변화시켜도 FirstPage에 구독한 상태가 잘 변경되는 것을 확인할 수 있다.

 

 

 

 

FirstPage와 SecondPage가 StatelessWidget인 것을 주목하자. ChangeNotifierProvider로 상태가 공유되기 때문에 상태 변화시 자동으로 위젯이 리빌드 되기 때문에 StatefulWidget처럼 작동하게 된다.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class Counter extends ChangeNotifier {
  int value = 0;

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

void main() {
  runApp(
    MultiProvider(
        providers: [
          ChangeNotifierProvider<Counter>.value(value: Counter()),
        ],
        child: const MaterialApp(
          home: FirstPage(),
        )),
  );
}

class FirstPage extends StatelessWidget {
  const FirstPage({super.key});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("First Page")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Selector<Counter, int>(
              selector: (context, counter) => counter.value,
              builder: (context, value, child) {
                return Text("$value");
              },
            ),
            ElevatedButton(
                onPressed: () {
                  Navigator.of(context).push(
                      MaterialPageRoute(builder: (context) => const SecondPage()));
                },
                child: const Text("Go Next")),
          ],
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Second Page"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("${Provider.of<Counter>(context).value}"),
            ElevatedButton(
                onPressed: () {
                  Provider.of<Counter>(context, listen: false).increment();
                },
                child: const Text("Count up")),
          ],
        ),
      ),
    );
  }
}
반응형
댓글
공지사항