티스토리 뷰

플러터의 상태 관리 패키지인 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")),
          ],
        ),
      ),
    );
  }
}
댓글
공지사항