본문 바로가기
Front-end/Android (안드로이드 앱 개발)

Android Studio , 채팅 구현하기 | 메시지 읽음 표시

by javapp 자바앱 2021. 2. 17.
728x90

 

카톡 메시지 처럼 읽은 사람 수를 표시하는 기능을 추가 하였다.

 

 

데이터 베이스에 채팅방내 메시지당 readUsers를 추가하여 읽은 id 수를 계산하여

채팅방 총 사람에서 읽은 사람 수를 뺀 count를 표시한다.

 

 


우선 

item_messagebox.xml 에서 좌측 우측 메시지 카운터 TextView를 추가

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            >
            <TextView
                android:id="@+id/item_messagebox_textview_readCounterLeft"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="1"
                android:textSize="9dp"
                android:textColor="@color/colorAccent"
                android:visibility="invisible"
                />

            <TextView
                android:id="@+id/item_messagebox_textview_msg"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="-"
                />

            <TextView
                android:id="@+id/item_messagebox_textview_readCounterRight"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="1"
                android:textSize="9dp"
                android:textColor="@color/colorAccent"
                android:visibility="invisible"
                />
            
        </LinearLayout>

 

<MessageActivity.java>

ViewHolder에 추가

        private class ViewHolder extends RecyclerView.ViewHolder
        {
            //..
            public TextView textViewReadCounterLeft;
            public TextView textViewReadCounterRight;
           

            public ViewHolder(@NonNull View itemView) {
                super(itemView);

				//..
                textViewReadCounterLeft = (TextView)itemView.findViewById(R.id.item_messagebox_textview_readCounterLeft);
                textViewReadCounterRight = (TextView)itemView.findViewById(R.id.item_messagebox_textview_readCounterRight);
            }
        }

 

peopleCount를 전역으로 선언하여

읽은 사람 수를 계산 하는 함수를 구현

파라미터는 리싸이클러뷰 위치(position)과 좌측 또는 우측 textView

       //처음에만 서버에게 묻도록
        public void setReadCounter(final int position, final TextView textView)
        {
            if(peopleCount == 0) {

                firebaseDatabase.getReference().child("chatrooms").child(chatRoomUid).child("users")
                        .addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(@NonNull DataSnapshot snapshot) {
                                //채팅방 사람 전체를 해시맵으로 받는다.
                                Map<String, Boolean> users = (Map<String, Boolean>) snapshot.getValue();
                                peopleCount = users.size();
                                int count = peopleCount - comments.get(position).readUsers.size();
                                if (count > 0) {
                                    textView.setVisibility(View.VISIBLE);
                                    textView.setText(String.valueOf(count));
                                } else {
                                    textView.setVisibility(View.INVISIBLE);
                                }
                            }

                            @Override
                            public void onCancelled(@NonNull DatabaseError error) {

                            }
                        });
            }else
            {
                int count = peopleCount - comments.get(position).readUsers.size();
                if (count > 0) {
                    textView.setVisibility(View.VISIBLE);
                    textView.setText(String.valueOf(count));
                } else {
                    textView.setVisibility(View.INVISIBLE);
                }
            }
        }

 

채팅 메시지를 읽어오는 함수

        //채팅 내용 읽어들임
        private void getMessageList()
        {
            databaseReference = firebaseDatabase.getReference().child("chatrooms").child(chatRoomUid).child("comments");
            valueEventListener = databaseReference.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    comments.clear();

                    Map<String, Object> readUserMap = new HashMap<>();

                    for(DataSnapshot dataSnapshot : snapshot.getChildren())
                    {
                        String key = dataSnapshot.getKey();
                        ChatModel.Comment commentOrigin = dataSnapshot.getValue(ChatModel.Comment.class);
                        ChatModel.Comment commentModify = dataSnapshot.getValue(ChatModel.Comment.class);

                        commentModify.readUsers.put(myuid, true);
                        readUserMap.put(key,commentModify);

                        comments.add(commentOrigin);
                    }

                    //읽음표시 추가
                    if(!comments.get(comments.size()-1).readUsers.containsKey(myuid)){
                        firebaseDatabase.getReference().child("chatrooms").child(chatRoomUid).child("comments").updateChildren(readUserMap)
                                .addOnCompleteListener(new OnCompleteListener<Void>() {
                                    @Override
                                    public void onComplete(@NonNull Task<Void> task) {
                                        //갱신
                                        notifyDataSetChanged();
                                        recyclerView.scrollToPosition(comments.size()-1);
                                    }
                                });
                    }else{
                        notifyDataSetChanged();
                        recyclerView.scrollToPosition(comments.size()-1);
                    }
                }
                @Override
                public void onCancelled(@NonNull DatabaseError error) { }
            });
        }

commentOrigin 처음 받아온 메시지

commentModify 채팅방을 읽고 수정 후 받아온 메시지

 

읽음 표시가 없을 경우 파이어베이스 데이터베이스에 저장

읽었으면 곧바로 갱신

 

 

뒤로가기 시 데이터 베이스 참조를 끊기 위해

데이터베이스 연결 제거

    private DatabaseReference databaseReference;
    private ValueEventListener valueEventListener;
    @Override
    public void onBackPressed() {
        databaseReference.removeEventListener(valueEventListener);
        Intent intent = new Intent(MessageActivity.this, MainHomeActivity.class);

        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

                | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra("activityKey", FROM_MESSAGEACTIVITY);

        startActivity(intent);
        overridePendingTransition(R.anim.in_left,R.anim.out_right);
    }

 


기능을 추가할때마다 예상치 못한 에러들이 나타나기 시작한다. 

기능을 추가하면서 어디서 에러가 날지 예상하거나 볼 수 있는 안목을 키우고 섬세하게 코딩하는 능력을 기르는게 좋을 것 같다.

댓글