1. 게시글 내용 페이지

- 게시글 목록 불러오는 것까지 구현했었는데 이제 각 게시물 카드를 터치했을 때 게시글 세부 내용을 확인하는 페이지로 이동하도록 추가함

2. 게시글 수정 및 삭제

- 작성한 게시글 내용을 수정, 삭제해서 DB에 반영하는 기능을 구현함

3. 댓글 등록

- 게시글에 대한 댓글을 작성할 수 있음

4. 댓글 목록 조회

- Comment.java (model) 과 CommetAdapter.java (viewmodel)을 만듦 (일기 목록, 게시글 목록과 유사한 방식으로 구현)

- 어댑터를 ListView에 연결해서 댓글 목록을 불러오도록 함

 

 

게시글 내용 페이지는 게시글 내용과 댓글 목록, 댓글 입력 부분으로 구성되어있다.

 

문제는 전체를 ScrollView에 넣고 그 중 댓글 목록을 ListView에 넣었는데

ScrollView 자체는 스크롤이 안되고 ListView만 스크롤이 되고 있다...

테스트로 작성한 글은 내용이 짧기 때문에 얼핏 괜찮아보이지만

글 내용이 길어지면 댓글이 나오는 영역이 많이 줄어들기 때문에

이 부분을 어떻게 해결할 수 있을지 더 찾아보아야 한다.

 

 

게시글 수정 및 삭제 기능을 이용할 수 있다.

 

아직은 앱 로그인 기능을 구현하지 않아 수정/삭제 권한을 따로 부여하지 않은 상태인데

나중에 로그인을 구현하고 나서 이 부분을 많이 수정해야할거 같다.

 

 

게시글에 대한 댓글 작성도 가능한데

등록 버튼을 클릭하면 키패드가 닫히도록 수정해야한다.

현재는 등록 버튼을 클릭해도 키패드가 그대로 열려있는 상태이다.

 

그리고 게시글 작성/댓글 작성 후에 출력되는 목록에 버그가 있는데

(기존에 있던 목록) + (기존에 있던 목록) + (새로 추가한거)

이렇게 데이터가 중복돼서 출력되는 현상이다.

로직 실행 순서에 문제가 있는건지 잘 모르겠다.

이것도 구글링을 더 해봐야할듯

 

그래도 오늘 하루만에 CRUD를 모두 다뤄서 뿌듯하다.

1. 게시판 Fragment화

앱에는 자유게시판과 익명게시판, 2개의 게시판이 존재한다.

 

그런데 기존 코드는 자유게시판/익명게시판 버튼을 터치할 때마다

새로운 Intent를 만들어 페이지 이동을 해서 Intent가 스택처럼 계속 쌓여나갔다.

 

이 점이 비효율적이라고 생각해서 Intent 대신 Fragment를 이용해서

한 Intent에서 자유게시판/익명게시판 Fragment를 호출하여 각 게시판을 이동할 수 있도록 수정했다.

 

 

Firebase DB와 연결하지 않아 실제 게시물 내용이 반영되진 않았지만,

각 게시판에 따라 서로 다른 RecyclerView 내용이 출력되는 것은 확인했다.

 

 

2. 게시글 작성 기능 구현 (DB 데이터 추가)

Firebase DB에 작성한 게시글 데이터를 등록하는 기능을 구현했다.

일기장 기능을 구현하면서 DB에 데이터 추가하는 코드는 작성했었기 때문에

게시글도 그와 유사하게 코드를 작성했다.

 

3. 게시글 조회 기능 구현 (DB 데이터 조회)

DB에서 데이터를 조회하면서 고민할 부분이 2가지가 있었다.

 

첫번째는 Firebase DB가 트리 구조이기 때문에

전체 일기 데이터를 어떻게 불러올 수 있는지 고민되어 찾아보았다.

구글링 한 결과 다음과 같은 코드를 작성했다.

 

freeBoardRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                    for(DataSnapshot dateSnap: dataSnapshot.getChildren()){
                        for(DataSnapshot snap: dateSnap.getChildren()){
                            Post value = snap.getValue(Post.class);
                            adapter.addItem(new Post(value.title, value.content, value.writer, value.writeDate));
                        }
                    }
            }
            ...
}

 

Firebase Reference에 ValueEventListener을 추가하는데 이때 onDataChange 메소드를 작성했었다.

여기에서 파라미터로 DataSnapshot을 가지는데, for Each문을 중첩해서 사용함으로써

트리 안쪽에 있는 데이터까지 접근할 수 있었다.

 

두번째로 고민된 것은, 자유/익명게시판을 Fragment로 구현해서 그런지

view를 return하는 것보다 DB에서 데이터를 가져오는 것이 더 나중에 실행되는 것이었다.

 

