홀리 해빗

3. Sign_Up 화면 만들기 본문

현재 프로젝트

3. Sign_Up 화면 만들기

깡 딱 2024. 4. 14. 15:04

UI/UX

역시나 반응형으로 되어 있기 때문에

이거도 인지 해야됨

UI와 프론트간 대화를 하기 위해서 어떤식으로 반응형이 만들어지는지가 중요한데

피그마는 그 벽을 없애주는 느낌이라 매우 좋은거 같음

 


프론트 엔드

 

home: Scaffold(
  body: SafeArea(
    child: SingleChildScrollView(
      child: Column(

간단한 이론 ( 블로그에서는 한번만 설명 할 것이다.  )

 

scaffold 기본적인 시각적 레이아웃 구조를 제공합니다. 앱 바(AppBar), 바닥 탐색 바(BottomNavigationBar), 서랍(Drawer), 본문(Body) 등 다양한 요소를 쉽게 추가할 수 있게 해주는 컨테이너 역할

 

SafeArea 같은 경우엔 디바이스에 어플이 가려지지 않게 만들어주는것이다. ( 상단바 등 예시1 참고 )

 

siglechildscrollview 같은 경우에는 필드를 누르는경우 보통 밑에서 키보드가 올라와서 위젯들을 가리는데

그걸 해결 해주는 레이아웃 구조이다. ( 예시 2 참고 )

 

Column은 수직

예시1

 

예시2

 

먼저 이 화면을 반응형으로 만들어 주기위해서 

화면이 옆으로 커졌을때 크기를 구해서 중간패널의 크기를 잡아준다.

428 586을 기준으로 만들어준다. 

그안에 텍스트들은 패딩 값을 이용해서 텍스트들을 잡아준다.

패딩값은 원래 360 740 기준으로 잡아줘야된다. 반응형으로 커져도 텍스트 자체가 커지는게 아니기 때문에

 

 

그리고 앞서 설명한 

칼럼 기준으로 정렬 해줍니다 

mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,

https://game-chanda.tistory.com/145

 

2. Agree_Page 동의화면 만들기

UI/UX 제작소요 12일 ( 디자인 틀 제작 및 약관 동의 화면) 피그마 반응형 제작 - UI UX 김00 프론트 엔드 Column body 부분은 수직 정렬로 설정 상단바 부분은 상단바에 적지 않고 Column부분에 적어줌 ( 즉

game-chanda.tistory.com

 

자세한 내용은 위 참고

 

 

텍스트 필드도 반응형 크기로 만들어줌 

 

컨테이너 > 로우(텍스트) > 칼럼(필드)

 

텍스트 필드는 TextFormField를 이용

https://dalgoodori.tistory.com/60

 

[Flutter] TextFormField

Form 과 함께 많이 쓰이는 TextFormField 를 포스팅합니다. TextFormField 의 기능은 너무 많으니 자주 쓰는 것들로 해서 기록용으로 포스팅하려고 합니다. TextFormField() 글자 수 제한 maxLength 로 글자 수를

dalgoodori.tistory.com

 

자세한 내용은 여기 참고

 


백엔드 ( 메서드 )

bool _isObscured = true; //비전 아이콘 활성화,비활성화
String emailErrorMessage = ''; // 클래스 멤버 변수 이름 변경
String passwordErrorMessage = ''; // 패스워드 에러 메시지

 

비전아이콘 bool 값으로 잡아주고 에러메시지를 가져오기 위해서 string으로 만들어줍니다!

 

final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
final TextEditingController repasswordController = TextEditingController();

 

바운딩 해줄 수 있는 컨트롤러를 만들어줌 email,password,repassword 필드 갯수에 맞게

 

final FocusNode _focusNode = FocusNode();
Color _borderColor = Color(0xFFD1D1D1); // 기본 테두리 색상

final FocusNode _passwordFocusNode = FocusNode();
Color _passwordBorderColor = Color(0xFFD1D1D1); // 기본 테두리 색상

final FocusNode _rePasswordFocusNode = FocusNode();
Color _rePasswordBorderColor = Color(0xFFD1D1D1); // 기본 테두리 색상

 

FocusNode 와 FocusScope 가 있는데 아무리 읽어봐도 엄청난 차이점을 가지고 있지는 않는다.

  • FocusNode는 개별적인 포커스 포인트를 의미합니다. 예를 들어, 텍스트 필드 하나하나가 FocusNode를 가질 수 있습니다. 사용자가 텍스트 필드를 탭하면, 해당 텍스트 필드의 FocusNode가 포커스를 받아, 사용자가 입력할 수 있게 됩니다.
  • 간단히 말해, FocusNode는 포커스를 받을 수 있는 하나의 위젯을 말합니다.
  • 반면, FocusScope는 여러 개의 FocusNode를 그룹화하여 관리하는 역할을 합니다. 이를 통해 포커스를 그룹 내에서 이동시키거나, 특정 그룹에만 포커스를 한정시킬 수 있습니다.
  • 예를 들어, 양식(form)에 여러 개의 입력 필드가 있을 때, FocusScope를 사용하면 사용자가 입력 필드 사이를 쉽게 이동할 수 있게 해줍니다. Tab키를 누를 때 다음 입력 필드로 넘어가는 것이 좋은 예입니다.
  • 간단히 말해, FocusScope는 여러 포커스 포인트(위젯)를 그룹화하고 관리하는 영역을 의미합니다.

이론은 이러한데 focusnode도 탭키를 누를때 입력필드로 넘어가지는데 별차이를 모르겠어서 node를 사용하기로 하였다..

 

void _onFocusChange() {
  setState(() {
    _borderColor =
        _focusNode.hasFocus ? Color(0xFF4B0FFF) : Color(0xFFD1D1D1);
  });
}

void _onPasswordFocusChange() {
  setState(() {
    _passwordBorderColor =
        _passwordFocusNode.hasFocus ? Color(0xFF4B0FFF) : Color(0xFFD1D1D1);
  });
}

void _onRePasswordFocusChange() {
  setState(() {
    _rePasswordBorderColor =
        _rePasswordFocusNode.hasFocus ? Color(0xFF4B0FFF) : Color(0xFFD1D1D1);
  });
}

 

이건 패널을 눌렀을때 색 변화를 위한 메서드들이다. 이 메서드들을 

 

@override
void initState() {
  super.initState();
  _focusNode.addListener(_onFocusChange);
  _passwordFocusNode.addListener(_onPasswordFocusChange);
  _rePasswordFocusNode.addListener(
      _onRePasswordFocusChange); // 비밀번호 재입력 필드의 FocusNode 상태 변화 감지
}

@override
void dispose() {
  _focusNode.removeListener(_onFocusChange);
  _focusNode.dispose();
  _passwordFocusNode.removeListener(_onPasswordFocusChange);
  _passwordFocusNode.dispose();
  _rePasswordFocusNode.removeListener(_onRePasswordFocusChange); // 메서드 제거
  _rePasswordFocusNode.dispose();

  super.dispose();
}

 

 

변화를 감지하게 만들어준다. 

이 코드를 설명하자면

이메일 포커스 일때 색변화가 되는데 만약 패스워드 포커스가 된다면 이메일 포커스가 꺼지는 코드인다.

 

_focusNode와 , _passwordFocuNode  , _repasswordFocuNode  

코드를 이제  텍스트 필드에 넣어주면

필드를 감지하게 된다. 

 

 

파이어베이스 로그인 코드

Future<void> signUp() async {
try{}
catch{}
}

 

메서드 설명 

이 메서드를 눌렀을때 유효성 검사를 하고 오류 코드를 콘솔에 적고 , 필드의 색을 빨간색으로 바꿔주는 역활을 한다.

 

try에 버튼을 눌렀을때 할 역활들을 적어주고

catch 문에 버튼을 눌렀을때 나올 오류 코드를 적어 줘야된다. 

 

 

다음버튼을 눌렀을때 이메일필드와 ,패스워드 필드가 비워져 있으면 오류 메시지와 

오류 콘솔을 띄우는 코드이다.

 

try {
  if (emailController.text.trim().isEmpty) {
    setState(() {
      emailErrorMessage = '이메일을 입력해주세요.';
      passwordErrorMessage = '';
      _borderColor = Color(0xFFFF3333);
    });
    print('오류: 이메일을 입력해주세요.'); // 여기에 print 추가
    return;
  }
  if (passwordController.text.trim().isEmpty) {
    setState(() {
      passwordErrorMessage = '비밀번호를 입력해주세요.';
      emailErrorMessage = '';
      _passwordBorderColor = Color(0xFFFF3333);
    });
    print('오류: 비밀번호를 입력해주세요.'); // 여기에 print 추가
    return;
  }

 

 

밑에는 바운딩 되어있던 이메일 컨트롤러와 패스워드 컨트롤러를 파이어베이스로 보내서 오류가 없을 시 

계정을 만들게 짜놓은 로직이다.

사실 파이어베이스를 쓰지 않았다면 직접 200 성공코드 부터 다 직접 만들어야 했지만 

돈을 내는 대신에 아주 쉽게 만들 수 있다는 장점이 있는거 같다.

final UserCredential userCredential =
      await FirebaseAuth.instance.createUserWithEmailAndPassword(
    email: emailController.text.trim(),
    password: passwordController.text.trim(),
  );
  print('계정 생성 성공: ${userCredential.user}'); // 계정 생성 성공 시 콘솔에 출력

  setState(() {
    emailErrorMessage = '';
    passwordErrorMessage = '';
  });


  Navigator.pushReplacement(
      context, MaterialPageRoute(builder: (context) => IdMaking()));

 

또한 계정생성 성공시 idmaking 화면으로 이동하게 로직을 짜놓음

on FirebaseAuthException catch (e){}

서버상에서 나는 오류는 따로 정리 해놨는데

 

사실 e.code 를 써서 오류코드를 전부 잡을 수 있어야되는데

인식을 못합니다... 그래서

메시지가 포함되어있으면 오류 코드를 띄우게 만들었습니다.

확실히 파이어베이스가 좋은데 오류가 나는 그런..

if (e.code == 'unknown') {
  if ((e.message ?? '').contains(
      'An unknown error occurred: FirebaseError: Firebase: The email address is badly formatted. (auth/invalid-email')) {
    emailErrorMessage = '유효하지 않은 이메일 형식입니다.';
    passwordErrorMessage = '';
    _borderColor = Color(0xFFFF3333);
    print('오류: 유효하지 않은 이메일 형식입니다.');
    }
 }

 


번외로 

 

비밀번호와 재입력 비밀번호 같은지 물어보는 유효성 검사가 없어서 추가 하였습니다.

 

// 비밀번호와 재입력한 비밀번호가 다를 경우 처리
if (passwordController.text.trim() != repasswordController.text.trim()) {
  setState(() {
    repasswordErrorMessage = '비밀번호가 똑같지 않습니다.';
    passwordErrorMessage = '';
    emailErrorMessage = '';
    _rePasswordBorderColor = Color(0xFFFF3333); // 재입력 비밀번호 필드의 테두리 색을 변경할 수 있습니다.
  });
  print('오류: 비밀번호가 똑같지 않습니다.');
  return;
}

 

'현재 프로젝트' 카테고리의 다른 글

2. Agree_Page 동의화면 만들기  (0) 2024.04.11
1. 남성 취미 플랫폼 - Modir  (0) 2024.04.11
Comments