- 게시글과 댓글 삭제 기능 구현하기
- 마이페이지 생성하기
- 게시글 조회와 작성에 따른 sharePoint 변화 주기 - 마이페이지에서 조회 가능
1. [안드로이드] Retrofit2 기본 사용법2 -'GET/POST/PUT/DELETE'
2. [안드로이드 Java] 버튼 추가 하기, 숨기기, 비활성화 하기
3. How to access Shared Preferences for each item in Recycler View in Fragment
4. How to update RecyclerView Adapter Data
RecyclerAdapter 에서 ItemView 추가/ 삭제/ 업데이트 즉각 반영하기
버튼을 보이게 하는 방법은 매우 단순했다.
xml 파일에서 일단 해당 버튼의 visibility 를 invisible로 설정해서 아무나 못보게 해놓은 후,
activity에서 지금 로그인 되어있는 유저의 아이디와 작성자의 아이디가 일치하면 해당 버튼의 visibility를 활성화 시키는 것이다.
id 변수는 이미지 상에서 보이지 않지만 위의 코드에서 sharedPreference로 로그인된 유저의 아이디를 참조하고 있는 상태다.
생각보다 버튼 활성화는 아주 쉬웠다!! 다행이야 😎
delete 통신은 안드로이드에서 처음 해보는 거라 조금 긴장했는데 메서드는 CRUD 중에서 가장 단순했다.
@DELETE("api/post/view/{postId}/delete")
Call<Void> deletePost(@Path("postId")Long postId);
delete 통신 후 return 값이 없게 설정을 했으니 Call Void로 받아야 한다.
게시글 삭제는 아주 손 쉽게 이루어졌으나 문제는 댓글 삭제였다.
댓글 자체가 listView에 담겨져 있는게 전부라 각 listView마다 user와 작성자의 아이디를 비교하고 삭제버튼을 활성화하여 삭제하는 것이 난감했다....
static
전역변수로 미리 Adapter 클래스에서 지정해두었다. public class MyViewHolder2 extends RecyclerView.ViewHolder{
TextView writer;
TextView timestamp;
TextView content;
📌 Button btn_deletecomment;
public MyViewHolder2(@NonNull View itemView){
super(itemView);
writer = (TextView) itemView.findViewById(R.id.tv_comment_nickname);
timestamp = (TextView) itemView.findViewById(R.id.tv_comment_timestamp);
content = (TextView)itemView.findViewById(R.id.tv_comment_content);
📌btn_deletecomment = (Button)itemView.findViewById(R.id.btn_deletecomment);
📌//현재 로그인되어있는 user의 id 갖고 오기
SharedPreferences sharedPreferences = itemView.getContext().getSharedPreferences("UserInfo",Context.MODE_PRIVATE);
userId = sharedPreferences.getString("userId","");
}
}
@Override
public void onBindViewHolder(@NonNull CommentRecyclerAdapter.MyViewHolder2 holder, int position){
holder.writer.setText(commentlist.get(position).getCommentWriterNickname());
holder.content.setText(commentlist.get(position).getCommentContent());
holder.timestamp.setText(commentlist.get(position).getCommentedTime());
//로그인 계정과 댓글 작성자가 일치하는지 확인 후 일치하면 삭제 버튼 활성화
📌 if(commentlist.get(position).getCommentWriterId().equals(userId)){
holder.btn_deletecomment.setVisibility(View.VISIBLE);
holder.btn_deletecomment.setTag(commentlist.get(position).getCommentId());
holder.btn_deletecomment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Long commentid = (Long) view.getTag();
PostAPI postAPI = RetrofitClient.getInstance().create(PostAPI.class);
Call<Void> call = postAPI.deleteComment(commentid);
call.enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
if(response.isSuccessful()){
Toast.makeText(c.getApplicationContext(), "댓글이 삭제되었습니다.", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(c.getApplicationContext(), "댓글 삭제에 실패했습니다.", Toast.LENGTH_SHORT).show();
ErrorBody error = new Gson().fromJson(response.errorBody().charStream(),ErrorBody.class);
Log.d("CommentRecyclerAdapter",error.getMessage());
}
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
Toast.makeText(c.getApplicationContext(), "댓글 삭제 연결 실패", Toast.LENGTH_SHORT).show();
}
});
}
});
}}
자 이렇게 각 댓글 listView Item에서 로그인 계정에 맞게 삭제 버튼도 활성화하고 삭제까지 잘 구현은 했는데
지금 한 가지 아쉬운 점은,, 삭제 하고 난 뒤에 페이지 refresh 가 안된다는 점이다..
그 말은 즉,, 삭제하고 나서 다른 페이지에 들어갔다가 다시 와야 삭제가 해당 화면에서 반영되지 삭제 버튼을 누르자마자 삭제가 반영되지 않았다.
이 부분은 삭제 작성이랑 똑같이 finish()를 startActivity()를 하면 될 줄 알았는데 ㅠㅠ Adapter 클래스 내에서는 해당 메소드를 사용할 수가 없었다...
How to update RecyclerView Adapter Data 다음 스택플로우 링크에서 많은 도움을 받았다!
의외로 삭제와 등록을 즉각으로 반영하는 코드는 매우 단순했다.
이거 지난번에 댓글 등록할 때도 엄청 헤맸고 결국 다른 코드로 어찌저찌 짜긴 했는데.. 왜 이 단순한걸 알지 못했을까
여튼!
int removeIndex = 2;
data.remove(removeIndex);
adapter.notifyItemRemoved(removeIndex);
삭제의 경우 위의 예시와 같이 삭제를 원하는 item의 position(index) 값을 받은 후
RecyclerAdapter 에서 멤버변수로 가지고 있는 (이후 각각 listView item으로 뽑아낼 ) 데이터 list에서 해당 index의 원소를 remove 시키고
이후 해당 index의 원소가 remove된걸 adapter가 반영할 수 있게 코드를 짜주면 된다.
if(response.isSuccessful()){
Toast.makeText(c.getApplicationContext(), "댓글이 삭제되었습니다.", Toast.LENGTH_SHORT).show();
commentlist.remove(pos);
notifyItemRemoved(pos);
}
위의 코드는 실제로 내가 댓글이 삭제된 후에 api로 DB에 반영하고 이후 처리를 코드로 작성한 것이다.
DB에 반영이 되었어도 adapter의 멤버변수로 남아있는 list에는 삭제가 반영이 안되어있기 때문에
따로 commentlist.remove를 해주고 그것을 감지하도록 코드를 짰다.
나머지 데이터 더하기, 데이터 수정 감지도 위의 스택플로우 링크에서 하라는 대로 간단하게 짤 수 있을 것이다.
어쨌든 adapter의 notify 함수의 핵심은 DB 변경을 notify하는 것이 아니라 자기의 멤버변수 list의 변경을 감지하는 것! 따라서 DB만 변경하지 말고 list에도 원소를 직접 넣어주고 notify해주면 된다!