본문 바로가기
개발/일지

20.04.27.(월) NearBuy 댓글, 대댓글

by EPdev 2020. 4. 27.
728x90

당근마켓을 모티브로 해서 안드로이드 앱 NearBuy 개발중.

 

댓글, 대댓글을 구현하고 있다.

이전에 댓글/대댓글 기능을 해본적이 있어서 쉽게 생각했으나 생각할게 은근히 많다.

 

먼저 댓글은 특별할게 없으나, 대댓글이 조금 신경 쓸게 생겼다.

대댓글을 더 쓸수록 휴대폰 화면에 계단모양으로 쌓아가야할까?

보통 웹에서는 이런 형태를 보이지만, 앱이란 특성상 계단모양으로 쌓을 경우 얼마 안 되어 공백화면이 너무 많아질 수 있기에

첫번째 대댓글만 왼쪽에 여백을 주고, 그 이후 대댓글은 첫번째 대댓글의 여백에 맞추기로 했다.

 

내가 참고하고 있는 당근마켓의 경우에는 대댓글을 달려고 하면

댓글 화면에서 작성하는 게 아니라 해당 댓글만 가지고 새로운 액티비티로 전환되어 작성할 수 있다. (현재 기준)

하지만 내 생각엔 이 방법은 그렇게 친화적이라고 생각하지 않는다.

그래서 다른 앱들은 어떤 방법을 사용하고 있는지 조사를 좀 해보았다.

내가 본 것들을 크게 나누면 아래와 같다.

1. 카카오톡 류 - 댓글 작성하는 부분과 대댓글 작성하는 부분이 다르다. 댓글은 작성란이 기본적으로 있고, 대댓글을 작성하려면 새로운 작성란이 뜬다.

2. 인스타그램 류 - 댓글과 대댓글 작성 부분이 같다. 다만 대댓글의 경우 키보드 위에 조그맣게 "대댓글 입력중"이라는 안내문구가 뜨고, 대댓글 대상자의 아이디가 @태그 된다. @태그를 삭제해도 해당 댓글로 대댓글이 남겨지고, 취소하려면 "대댓글 입력중" 문구 옆의 x버튼을 누르면 된다.

둘의 비교결과 인스타그램 류의 방법이 더 직관적인 것처럼 느껴져서, 인스타그램의 방식에 @태그만 없애기로 했다. @태그를 뺀 사유는 이번 앱의 경우 SNS 느낌이 아니기 때문에 태그 기능까진 아직 필요 없다고 판단했다.

 

그렇다면 데이터베이스 테이블을 어떻게 구성해야할까?

comments란 테이블에 num(댓글번호, primary key), postNum(게시글 번호), phoneNum(작성자 아이디), time(작성일시), comment(댓글 내용), parentNum(부모 댓글 번호), sequence(댓글간 순서) 로 구성하였다.

다른 곳에서는 depth, group_id 등의 컬럼도 포함해서 댓글을 삭제하면 대댓글이 다 삭제된다거나, 대댓글간의 깊이를 정렬해준다거나 하는 기능을 넣었는데, 내가 현재 하고 있는 것은 대댓글이 계단형식이 아니라 depth는 필요없다고 판단했고, 댓글 삭제 시 대댓글을 모두 삭제하는 게 아니라 해당 댓글만 삭제되도록 spl 쿼리문을 update로 하려고 계획하기에 포함하지 않았다.

구현된 마지막은 "안드로이드" 카테고리에서 보여주도록 하겠다. 현재 댓글을 select 하는 쿼리문은 아래처럼 생각중이다.

SELECT *

FROM comments

ORDER BY IF(ISNULL(parent), num, parent), sequence;

 

오늘 구현하면서 맞이한 것들..

1. Alertdialog 에러 잡기

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

이러한 에러가 떴었다. 구글 했을 땐 Alertdialog를 import 를 주의한다던지, 아니면 manifest에서 액티비티 theme을 Theme.Appcompat으로 바꿔준다든지 하라고 했다. 하지만 둘다 에러를 잡을 수 없었고 내가 찾은 부분은

AlertDialog.Builder builder = new AlertDialog.Builder(CommentActivity.this);

이 부분이었다.

보통 나는 context를 지정할 때 this나 getApplicationContext를 많이 쓴다. 이렇게 사용하면 다음에 복붙하기가 쉽기 때문이다.

하지만 위의 경우 this는 클릭리스너 안에 있기 때문에 작동하지 않았고, 두번째인 getApplicationContext를 썼는데 여기서 오류가 난 것이다. 그래서 액티비티이름.this로 수정하니 에러가 사라졌다.

내가 이해한 context의 개념에 대해서는 다음에 다시 정리하겠다.

 

2. 안드로이드 단에서 서버와 통신하는 부분

나는 안드로이드-서버 통신을 위해 retrofit2를 사용하고 있다. 왜 이걸 사용하는 지는 다른 데에 정리하겠다.

처음에는 댓글과 대댓글이 서버에 보내는 정보가 다를 것이니(대댓글에는 부모댓글 번호가 없다)

처리를 따로 해야겠다고 생각했다. 하지만 구현하면서 보니까 굳이 따로해야할 이유가 없는 것처럼 보였고

다시 설계를 했다. 그래서 서버로 보내는 retrofitService 인터페이스의 메소드를 하나로  합치고,

서버단에 댓글을 보낼 때, 댓글이면 부모댓글 num에 일정 정수(-1)를 포함시키고 대댓글이면 부모댓글번호를 포함시키는 방법을 생각했다.

이를 서버단에서 받은 정보가 댓글인지 대댓글인지 구분한 다음에 쿼리문을 다르게 질의해주면 될 것으로 보인다.

그래서 구현했던 것을 다시 수정하는 과정중이다.

 

3. 리사이클러뷰 뷰홀더에 버튼이 두개?

현재 댓글 리사이클러뷰의 아이템에 두개의 버튼기능이 있다.

"답글달기"와 "더보기"

이를 위해 뷰홀더에 버튼클릭 기능을 두개 넣어야했다. 처음에 어떻게 했는지 기억이 잘 나지 않았으나

다시 생각해보니 어뎁터에 implement한 onClickListener 인터페이스에 클릭 이벤트 메소드를 두개 만들고,

이를 어뎁터에서 모두 override한 다음에, 뷰홀더 클래스에서 각각의 버튼에 클릭 기능을 넣으면 됐었다.

그리고 난 다음 액티비티에서 각각의 클릭이벤트를 어떻게 처리할 것인지 구현해주면 된다.

처음엔 이것에 대해서 좀 고민을 했었으나, 다시 살펴보니 이 기능밖에 없다.

(참고로, 리사이클러뷰에 클릭 이벤트를 넣는 방법이 다양한데, 나는 위에 기술한 것 처럼 클릭리스너 인터페이스를 하나 만들고

그 메소드를 어뎁터에서 override한 다음, 액티비티에서 기능을 구현해주는 방법을 사용하고 있다.

방법마다 장단점은 있다고 하는데 다른 건 안써봐서 모르겠고, 이 방법을 택한 이유는 다른 방법보다 약간 만들게 많은 것처럼 느껴지나

각각이 구분되어 있어서 보기가 쉽다.)

 

728x90

댓글