[039] 플러터 (Flutter) 배우기 - Form, validator, TextFormField, Navigator 매개변수 전달하기

2023. 3. 11. 15:38모바일어플개발/Flutter

반응형

안녕하세요~ totally 개발자입니다.

 

Form, validator, TextFormField, Navigator.pushNamed의 매개변수 전달해서 다른 클래스에서 받기

 

Form, validator, TextFormField를 사용해서 잘 제출되었을 때 다른 페이지로 넘어갈 수 있는 예제를 살펴 보도록 하겠습니다.

 

플러터에서는 Form 위젯을 제공하여 양식을 만들 수 있습니다. 그리고 TextFormField를 사용하여 autoFocus, validator, onSaved 등 여러가지 속성을 같이 활용할 수 있습니다.

 

Step 1: MaterialApp 부분에 home 부분을 주석 처리해주시고 initialRoute와 routes를 다음처럼 정의해주도록 합니다. 이 routes 정의를 통해 pushNamed로 페이지 라우팅을 해줄 수 있습니다. (리액트랑 원리가 같습니다) 그리고 initialRoute로 최초 라우팅 위치를 지정해줍니다. 그리고 / 일 때는 메인 MyHomePage() 클래스를 렌더링해줍니다.

 

Step 2: 다음처럼 지정해줍니다. GlobalKey<FormState>()를 사용하여 앱에서 유일한 key를 만들어서 Form 안에서 FormState를 사용할 수 있도록 합니다. FormState는 save, reset, validate 등의 속성을 사용할 수 있게 도와줍니다. 그리고 사용자 이름과 이메일 주소를 받을 수 있게 변수를 만들어줍니다.

 

 

Step 3: user.dart 파일을 새로 생성해서 아래처럼 만들어줍니다. 매개변수를 전달하기 위한 목적의 모델링입니다.

 

 

 

Step 4: 별도의 usernameInput() 위젯을 만들어서 분리합니다. 69번째 autofocus: true,는 이 페이지가 열렸을 때 바로 초점을 주어 입력할 수 있도록 만들어주는 것이고 validator에서 입력값을 검증할 수 있습니다. 77번째 onSaved는 추후 save 메소드가 발생되었을 때 변수에 값을 할당해줍니다. 78-86번째 줄을 통해 스타일을 적용해줍니다. 

 

 

 

Step 5: emailInput() 위젯도 위와 비슷하게 작성해줍니다.

 

 

Step 6: 제출 버튼을 위한 submitButton() 위젯도 생성해줍니다. 여기에서 115~121번째 줄에 있는 내용을 보면 116번째에서 validate가 성공적으로 된 경우 117번쨰에서 save를 하여 변수를 할당해주고, 118번째 pushNamed를 통해 success 페이지로 옮겨주고 매개변수로 사용자 이름, 이메일을 제공해주도록 했습니다. import 'user.dart'; 해주셔야 합니다.

 

 

 

 

Step 7: 다음처럼 build 부분을 입력해줍니다. 50번째에 key를 넣어주시고 Column 안에 위에서 생성한 위젯들을 차례로 넣어주시면 됩니다. const SizedBox(height: 15)를 사용한 것은 사이 공간을 주기 위함입니다. 

 

 

 

Step 8: successPage.dart 파일을 생성하여 다음처럼 입력해줍니다.

 

 

Step 9: 14번째 줄을 통해서 위에서 전달한 매개변수들을 전달 받을 수 있도록 합니다. 17~22번째 줄을 통해 뒤로 가기 버튼을 구현하여 원래 페이지로 되돌아갈 수 있습니다. 그리고 30-31번째 줄을 통해 전달 받은 매개변수들인 username과 email를 화면에 표시할 수 있습니다.

 

 

Step 10: 결과를 확인해본 모습입니다.

 

 

[전체 소스 코드]

 

main.dart

 

import 'package:flutter/material.dart';
import 'package:project/successPage.dart';
import 'user.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// home: const MyHomePage(),
initialRoute: '/',
routes: {
'/': (context) => const MyHomePage(),
'/success': (context) => const SuccessPage(),
});
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _key = GlobalKey<FormState>();
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: 10),
submitButton(),
],
),
),
),
);
}
Widget usernameInput() {
return TextFormField(
autofocus: true,
validator: (val) {
if (val!.isEmpty) {
return 'The input is empty.';
} else {
return null;
}
},
onSaved: (username) => _username = username as String,
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Input your username.',
labelText: 'Username',
labelStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
);
}
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 address.',
labelText: 'Email Address',
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(
"SUBMIT",
style: TextStyle(
fontSize: 18,
),
),
),
);
}
}
view raw 039_main.dart hosted with ❤ by GitHub

 

user.dart

 

class User {
final String username;
final String email;
User(this.username, this.email);
}
view raw 039_user.dart hosted with ❤ by GitHub

 

successPage.dart

 

import 'package:flutter/material.dart';
import 'package:project/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) {
final User args = ModalRoute.of(context)!.settings.arguments as User;
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: const Icon(
Icons.arrow_back_ios,
),
),
title: const Text("Test App"),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text("Successfully submitted!"),
Text("Username: ${args.username}"),
Text("Email: ${args.email}"),
],
),
),
);
}
}

[유튜브 강좌 영상]

 

https://youtu.be/qkDnepHYNIc

 

반응형