본문 바로가기

Flutter/12 Clone 'Used Goods app'

[Flutter] Clone - 당근마켓14(pageController with provider)

이번시간에는 PageController 를 Provider 로 구현해보겠습니다.

지난번에 인자로 전달하는 방식으로 했던 부분을 Provider 로 변경하는 것입니다.

개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1

 

 

 

수정할 파일 리스트는 아래와 같습니다.

 

main.dart - 아래 옵션을 추가해야 한다

 

void main() {
  // start_screen 에서 provider 를 사용하는데, 값을 변경하는게 아니고 사용만
  // 컨트롤러 자체만 사용 하는 경우는 아래 처럼 확실하게 컴파일러에게 알려줘야 한다
  Provider.debugCheckInvalidValueType = null;
  runApp(const MyApp());
}

 

 

./src/screens/start_screen.dart - 2가지 다 테스트해보고 차이점이 있는지 확인해 봅시다

결론 - 2번째만 가능, 이유는 PageView 에서도 같은 컨트롤러를 사용해야 하기 때문입니다

 

class StartScreen extends StatelessWidget {
  StartScreen({Key? key}) : super(key: key);

  // ~Controller() 끝나는 변수들은 항상 dispose 해야 한다
  // 단, StatelessWidget 에서는 제외
  final PageController _pageController = PageController();

  @override
  Widget build(BuildContext context) {
    // 일반적으로 Provider 를 잘 사용하지 않지만
    // 여기선 하위 페이지들에게 적용하기 위해서 변수를 전달하는 것 보단
    // Provider 로 처리하는게 더 좋아서 적용함
    // 2가지 방법중 첫째는
    // return Provider<PageController>(
    //     create: (context) => PageController(),
    // 2가지 방법중 두번째는
    // return Provider<PageController>.value(
    //     value: _pageController,
    // 상황에 맞게 처리하면 된다다
    return Provider<PageController>.value(
      value: _pageController,
      child: Scaffold(
        body: PageView(
          controller: _pageController,
          // 이부분이 활성화 되면 사용자가 화면을 좌/우로 스크롤하지 못하게 설정 가능
          // physics: const NeverScrollableScrollPhysics(),
          children: const <Widget>[
            IntroPage(),
            AddressPage(),
            AuthPage(),
          ],
        ),
      ),
    );
  }
}

 

 

./src/screens/address_page.dart

 

  _saveAddressOnSharedPreference(String address, num lat, num lon) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    debugPrint('save Address: $address.');
    await prefs.setString(SHARED_ADDRESS, address);
    await prefs.setDouble(SHARED_LAT, lat.toDouble());
    await prefs.setDouble(SHARED_LON, lon.toDouble());
  }

// Provider 추가로 함수 추가
  _saveAddressAndGoToNextPage(String address, num lat, num lon) async {
    await _saveAddressOnSharedPreference(address, lat, lon);
    // "flutter do not use build contexts across async gaps"
    // 상기 경고가 나와서 mounted 조건을 추가함
    if (!mounted) return;
    context.read<PageController>().animateToPage(2,
        duration: const Duration(milliseconds: 500), curve: Curves.ease);
  }
  
  
// 함수 데체  
// _saveAddressOnSharedPreference(
_saveAddressAndGoToNextPage(

 

 

./src/screens/intro_page.dart - 인자 전달 변경 전/후

 

class IntroPage extends StatelessWidget {
  // final PageController pageController;
final PageController pageController;
  
  // const IntroPage({Key? key, required this.pageController}) : super(key: key);
  const IntroPage({Key? key}) : super(key: key);