https://t-okk.tistory.com/12

구글링하다가 찾은 위의 포스팅을 참고하여 구현했다.

 

결과적으로 PostAdapter.java에 작성했었던 setItems와,

public void setItems(ArrayList<Post> items){
        this.items = items;
    }

 

포스팅에서 참고한 adapter.notifyDataSetChanged(); 를 이용했다.

 

1. 게시판 게시물 목록 구현 (RecyclerView 이용)

구현 방법

1) 기존 화면에 RecyclerView 태그 추가

2) 게시물.java 생성 <- 속성, 생성자, Get/Set 함수 생성

3) 게시물_item.xml 생성

  -현재는 CardView 사용, 추후에 레이아웃 수정할 예정

4) 게시물Adapter.java 생성

5) 기존 화면 관련 java 파일에 코드 추가

  -setLayoutManager, 게시물Adapter 이용

 

2. 자체 테스트 문항 목록 구현 (RecyclerView 이용)

구현 방법은 게시판과 동일함

 

3. 마이페이지 레이아웃 수정

-스마트폰 화면 크기와 상관 없이 화면에 내용이 꽉 차도록 수정

외부 저장소에 프로젝트를 저장할 경우 장점

  1. 프로젝트 복구 가능
  1. 협업과 동시에 버전 관리 가능

 

 

Remote repository란?

  • GitLab에서 생성한 프로젝트 url (https~) 복사
💡
git remote add origin 프로젝트url
  • git remote : 내 컴퓨터에서 외부 저장소에 관한 작업을 할 때 사용
  • add origin url : URL이 가리키는 외부 서버의 프로젝트를 원격 저장소로 지정하는데 이름은 origin이라고 할게

 

 

Git push/Git pull

💡
git push -u origin master
  • 내 컴퓨터의 프로젝트 디렉토리 내용을 origin이 가리키는 원격 저장소의 프로젝트로 업로드한다는 뜻
  • 실행하면 인증 절차를 거쳐야함
  • .git 디렉토리 내부에서 관리되던 Repository 영역을 업로드한 것

 

  • 이미 앞에서 add를 해주었기 때문에 origin이 가리키는 원격 저장소를 이미 알고 있다
  • 따라서 앞으로는 git push만 입력하면 된다.

 

  • 새로운 폴더를 만들어서 또 다른 사용자를 만든다면?
    💡
    git clone 프로젝트url
    • GitLab 서버에 있는 프로젝트를 맨 처음에 가져올 때 git clone을 실행해야함
    💡
    git push
    • 원격 저장소에 있던 프로젝트를 clone한 것이기 때문에 git push만 입력하면 된다.

 

💡
git pull
  • GitLab 프로젝트에서 새로운 commit이 생성되었을 때 해당 commit을 다시 내 컴퓨터로 가져오려면? → git pull

 

  • 왜 origin일까?
    • 가장 근원이 되는 파일 → GitLab 서버에 있는 프로젝트 파일
    • 관습적으로 외부 저장소에 존재하는 프로젝트를 origin이라는 이름으로 가리킨다.

 

❗ push 하기 전에 반드시 pull 먼저 하기 ❗

Git reset

  • HEAD : 현재 내가 위치해있는 commit을 가리키는 식별자
  • HEAD가 가리키는 commit을 변경함
💡
git reset —hard 커밋아이디
  • HEAD가 첫번째 커밋을 가리킴 → Working Directory의 내용도 첫번째 커밋 시점으로 바뀜 (hard 옵션을 사용했기 때문에)

 

Soft/Mixed/Hard 옵션의 차이

Hard

  • Working Directory가 바뀐다.
  • Staging Area가 바뀐다.

Mixed

  • Working Directory는 건드리지 않는다.
  • Staging Area가 바뀐다.

Soft

  • Working Directory는 건드리지 않는다.
  • Staging Area를 건드리지 않는다.

 

💡
git status
  • git 상태를 더 자세히 확인

 

  • hard는 위험한 옵션 → 바로 직전 commit으로 되돌아가서 Working Directory에서 작업하던 내용이 사라져도 괜찮을 때 사용
  • soft : 내가 작업하면서 만든 Staging Area가 그대로 남아있어 바로 commit 가능
  • mixed : Staging Area가 바뀌므로 최근 작업했던 상태를 commit으로 남기고 싶다면 반드시 git add를 하고 commit 해야한다.
  • 그래서 soft나 mixed 옵션은 언제 사용하는건지?

    commit 01~06까지 작업해둠. reset으로 commit 03으로 돌아간 다음 추가 작업을 하고 commit을 하면 commit 03 다음에 commit 07이 쌓이게 된다. → 제대로 된 커밋들만 깔끔하게 남길 수 있다.

 

