목차

  1. 사용된 기능 설명
  2. 사용 예시

 

 

 

✅ 사용된 기능 설명

  • ModalRoute : 현재 화면(Route)에 대한 정보를 담고 있는 클래스
  • Route : Flutter에서 한 화면(Page)을 의미
  • .of(context) : 위젯 트리에서 특정 상위 객체를 찾아 가져오는 패턴
  • ! : Non-null assertion operator 또는 non-null 단언 연산자. null 아님을 확신하고 컴파일러에게 알려주는 연산자
    ** 실제 값이 null 일 경우, 런타임 에러
    ** nullable 타입(T?) → non-nullable(T)로 강제로 변환
    • not의 의미인 논리 부정 연산자(!) 와는 다름
      • bool 변수나 조건문 안에서 쓰이면 → 논리 부정 연산자 (ex. if(!true){...})
      • nullable 타입 뒤에 붙으면 → non-null 단언 연산자 (ex. name!.length)
  • .settings.arguments : Navigator로 전달한 arguments 데이터 접근
  • pop() : 뒤로가기
  • initialRoute : 초기의 루트를 어떻게 할지 설정
  • GlobalKey : 위젯 트리 어디서든 해당 위젯의 상태에 접근할 수 있게 해주는 키(주로 Form, Scaffold 위젯 상태 관리에 사용)
  • TextFormField : 텍스트 입력 위젯 (Form 내에서 validator를 통해 입력값 검증 가능)
    • autofocus : 화면이 열릴 때 자동으로 포커스
    • validator : 입력값 유효성 검사
    • onSave : 입력값 저장할 때 호출

 

 

✅ 사용 예시

 

1️⃣ Model 작성

 

 

2️⃣ 두 번째 페이지(제출 성공 시 호출)

 

 

3️⃣ Main.dart

  1. Route 설정
  2. 전역 변수와 Scaffold 작성
  3. username 입력 받는 박스
  4. email 입력 받는 박스
  5. 제출 버튼

1. Route 설정
2. 전역 변수와 Scaffold 작성
3. username 입력 받는 박스
4. email 입력 받는 박스
5. 제출 버튼

 

 

4️⃣ 테스트

 

 

 

 

 

 

 

 

✔️ 사용된 코드

1️⃣ Model

class User{
  final String username;
  final String email;

  User(this.username, this.email);
}

 

2️⃣ 두 번째 페이지

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';
import 'package:프로젝트명/user.dart';

class SuccessPage extends StatefulWidget {
  const SuccessPage({super.key});

  @override
  State<SuccessPage> createState() => _SuccessPageState();
}

class _SuccessPageState extends State<SuccessPage> {
  @override
  Widget build(BuildContext context) {
    // ModalRoute : 현재 화면(Route)에 대한 정보를 담고 있는 클래스
    // Route : Flutter에서 한 화면(Page)을 의미
    // .of(context) : 위젯 트리에서 특정 상위 객체를 찾아 가져오는 패턴
    // ! : null 아님을 확신하고 컴파일러에게 알려주는 연산자
    // .settings.arguments : Navigator로 전달한 arguments 데이터 접근
    final User args = ModalRoute.of(context)!.settings.arguments as User;
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(  // AppBar 왼쪽 영역에 표시되는 위젯
          onPressed: () => Navigator.of(context).pop(), // pop() : 뒤로가기
          icon: const Icon(Icons.arrow_back_ios), // 뒤로가기 화살표
        ),
        title: const Text("Text App"),
      ),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text("성공적으로 제출되었습니다."),
            Text("Username : ${args.username}"),
            Text("Email : ${args.email}"),
          ],
        ),
      ),
    );
  }
}

 

3️⃣ Main.dart

import 'package:flutter/material.dart';
import 'package:프로젝트명/successPage.dart';
import 'package:프로젝트명/user.dart';

void main() async {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //home: const HomePage(),
      title: "Flutter App",
      initialRoute: '/',    // 초기의 루트를 어떻게 할지 설정
      routes: {             // 루트의 경우에 따라 경로를 분기 태움
        '/': (context) => const HomePage(),
        '/success': (context) => const SuccessPage(),
      },
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _key = GlobalKey<FormState>();  // GlobalKey : 위젯 트리 어디서든 해당 위젯의 상태(State)에 접근할 수 있게 해주는 키(주로 Form, Scaffold 위젯 상태 관리에 사용)
  late String _username, _email;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test App"),
      ),
      body: Container(
        padding: const EdgeInsets.all(15),
        child: Form(
          key: _key,
          child: Column(
            children: [
              usernameInput(),
              const SizedBox(height: 15),
              emailInput(),
              const SizedBox(height: 15),
              submitButton(),
            ],
          )
        ),
      )
    );
  }
  // username 입력받는 박스
  Widget usernameInput(){
    return TextFormField( // TextFormField : 텍스트 입력 위젯 (Form 내에서 validator를 통해 입력값 검증 가능)
      autofocus: true,    // autofocus : 화면이 열릴 때 자동으로 포커스
      validator: (val){   // validator : 입력값 유효성 검사
        if(val!.isEmpty){
          return 'The input is empty';
        }else{
          return null;
        }
      },
      onSaved: (username) => _username = username as String,  // onSave : 입력값 저장할 때 호출
      decoration: const InputDecoration(
        border: OutlineInputBorder(),
        hintText: 'Input your username',
        labelText: 'Username',
        labelStyle: TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold
        )
      ),
    );
  }
  // email 입력받는 박스
  Widget emailInput(){
    return TextFormField(
      autofocus: true,
      validator: (val){
        if(val!.isEmpty){
          return 'The input is empty';
        }else{
          return null;
        }
      },
      onSaved: (email) => _email = email as String,
      decoration: const InputDecoration(
        border: OutlineInputBorder(),
        hintText: 'Input your email',
        labelText: 'Email',
        labelStyle: TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold
        )
      ),
    );
  }

  // 제출 버튼
  Widget submitButton(){
    return ElevatedButton(
      onPressed: (){
        if(_key.currentState!.validate()){
          _key.currentState!.save();
          Navigator.pushNamed(context, '/success',
            arguments: User(_username, _email));
        }
      },
      child: Container(
        padding: const EdgeInsets.all(15),
        child: const Text("제출", style: TextStyle(fontSize: 18)),
      )
    );
  }
}

 

+ Recent posts