[TIL-019] Flutter로 기차 좌석 예매 어플 만들기-1

개요

Flutter의 기본적인 상태 관리를 어떻게 하는지 알고 익숙해지기 위해 기차 좌석 예매 어플을 만들어 보자.

 

기능

  • 사용자의 시스템 테마에 따라 UI의 색상을 변경할 수 있다.
  • 상태 관리를 통해 출발역과 도착역을 선택하여 UI를 동적으로 변경할 수 있다.
  • 상태 관리를 통해 좌석을 선택 및 해제가 가능하며 좌석이 없을 경우에는 예매 버튼이 비활성화된다.
  • Navigator위젯을 통해 라우팅을 할 수 있다.

 

문제 발생

`Navigator`위젯을 통해 메인 페이지, 기차역 리스트 페이지, 좌석 페이지를 이동할 수 있게 됐다.

그러나 가장 중요한 것은 페이지 이동 시, 데이터를 전달하는 방법이다.

 

다음 페이지를 라우팅 할 때 데이터를 전달하는 것은 어렵지 않다.

문제는 이전 페이지로 다시 돌아올 때 데이터를 전달하는 방법과 전달받은 데이터를 어떻게 확인하는 것인지 모르겠다.

 

해결 방법

이전 페이지로 이동 및 데이터를 전달하는 법

// context의 타입은 BuildContext
Navigator.pop(context, data);

 

다음 페이지로부터 전달받은 데이터를 이전 페이지에서 확인하는 방법

GestureDetector(
  onTap: () async {
    var data = await Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) {
          // 페이지 이동 시 데이터를 넘기는 방법2
          // 클래스의 인자로 데이터를 넘길 수 있다.
          return StationListPage(title, stationInfo);
        },
        // 페이지 이동 시 데이터를 넘기는 방법1
        // settings: RouteSettings(arguments: 데이터),
      ),
    );

    // appBar의 뒤로가기 버튼 또는 앞페이지에서 Navigator.pop을 했을 경우 동작
    if (data != null) {
      onChangeStation(start: data['start'], end: data['end']);
    }
  },
  child: Text(
    station ?? '선택',
    style: TextStyle(
      fontSize: 40,
      color: Theme.of(context).dividerColor,
    ),
  ),
)
  • 다음 페이지으로 이동하기 위해 `Navigator.push`를 사용하지만 여기에서 다음 페이지가 전달 해준 데이터를 받을 수 있다.
  • `await`키워드를 `Navigator.push`에 사용하고 상위 함수에 `async`키워드를 사용하면 된다.
  • `await Navigator.push`가 자동으로 동작하는 경우는 아래와 같다.
    • 다음 페이지에서 appBar의 뒤로가기 버튼을 터치할 경우 → `var data = null`이 된다.
    • 다음 페이지에서 `Navigator.pop`을 했을 경우  `await Navigator.push`의 반환 값이 다음 페이지가 전달 해준 데이터가 된다.
  • `await`키워드를 사용했다는 것은 `Navigator.push`의 반환 타입이 `Future`임을 알 수 있다.
  • 그러므로 `await`키워드 대신 `then`을 사용해도 된다.
GestureDetector(
  onTap: () {
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (context) {
          // 페이지 이동 시 데이터를 넘기는 방법2
          // 클래스의 인자로 데이터를 넘길 수 있다.
          return StationListPage(title, stationInfo);
        },
        // 페이지 이동 시 데이터를 넘기는 방법1
        // settings: RouteSettings(arguments: 데이터),
      ),
    ).then((data){
      // appBar의 뒤로가기 버튼 또는 앞페이지에서 Navigator.pop을 했을 경우 동작
      if (data != null) {
        onChangeStation(start: data['start'], end: data['end']);
      }
    });
  },
  child: Text(
    station ?? '선택',
    style: TextStyle(
      fontSize: 40,
      color: Theme.of(context).dividerColor,
    ),
  ),
)