Git 히스토리 관리하기

 

💡
git reflog
  • git reflog = git reference log : HEAD가 가리켰던 Commit 기록을 모두 보여주는 명령어

 

💡
git reset —hard HEAD@{number}
  • commit ID 대신 commit에 대한 HEAD@{number}을 입력해도 된다.

버전관리 시작하기

  • 바탕화면에 RacingGround 폴더 생성
  • VS Code에서 RacingGround 폴더 열기, 파일 작성
  • RacingGround처럼 프로젝트 내용을 담고 있는 폴더를 프로젝트 디렉토리라고 한다.
  • Git 명령어는 프로젝트 디렉토리 안에서 실행해야 한다.

git 초기화

💡
git init →Initialized empty Git repository in 경로
  • git으로 버전 관리를 할 수 있는 상태가 됨
  • RacingGround 폴더 안에 .git 폴더가 생성됨
  • .git폴더 → git으로 인해 버전 관리가 되고 있는 디렉토리
  • 기본적으로 숨김 파일 처리가 되어있음

git 사용자 정보 설정

💡
git config user.name "이름" git config user.email "이메일주소"
  • config = configuration, 설정
  • 프로젝트 디렉토리에 버전을 남길 때마다 설정한 이름, 이메일이 남는다.

특정 버전 저장

  • → commit 한다고 한다.
  • 특정 버전 = commit
  • commit 하는 것은 3가지 영역을 바탕으로 작동한다.
    1. Working Directory

      -실제로 다루고 있는 RacingGround 디렉토리같은 프로젝트 디렉토리 자체를 의미

    1. Staging Area

      -특정 버전으로 관리하고 싶은 파일들을 모아두는 장소

    1. Repository

      -특정 시점의 Staging Area의 모습을 commit으로 남기면 해당 commit들이 저장되는 장소

    • Working Directory에서 작업을 하다가 commit을 하고 싶다 → commit을 남기고 싶은 모든 파일들을 Staging Area에 올린다. → commit 명령어 실행 시 해당 시점에 Staging Area에 있던 모든 파일들이 그대로 하나의 commit으로 Repository에 저장된다.

Staging Area에 올리기

💡
git add BasicCar.js README.md #특정 파일 지정 git add . #새롭게 만들어지거나 수정된 모든 파일

Commit 하기

💡
git commit -m "커밋 메세지"
  • -m : 해당 commit에 대한 설명을 의미
  • 왜 Working Directory에서 바로 Repository로 저장하지 않고 중간에 Staging Area가 있는가?

    → 지금 당장 commit을 남기고 싶지 않은 파일이 존재할 수 있기 때문

Commit 기록 확인하기

💡
git log
  • commit log 또는 commit history라고 한다.
  • 각 commit을 고유하게 식별할 수 있는 commit ID가 있다.
  • Author : commit을 한 사용자에 대한 정보
  • 기록 확인을 끝냈으면 q 입력

Commit 비교하기

💡
git diff 커밋아이디1 커밋아이디2
  • git이 값을 구분할 수 있을 정도만 아이디를 적으면 된다. (앞 4글자 정도)

Git이 무엇일까요?

  • Git : 프로젝트 버전 관리를 하기 위해 사용하는 프로그램
  • 주요 기능
    1. 버전 관리-소프트웨어 개발 시 기능 추가, 버그 수정 등 코드 수정/추가/삭제 작업이 계속 이루어짐 → 버전 관리 필요
    1. 협업-여러 개발자들간의 협업

 

Git과 GitLab의 차이

  • Git으로 관리한 프로젝트를 저장할 서버 필요→ Git 기반의 저장소 서비스 (GitHub, GitLab)
  • Git ≠ GitLab ‼

 

Git 설치하기 (Windows & Mac)

  • Git Bash : Git 사용에 특화된 명령어 실행기→ Git 설치 시 반드시 Git Bash Here 체크!
  • Git Bash 검색해서 콘솔창 확인

5월 초 : 아키텍처 결정 및 개발 환경 세팅

우리 프로젝트는 안드로이드 스튜디오로 진행하는 것으로 생각했었는데

이왕 프로젝트를 진행하는 안드로이드, iOS 모두 지원 가능한 앱을 만들까? 라는 얘기가 잠깐 나왔었다.

네이티브 앱? 리액트? 웹 앱? 등 여러 키워드가 회의 시간에 제시되었지만

결론적으로는 원래 계획대로 안드로이드 스튜디오에서만 구현하기로 했다.

우리 팀은 서버 숙련자가 없기도 하고

앱 자체 기능을 구현하는데도 꽤 오랜 시간이 걸릴 것 같아서

서버단의 작업은 최소화하는게 좋을 것이라고 판단했다.

 

