키즈_프로젝트

6. 마이프로필 만들기

깡 딱 2024. 11. 24. 19:06
728x90

인풋필드 기능과 인풋필드 감지

동그라미 친거

 

인풋필드 컨트롤러에 값들이 전부 들어가게 되면

저장하기 버튼이 파란색으로 변해야 된다. 


(코드) 닉네임과 생년월일에 해당하는 인풋필드를 디자인 후 컨트롤러를 넣어주자

final TextEditingController nicknameController = TextEditingController();
final TextEditingController birthDateController = TextEditingController();

 

컨트롤러 두 개를 만들어 줬다.

 

 컨트롤러와 닉네임이라는 단어를 재사용하기 위해서 인풋필드라는 위젯을 만들어주고

상태 변화를 감지하기 위해 setState를 넣어준다.

 

inputField(nicknameController, '닉네임', (value) {
  setState(() {}); // 텍스트 변화 시 상태 업데이트
}),
inputField2(birthDateController, '생년월일', (value) {
  setState(() {}); // 텍스트 변화 시 상태 업데이트
}),

 

인풋필드 위젯은 위와 같이 만들었다.

 

인풋필드 코드

Widget inputField(TextEditingController controller, String hintText, Function(String) onChanged) {
  return Container(
    width: 328,
    height: 54,
    decoration: ShapeDecoration(
      color: Colors.white,
      shape: RoundedRectangleBorder(
        side: BorderSide(width: 1, color: Color(0xFF888888)),
        borderRadius: BorderRadius.circular(4),
      ),
    ),
    padding: EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
    child: TextField(
      controller: controller,
      onChanged: onChanged, // 부모에서 전달된 콜백 사용
      decoration: InputDecoration(
        hintText: hintText,
        hintStyle: TextStyle(
          color: Color(0xFFB0B0B0),
          fontSize: 14,
          fontFamily: 'Pretendard',
          fontWeight: FontWeight.w500,
          height: 2.7,
          letterSpacing: -0.35,
        ),
        border: InputBorder.none, // 테두리 없음
      ),
      style: TextStyle(
        color: Color(0xFF3D3D3D),
        fontSize: 14,
        fontFamily: 'Pretendard',
        fontWeight: FontWeight.w500,
        height: 2.7,
        letterSpacing: -0.35,
      ),
    ),
  );
}

 

 

 

저장하기 버튼 위젯을 따로 빼서 

컨트롤러 두개가 비어있다면 색이 회색 입력이 있다면 파란색으로 뜨게 만들었다.

saveButton(
  '저장하기',
      () {
    next();
  },
  (nicknameController.text.trim().isNotEmpty && birthDateController.text.trim().isNotEmpty)
      ? Color(0xFF0095F6) // 입력이 모두 있을 때의 색상
      : Color(0xFFB0B0B0), // 입력이 없을 때의 색상
),

 

저장하기 버튼 위젯은 밑과 같다.

 

저장하기 버튼 코드

Widget saveButton(String label, VoidCallback onPressed, Color backgroundColor) {
  return InkWell(
    onTap: onPressed, // 버튼 클릭 시 실행될 함수
    child: Container(
      height: 50,
      width: 328,
      padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
      decoration: BoxDecoration(
        color: backgroundColor, // 배경색 지정
        borderRadius: BorderRadius.circular(4), // 모서리 둥글게
      ),
      child: Center(
        child: Text(
          label,
          style: TextStyle(
            color: Colors.white,
            fontSize: 14,
            fontFamily: 'Pretendard',
            fontWeight: FontWeight.w600,
            height: 1.3,
            letterSpacing: -0.35,
          ),
        ),
      ),
    ),
  );
}

 


동영상

 

글 가장 아래 동영상참고


주의할 점

이런 식으로 코드를 위젯으로 만들어서 쓰게 되면 훨씬 효율적이고 주석 때문에 헷갈릴 일도 없다.

근데 여기서 주의할 점은 나처럼 적게 되면 상대방이 무슨 코드인지 쉽게 알아볼 수없기 때문에

리네임을 하는 것을 추천한다.

 

 


저장하기 버튼 서버 연동 시키기

saveButton(
  '저장하기',
      () {
    next();
  },
  (nicknameController.text.trim().isNotEmpty && birthDateController.text.trim().isNotEmpty)
      ? Color(0xFF0095F6) // 입력이 모두 있을 때의 색상
      : Color(0xFFB0B0B0), // 입력이 없을 때의 색상
),

저장하기 버튼을 자세히 보면 next라는 코드를 짜놨는데 이 코드로 파이어베이스한테 데이터를 보내는 것이다.

 

 

next코드에는 쉽게 설명하면

 

users라는 컬렉션 안에 사용자 uid로 필드를 추가하는 과정이 next라고 생각하면 아주 쉽게 이해가 될 것이다.

또한 아까 만든 컨트롤러를 기준 오류, 그 외 오류들의 코드를 적는 곳

 

createdAt

editData 두 개를 적은 이유는

가입한 날짜, 수정한 날짜 두 개를 내가 확인하기 위해서 이다.

 

밑에 코드를 보면 아주 쉽게 이해가 가능할 것이다.

Future<void> next() async {
  final String nickname = nicknameController.text;
  final String birthDate = birthDateController.text;

  if (nickname.trim().isEmpty) {
    print('오류: 닉네임을 입력해주세요.');
    return;
  }

  if (birthDate.trim().isEmpty) {
    print('오류:생년월일을 입력해주세요.');
    return;
  }

  try {
    final User? user = FirebaseAuth.instance.currentUser;

    if (user != null) {
      // 가입 날짜를 Firestore에 저장
      DocumentReference userDoc = FirebaseFirestore.instance.collection('users').doc(user.uid);
      await userDoc.set({
        'nickname': nickname,
        'birthDate': birthDate,
        'editData': FieldValue.serverTimestamp(), // 가입 날짜 저장
      }, SetOptions(merge: true));

      print('사용자 정보가 성공적으로 업데이트되었습니다.');

      // Firestore에서 가입 날짜를 가져와서 출력
      DocumentSnapshot userSnapshot = await userDoc.get();
      if (userSnapshot.exists) {
        Timestamp createdAtTimestamp = userSnapshot['editData'];
        DateTime editData = createdAtTimestamp.toDate();
        print('가입 날짜: ${editData.toLocal()}');
      } else {
        print('오류: 사용자 정보를 가져올 수 없습니다.');
      }
    } else {
      print('오류: 사용자가 로그인되어 있지 않습니다.');
    }
    Navigator.push(
      context,
      MaterialPageRoute(builder: (_) => Home_Screen()),
    );
  } catch (e) {
    print('오류: 사용자 정보를 업데이트하는 데 실패했습니다. ${e.toString()}');
  }
}

휴대폰 빌딩시 오류 발견

 

회색 버튼일때는 아예 작동을 안하게 만들어야된다

만약에 원래 닉네임과,생년월일이 있다면 회색 버튼이 뜰것이다. 그리고 수정을 할때 파랑색으로 변하는데

수정을 하지않았을때는 굳이 저장하기 버튼을 활성화 할 필요가 없기 때문에 코드 수정을 할 예정이다.

 


 

 

 

728x90