우선 프로젝트의 기본 짜임새는 다음과 같습니다.
main.dart
import 'package:flutter/material.dart';
import 'package:new_account_tutorial/pages/home.dart';void main() => runApp(MaterialApp(
title: 'new account tutorial',
theme: ThemeData(
primarySwatch: Colors.purple,
),
initialRoute: Home.RouteName,
routes: {Home.RouteName: (context) => Home()},
));
home.dart
import 'package:flutter/material.dart';class Home extends StatefulWidget {
static const RouteName = '/home';@override
_HomeState createState() => _HomeState();
}class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [Colors.blue, Colors.red],
),
),
child: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 80,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 30),
child: FlatButton(
onPressed: () {},
child: Text(
"Submit",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
)),
],
),
],
),
),
),
);
}
}
먼저 이름을 입력하는 TextField 를 하나 만들어보도록 하겠습니다.
String _name;final GlobalKey<FormState> _formKey = GlobalKey<FormState>();Widget _buildName() {
return TextFormField(
decoration: InputDecoration(
labelText: 'Name',
labelStyle: TextStyle(
color: Colors.white,
),
),
maxLength: 10,
validator: (String value) {
if (value.isEmpty) {
return 'Name is required';
}return null;
},
onSaved: (String value) {
_name = value;
},
);
}
이름의 값을 받을 수 있는 _name 변수를 하나 생성해주었고, Globalkey<FormState> 형 formKey 도 생성해주었습니다. formKey같은 경우에는 form 을 관리하게 해주는 여러 방식중에 하나인데, 표준방법이라고 하네요.
formKey 를 생성해주었으니, Form widget 안에 속성으로 부여해줍니다.
child: Form(
key: _formKey,
.
.
.
그리고 submit 버튼을 눌렀을때 모든 값들이 유효할 경우 해당 값들을 찍어주는 함수를 만들어주세요.
onPressed: () {
if (!_formKey.currentState.validate()) {
return;
}_formKey.currentState.save();print(_name);
},
이제 name 값을 비우고 submit 버튼을 클릭하면,
옆과 같이 “Name is required” 라는 문구가 나올것이고
이름에 뭔가를 적고 Submit 버튼을 클릭한다면,
콘솔에 _name 값이 찍히는 것을 확인 할 수 있습니다.
그러면 이번엔 email validator 를 만들어보도록 하겠습니다.
Widget _buildEmail() {
return TextFormField(
decoration: InputDecoration(
labelText: 'Email',
labelStyle: TextStyle(
color: Colors.white,
),
),
maxLength: 10,
validator: (String value) {
if (value.isEmpty) {
return 'Email is required';
} else if (!RegExp(
r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")
.hasMatch(value)) {
return 'Please enter a valid email address';
}return null;
},
onSaved: (String value) {
_email = value;
},
);
}
email 에는 특별히 email 유효성 검사를 하는 정규식까지 포함시켜보았습니다. 정규식 문법은 굉장히 복잡하기때문에 구글에서 검색해서 이용하시는게 편합니다.
이번에는 passworld textfield 를 만들어보도록 하겠습니다.
Widget _buildPassword() {
return TextFormField(
decoration: InputDecoration(labelText: 'Password'),
keyboardType: TextInputType.visiblePassword,
obscureText: true,
validator: (String value) {
if (value.isEmpty) {
return 'Password is Required';
}return null;
},
onSaved: (String value) {
_password = value;
},
);
}
이번에는 KeybordType 이라는 속성과 obscureText 라는 속성도 추가해주었습니다. obscureText 를 true로 설정해주면 눈에 보이지 않는 입력값을 넣어줄 수 있습니다.
validator 속성에서 한가지 주의하셔야 할 점은 문제가 될 게 없을 경우 항상 null 을 return 해야 한다는 점 입니다.