서버 구축에 대해 구글링을 많이 해봤는데

firebase를 이용해서 서버리스 아키텍처를 적용한 안드로이드 스튜디오 프로젝트 사례가 많이 있었고

firebase 이용 관련 문서가 잘 나와있는 것 같아 인터넷을 참고해서 충분히 구현할 수 있을 것이란 생각이 들어서

google에서 지원하는 firebase를 이용하는 것으로 결정했다.

또한 우리가 기획한 기능들 중 챗봇을 이용한 상담 기능이 있어서

챗봇 같은 경우 google의 dialogflow를 이용하기로 했다.

결론적으로 우리 팀의 아키텍처는

1. 안드로이드 스튜디오내에서 UI, 로직을 처리하고

2. dialogflow API를 가져와서 챗봇을 구현하고

3. firebase 서버와 연동하여 서버 운영, 실시간 데이터베이스를 사용하는 것이다.

 

 

코드 형상 관리는 GitHub를 이용해서 진행하는데 안드로이드 스튜디오와 GitHub 연동은 생각보다 수월했다.

 

Firebase 연동도 무난하게 하는 듯 했으나...

실시간 데이터베이스를 이용하기 위해 앱 수준의 gradle 파일에 google service 4.3.6버전 dependency를 추가했는데

빌드를 시도할 때마다 자꾸 오류가 나는 것이었다.

구글링해도 해당 오류에 대한 자료가 너무 없길래 몇 시간동안 절망했는데

알고보니 4.3.6버전 자체 버그가 있던 것이다,,, 아래는 해당 이슈

https://github.com/google/play-services-plugins/issues/176

Could not find setVariantDir after 4.3.6 · Issue #176 · google/play-services-plugins

Describe the bug A problem occurred configuring project ':mobile'. > Failed to notify project evaluation listener. > com.android.build.gradle.internal.crash.ExternalApiUsageException:...

github.com

4.3.6 버전에서 삭제된 메소드를 여전히 호출하는 메소드가 있었던 것..

해당 이슈가 발생한지 얼마 안된 시점이었는데

다행히도(?) 며칠 만에 버그 픽스가 된 4.3.8 버전이 나왔고 Firebase DB와 연동을 마쳤다.

 

5월 중순 : 개발 시작 (레이아웃 구성)

Figma 툴을 이용해서 작성한 앱 화면 프로토타입을 바탕으로

팀원들이 각자 맡은 역할대로 안드로이드 스튜디오 안에서 레이아웃을 구현했다.

현재는 디자인 고려 안하고 화면 해상도에 맞게 레이아웃, 버튼 배치만 한 상태이다. (위의 이미지는 메인 화면)

디자인보단 기능 구현이 우선이라고 생각해서 색 조합이나 이미지뷰는 나중에 고려할 듯 하다.

나는 앱의 주요 기능들 중 일기장 부분 레이아웃을 맡아 일기 내용/작성/수정 페이지 레이아웃을 구현했다.

5월 말 : 일기장 기능 구현 중

우리 팀이 구현할 기능들 중 가장 먼저 일기장 기능을 다뤄보기로 했다.

Firebase DB 사용법을 찾아보며 간단히 일기를 등록하고, 삭제하는 것까지 구현했다.

 

그런데 문제점이 있었으니..

1. MaterialCalendarView

커스텀 캘린더뷰를 구현하기 위해 MaterialCalendar을 활용하려고 하는데

생각보다 MaterialCalendarView와 관련된 자료들이 많이 없으며

특정 부분에서 NullPointerException 에러가 발생하는데 해당 오류의 원인을 찾지 못했다.

2. ViewModel

우리는 MVVM(Model-View-ViewModel) 패턴을 이용하여 개발을 진행하고자 한다.

그런데 안드로이드 스튜디오의 ViewModel과 관련된 자료들을 찾아보았을 때

Kotlin 언어를 이용한 자료들이 대부분.. Java를 사용하여 설명을 작성한 경우가 거의 없었다ㅠㅠ

또한 공식 문서를 읽어보아도 이것을 어떻게 활용해야할지 감이 안와서 난감한 상태다.

 

5월 말에 한번 멘토님과 온라인 미팅을 진행했었다.

본격적인 개발을 하기 앞서 개발 환경 세팅, 아키텍처 결정 등에 많은 시간을 들여서

우리 팀의 개발 속도가 너무 더딘건 아닐지 걱정스러운 마음이 있었는데

멘토님께서는 잘 진행하고 있는 것 같다며 힘이 되는 말씀을 해주셨다.

한이음 프로젝트와 관련된 다양한 조언들을 해주셔서

끝까지 책임감을 가지고 프로젝트를 진행해보겠다는 의지를 다시 한번 다잡을 수 있었다.

+ Recent posts