크리스마스도 지나가고 다시 내일배움캠프를 시작하는 한 주가 돌아왔다.
크리스마스가 지나갔다는 말은, 올해도 벌써 1주일밖에 안 남았다는 뜻이기도 하다.
2023년도 이제 1주일이 채 남지 않았지만, 아직 우리의 갈길은 멀다.
2023년의 마지막 주도 열심히 달려보자.
1. 코드카타
오늘 푼 알고리즘 문제는 '문자열 나누기' 이다.
문자열 나누기 |
![]() |
![]() |
이번 문제는 지난 문제들의 경험들을 발판삼아서 한번 쉽게 풀어보자.
우선, 문제에서는 처음에 나오는 알파벳을 x라고 읽으라고 했지만, 내가 일치하는 글자와 일치하지 않는 글자를 표현하는 데에 o와 x를 사용하기로 결정해서(왜 굳이 이렇게 표현할까 싶지만, 왠지 이렇게 표현하고 싶더라) 나는 다른 변수명을 사용하기로 했다.
var o: Int = 0
var x: Int = 0
var spell = ""
그 다음은 for반복문을 취할 차례다.
우선, spell에 값을 부여한다.
for (i in 0 until s.length) {
if (spell == "") spell = s[i].toString()
여기서 위의 spell 값을 빈 값으로 준 이유가 나오게 되는데 추후에 초기화를 용이하게 하기 위해서이다.
그 다음, 조건문을 집어넣는다.
if (s[i].toString == spell) o++
else x++
s[i]의 글자가 처음 지정한 spell과 일치하면 o에 1씩 추가하고, 일치하지 않으면 x에 1씩 추가한다.
마지막으로 위의 문제의 핵심인 '처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.'를 충족시키는 조건을 작성한다.
if (o == x || i == s.length - 1) {
o = 0
x = 0
spell = ""
answer++
}
}
이렇게 적으면 자연스럽게 분해되는 문자열의 개수가 출력이 된다.
이 때, i = s.length - 1 조건을 집어넣은 이유는 문제의 또다른 조건인 '남은 부분이 없다면 종료합니다.'를 충족시키기 위해서이다.
이를 종합해보면 다음과 같은 코드가 나오게 된다.
class Solution {
fun solution(s: String): Int {
var answer: Int = 0
var o: Int = 0
var x: Int = 0
var spell = ""
for (i in 0 until s.length) {
if (spell == "") spell = s[i].toString()
if (s[i].toString() == spell) o++
else x++
if (o == x || i == s.length - 1) {
answer++
o = 0
x = 0
spell = ""
}
}
return answer
}
}
2. Android 앱개발 팀 프로젝트 - SNS 앱 프로젝트
이번 주에는 드디어 팀 단위로 앱을 만드는 팀 프로젝트가 시작되었다.
저번에도 팀 과제는 있었지만, 그 때는 역할 분담을 철저하게 맡아서 하나씩 만들고 합쳤다기보다는 과제는 개인으로 하되 그 중에서 가장 최상의 결과물을 팀 단위로 제출하던 거에 반해 이번에는 정말 말 그대로 조별과제처럼 개개인에게 역할을 분담시키고 그걸 합쳐서 완성시키는 프로젝트다.
벌써부터 내가 잘 할 수 있을까 하는 걱정이 앞서지만, 내가 모자란 부분을 채워줄 수 있는 것이 바로 팀 아니겠는가.
정말로 코딩의 협동이 뭔지 실감시켜주는 컨텐츠가 아닐까 싶다.
이번 팀 프로젝트의 큰 주제는 'SNS 앱 구현하기'이지만, 말이 SNS고 여기서 크게 벗어나지 않는 선에서는 자유롭게 만들어도 된다고 했으므로 각 조에 따라서 정말 다양한 앱이 나올 것으로 기대된다.
아울러, 이 앱에 필수적으로 구현해야 할 것과, 선택적으로 구현해도 되는 것이 있다.
<필수 구현사항>
- 메인 페이지 ( MainPageActivity )
- 메인 페이지는 앱의 첫 화면으로, 필수 구현 기능들에 대한 진입점을 제공해야 함.
- 다양한 Widget을 활용하여 매력적인 메인 페이지를 만들어 보기.
- 디자인 구성은 자율. 평소 자주 사용하던 앱의 구조를 참고.
- 사용자에게 흥미로운 콘텐츠나 공지사항을 표시하여 재방문을 유도
- 디테일 페이지 ( DetailPageActivity )
- 사용자가 메인 페이지에서 선택한 아이템의 상세 정보를 제공하는 페이지
- 상세 정보를 구조화된 형태로 표시하기 위해 **ConstraintLayout**을 활용
- 메인 페이지에서 상세 페이지를 생성할 때 필요한 data를 Intent로 전달
- 사용자와 상호작용을 위한 버튼이나 링크를 포함하여 다양한 기능을 제공
- 로그인, 회원 가입 페이지 ( SignInActivity, SignUpActivity )
- 비밀번호 입력 시, 보안을 유지하기 위해 ***로 표현
- 로그인 이후에는 사용자 이름이 화면에서 보이도록 구성
- 로그인, 회원 가입 예외 처리
- 예외 발생 시 사용자에게 안내 메시지를 표시하며, 가능한 다음 동작을 안내
- 사용자의 입력 편의를 위해 이메일, 비밀번호의 유효성 검사를 실시간으로 제공(TextWatcher 등을 활용)
- 마이 페이지 ( MyPageActivity )
- 사용자 정보와 관련된 기능들을 보여주는 페이지를 꾸미기
- 내 프로필 표시 기능, 내 게시물 보기 기능 등
- Activity 전환시 animation 구현
- 화면을 전환할 때 UI가 자연스럽게 전환되도록 하기
- startActivity()를 호출한 후에 overridePendingTransition() 메서드를 활용하여 다양한 Activity 전환 애니메이션을 적용
- 영어 버전으로 변경 적용해보기(string.xml)
- Multi-Language 지원을 위해 string.xml을 통해 문자열을 관리
- res/values-en 디렉토리를 활용하여 영어 리소스를 분리 및 관리
<선택 구현사항>
- 동그란 ImageView 만들기
- 사용자의 프로필 이미지나 아이콘 등을 원형으로 표시하기
- 이미지의 해상도와 비율에 상관없이 원형으로 잘 표시되도록 최적화
- **android:scaleType**과 함께 **android:clipToOutline**속성 등을 활용
- 스크롤 기능 추가
- 긴 내용이나 여러 아이템을 효과적으로 표시하기 위해 스크롤을 지원
- **ScrollView**를 사용하여 스크롤 가능한 레이아웃을 구현
- 더보기 기능
- 내용이 길 경우 요약 표시 후, "더보기" 버튼을 클릭하여 전체 내용을 확인
- 사용자가 내용을 축소하고 싶을 때 "접기" 기능도 함께 제공
- **TextView**의 maxLines 속성과 View.OnClickListener 등을 활용하여 구현
- Font 크기 설정에 따라 글씨 크기 달라지도록 구현
- 사용자의 시스템 설정을 반영하여 앱 내 글씨 크기를 동적으로 변경 가능
- sp, dp 차이를 이해하고 TEXT 크기를 지정하여 시스템 설정에 반응하게 하기
- 폰트 설정이 바뀌어도 레이아웃이 깨지지 않게 최적화
- Dark theme 구현
- 사용자의 시스템 설정에 따라 테마 변경이 가능
- Dark mode에서도 모든 요소가 명확하게 보이도록 색상 및 명도 조절
- res/values, res/values-night 디렉토리를 구분하여 다크 모드 전용 리소스를 정의
- 세로/가로 모드 ui 분리 구현
- 사용자가 화면을 회전할 때 UI가 자연스럽게 전환되도록 하기
- 레이아웃이 깨지지 않도록 각 모드에 맞게 최적화
- 레이아웃 리소스 폴더를 res/layout와 res/layout-land로 구분하여 관리
- 회원 정보 관리 구현
- 앱이 실행되는 동안만 임시로 회원 정보를 저장하고 관리할 수 있는 간단한 객체를 설계(Singletone)
- 예시) MemberManager
아이디어 회의 - 브레인스토밍
우선은 브레인스토밍을 통하여 어떤 걸 만들지부터 하나하나씩 아이디어를 발표했다.
거기서 나온 아이디어들은 다음과 같다.
- 인스타 같은 것 말고 카페같은 형식으로 하자. (일상 공유 목적)
- 대나무숲 같은 형식의 앱을 만들자.
- 유용한 정보를 담을 수 있는 블로그 형식으로 하자.
- 크리스마스 or 연말에 맞는 음악들을 소개하는 앱을 만들자.
- 신년 운세를 봐주는 앱을 만들자.
- Kotlin 언어를 알려주는 블로그를 만들자.
이렇게 나온 아이디어들을 취합해보면 크게 두 가지 주제로 나눌 수 있다.
- SNS형식 or 블로그형식
- 무얼 중점적으로 소개할 것인가?
이제 이걸 바탕으로 뭘 할 건지 추려보았다.
1. SNS 형식 or 블로그형식
의논 결과 블로그 형식을 가져오되 유명한 앱의 형식을 참조하기로 했다.
2. 무얼 중점적으로 소개할 것인가?
신년 운세 -> 생년월일마다 정보를 다르게 기입해야 함. 난이도 하드코어 예상.
일상 공유 -> 너무 무난함
음악 소개 -> 저작권 이슈 or 아직 배운 기능이 아님.
Kotlin 언어 정보 소개 -> 우리가 유용하게 사용할 수 있는 정보기도 하고, 접근하기도 쉬움.
그 결과 우리 조는 다음의 앱을 만들기로 결정하였다.
블라인드 앱을 참조하여 Kotlin 언어에 대한 각종 정보를 소개하는 SNS 앱 만들기
기본 골자(와이어프레임) & 역할 분담
뭘 만들지는 정했으니 이제 본격적으로 어떻게 만들지를 논의했다.
논의 결과를 요약한 내용은 다음과 같다.
- 화면 구성
- 각각 화면마다 필수요소가 있으니 참고하면서 코드짜기
- 메인화면에서, 글을 눌러서 디테일화면으로 이동.
- 글에는 시간, 댓글수, 좋아요수, 본 횟수, 날짜 포함
- 선택과제, 동그란 ImageView 만들기 와 스크롤 기능 추가
- 내 프로필 사진을 누르면 마이페이지로 이동
- 마이페이지에서 언어를 영어로 변경 가능
여기서 우리는 Figma라는 프로그램을 사용하여 대략적인 골자를 그려봤다.
맨 왼쪽에 있는 그림은 기본적으로 로그인을 어떻게 할지를 표현했는데 메인 화면에서 프사를 누르면 로그인 버튼이 뜨고, 그걸 누르면 로그인 화면으로 넘어가도록 설계했다.
그리고 오른쪽 그림은 우리가 이 앱을 만드는 데에 필요한 레이아웃과 그 레이아웃의 기본 구조를 표현했다.
이렇게 와이어프레임까지 마친 뒤 각자 만들 화면을 배정받았는데 나는 여기서 '마이 페이지 프로필'과 '언어 설정 화면'을 구현하는 역할을 맡았다. 그리고 부가적으로 프사를 둥글게 만드는 방법도 맡게 되었다.
이제 내일부터는 본격적으로 어떻게 UI를 구현시킬 건지, 그리고 각 팀원들이 만든 코드를 Git으로 합칠 때 어떤 문제가 발생하는지에 대한 트러블 슈팅을 이야기해보도록 하겠다.
'[TIL][내일배움캠프]' 카테고리의 다른 글
[내일배움캠프][TIL] 23.12.28 (목) - 팀 프로젝트 개발 3일차 : 다른 Activity와 상호작용 (0) | 2023.12.28 |
---|---|
[내일배움캠프][TIL] 23.12.27 (수) - 팀 프로젝트 개발 2일차 : 개발 초기 (1) | 2023.12.27 |
[내일배움캠프][TIL] 23.12.22 (금) - 카드 뭉치 (1) | 2023.12.22 |
[내일배움캠프][TIL] 23.12.21 (목) - 둘 만의 암호 (2), 자기소개 앱에 registerForActivityResult 적용시키기 (2) | 2023.12.21 |
[내일배움캠프][TIL] 23.12.20 (수) - 둘 만의 암호, Activity LifeCycle (2) | 2023.12.20 |