Flutter - 내비게이션 이해하기(3)

유의선·2024년 3월 21일
0

Flutter의 내비게이션 기능을 이용하여 페이지에 데이터를 전달하는 방법에 대해 알아보았다.

할 일 을 기록하는 앱을 만들어보며 알아보았다.

이전의 코드에서 이어서 작성하였다.


_SubDetail 클래스에 List를 선언하고 기본 내용을 추가했다.

class _SubDetail extends State<SubDetail>{
  List<String> todoList = new List.empty(growable: true);

  
  void initState() {
    super.initState();
    
    todoList.add(('Flutter 공부하기'));
    todoList.add(('코딩 테스트 풀기'));
    todoList.add(('면접 예상질문 추가하기'));
    todoList.add(('면접 예상질문 복습하기'));
    todoList.add(('앱 개발하기'));
  }

그 후 Scaffold에 ListView를 만들어 표시한다.

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Sub Detail Example'),
        ),
        body: ListView.builder(
          itemBuilder: (context, index) {
            return Card(
              child: InkWell(
                child: Text(
                  todoList[index],
                  style: TextStyle(fontSize: 30),
                ),
                onTap: () {
                  Navigator.of(context)
                      .pushNamed('/third', arguments: todoList[index]);
                },
              ),
            );
          },
          itemCount: todoList.length,
        ));
  }

리스트뷰에 todoList의 내용을 보여주는 기능을 구현했다.

InkWell 위젯은 탭, 더블탭, 롱탭 등 다양한 터치 이벤트를 처리할 수 있는 위젯이다.
onTap() 이벤트 처리 함수에 내비게이션을 이용해 스택에 페이지를 추가한다.

이 때 arguments 를 추가했는데 이는 첫 번재 인자로 지정한 경로에 이 데이터를 전달하게된다.


ThirdDetail 클래스에서 데이트를 받아 처리하는 코드를 작성했다.

  
  Widget build(BuildContext context) {
    final String args = ModalRoute.of(context)!.settings.arguments.toString();
    
    return Scaffold(
      appBar: AppBar(title: Text('Third Page'),),
      body: Container(
        child: Center(
          child: Text(
            args,
            style: TextStyle(fontSize: 30),
          )
        ),
      ),
    );
  }

args 변수에 ModalRoute.of(context)!.settings.arguments.toString() 코드로 라우터로 전달받은 arguments 값을 받는다.

그 후 텍스트 위젯에 이 값을 출력한다.


할 일 목록에 데이터를 추가하는 기능을 만들어보았다.
이 기능을 첫 번째 페이지의 Floating Button을 누르면 동작하도록 구현하였다.

subDetail.dart에 두 번째 페이지로 이동하고 반환하는 값을 저장해 할 일 목록에 추가하는 _addNavigation() 함수를 정의했다.
이 함수는 데이터를 받은 다음에 처리해야 하므로 비동기 방식으로 구현하였다.

class _SubDetail extends State<SubDetail> {

	...
  
  void _addNavigation(BuildContext context) async {
    final result = await Navigator.of(context).pushNamed('/second');
    setState(() {
      todoList.add(result as String);
    });
  }
}

pushNamed() 함수로 받아온 반환값을 result에 저장한다.

이 때 pushNamed() 함수 호출문 앞에 await 키워드를 붙여 이 함수가 끝날 때까지 기다린다.

floatingActionButton의 이벤트 처리 함수 onPressed에서 지금 만든 _addNavigation() 함수를 호출한다.

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar( ... ),
      body: ListView.builder( ... ),
      
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _addNavigation(context);
        },
        child: Icon(Icons.add),
      ),
    );
  }

SecondDetail 클래스를 수정하였다.
할 일을 입력하는 텍스트필드와 버튼을 추가하였다.
텍스트필드에 할 일을 입력한 후 버튼을 누르면 데이터를 전달한 후 현재 화면을 종료한다.

  
  Widget build(BuildContext context) {
    TextEditingController controller = new TextEditingController();

    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Container(
        child: Center(
          child: Column(
            children: <Widget>[
              TextField(
                controller: controller,
                keyboardType: TextInputType.text,
              ),
              ElevatedButton(
                  onPressed: () {
                    Navigator.of(context).pop(controller.value.text);
                  },
                  child: Text('저장하기'))
            ],
          ),
        ),
      ),
    );
  }

pop() 함수에 종료할 때 전달할 데이터를 입력하였다.

0개의 댓글