Front-end/Android (안드로이드 앱 개발)

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

javapp 자바앱 2021. 2. 17. 00:00
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);
    }

 


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

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