1. get package 사용
2. 이메일 유효성 검사
3. 비밀번호 obscure suffix icon event
4. login button event
1. 기본 틀 구현
// @dart=2.9
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class Login extends StatelessWidget {
final TextEditingController _email = new TextEditingController();
final TextEditingController _pass = new TextEditingController();
String get emailText => _email.text;
String get passText => _pass.text;
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
onSubmit() {
print(emailText + " " + passText);
}
return Container(
padding: EdgeInsets.only(top: height / 10),
child: Column(
children: <Widget>[
TextField(
controller: _email,
decoration: InputDecoration(hintText: '이메일'),
),
Text('alert message'),
TextField(
controller: _pass,
decoration: InputDecoration(
hintText: '비밀번호',
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: Colors.grey,
),
)),
obscureText: true,
),
Container(
padding: EdgeInsets.only(top: height / 10),
child: ElevatedButton(
child: Text('로그인'),
onPressed: onSubmit,
style: ElevatedButton.styleFrom(
primary: Colors.black,
onPrimary: Colors.white,
padding: EdgeInsets.only(
left: width / 10 * 2, right: width / 10 * 2)),
))
],
),
);
}
}
2-1. email 유효성 검사
String _buildEmail(text) {
if (text.toString().isEmpty) {
_pass.clear();
return '이메일을 입력해주세요.';
} 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(text.toString())) {
return '이메일 형식을 확인하세요.';
} else {
return null;
}
}
2-2. Controller class (alert message)
class Controller extends GetxController {
var alert = ''.obs;
textChange(String text) {
alert.value = text;
}
}
2-3. Controller 사용 (email TextField 입력에 따른 alert message 보여주는 Text Change)
class Login extends StatelessWidget {
...
Controller _controller = Get.put(Controller());
@override
Widget build(BuildContext context) {
...
return Container(
padding: EdgeInsets.only(top: height / 10),
child: Column(
children: <Widget>[
TextField(
controller: _email,
decoration: InputDecoration(hintText: '이메일'),
onChanged: (text) {
_controller.textChange(_buildEmail(text));
},
),
Obx(() => Text(_controller.alert.value ?? '')),
TextField(
controller: _pass,
decoration: InputDecoration(
hintText: '비밀번호',
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: Colors.grey,
),
)),
obscureText: true,
),
Container(
padding: EdgeInsets.only(top: height / 10),
child: ElevatedButton(
child: Text('로그인'),
onPressed: onSubmit,
style: ElevatedButton.styleFrom(
primary: Colors.black,
onPrimary: Colors.white,
padding: EdgeInsets.only(
left: width / 10 * 2, right: width / 10 * 2)),
))
],
),
);
}
}
3-1. Controller class (password suffix icon)
class Controller extends GetxController {
var alert = ''.obs;
var isobscure = true.obs;
textChange(String text) {
alert.value = text;
}
obscureChange() {
isobscure.value = !isobscure.value;
}
}
3-2. Controller 사용 (suffix icon 이벤트)
@override
Widget build(BuildContext context) {
...
return Container(
padding: EdgeInsets.only(top: height / 10),
child: Column(
children: <Widget>[
...
Obx(() => TextField(
controller: _pass,
decoration: InputDecoration(
hintText: '비밀번호',
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: _controller.isobscure.value
? Colors.grey
: Colors.black,
),
onPressed: _controller.obscureChange,
)),
obscureText: _controller.isobscure.value,
},
)),
...
],
),
);
}
4-1. Controller class (login button active)
class Controller extends GetxController {
var alert = ''.obs;
var isobscure = true.obs;
var btnable = false.obs;
textChange(String text) {
alert.value = text;
}
obscureChange() {
isobscure.value = !isobscure.value;
}
btnableChange(bool value) {
btnable.value = value;
}
}
4-2. Controller 사용 (각 TextField 입력에 따른 login button 활성화 이벤트)
@override
Widget build(BuildContext context) {
...
return Container(
padding: EdgeInsets.only(top: height / 10),
child: Column(
children: <Widget>[
...
Obx(() => TextField(
...
onChanged: (text) {
if(text.isEmpty) {
_controller.btnableChange(false);
} else if(_controller.alert.value == null) {
if(!_controller.btnable.value) {
_controller.btnableChange(true);
}
} else {
_controller.btnableChange(false);
}
},
)
),
Container(
padding: EdgeInsets.only(top: height / 10),
child: Obx(() => ElevatedButton(
child: Text('로그인'),
onPressed: onSubmit,
style: ElevatedButton.styleFrom(
primary: _controller.btnable.value ? Colors.black : Colors.black26,
onPrimary: Colors.white,
padding: EdgeInsets.only(
left: width / 10 * 2, right: width / 10 * 2)),
)
)
)
],
),
);
}
5. 결과
320x100
'프로그래밍 > Flutter-Dart' 카테고리의 다른 글
[Flutter] Flexible, Expanded (0) | 2022.02.16 |
---|---|
[Flutter] Row, Column (0) | 2022.02.16 |
[Flutter] native code 호출하기 (0) | 2021.03.26 |
[Flutter] Card (0) | 2021.03.25 |
[Flutter] Unsound null safety 관련 (0) | 2021.03.25 |
댓글