우선은 목표를 간단하게 설정했다
앞부분의 환경설정과 회원가입,로그인은 필수라서 참고하고
원하는건 첫 화면
즉 메인화면으로 들어왔을때
1. 로그인을 하였는지 확인후 로그인이 안됐다면 로그인과 회원가입이 되는 액티비티로 이동
2. 로그인을 했다면 회원들의 목록이 떠 그 이름을 누르면 그 사람과 채팅을 시작
3. 나의 메세지는 오른쪽 상대의 메세지는 왼쪽에
실시간으로 업데이트 되도록 구현
코드 설명에 앞서
모든 코드를 올리진 않았고,
참고만 하시기 바랍니다
1. 로그인이 안됐다면 로그인페이지로 이동
// Firebase 인증 및 데이터베이스 초기화
mAuth = FirebaseAuth.getInstance(); // 파이어베이스 인증객체 초기화
currentUser = mAuth.getCurrentUser(); //현재 로그인한 유저 정보 가져오기
if (currentUser == null) {
// 사용자가 로그인되어 있지 않은 경우, 로그인 화면으로 이동
Intent intent = new Intent(ChatActivity.this, LoginActivity.class);
startActivity(intent);
finish();
return;
}
로그인페이지에서도 사용한
인증관련한 FirebaseAuth에서 .getInstance() 를 사용,
그리고 그것을 변수로 저장후
이번엔
.getCurrentUser() 로 사용자를 특정
if문으로 CurrentUser가 null이라면
로그인을 하지않은 경우이기때문에 인텐트를 띄워 로그인페이지로 이동시켜주고
finish()와 리턴
2. 로그인을 해서 돌아온다면 이제 채팅창이 보여야한다
화면설정은 간단하게 해준뒤
adapter = new UserAdapter(this, userList);
listViewUsers.setAdapter(adapter);
로 어댑터에 연결 시켜준다
해당 어댑터는
public class UserAdapter extends ArrayAdapter<User> {
public UserAdapter(Context context, List<User> users) {
super(context, 0, users);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
User user = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.user_item, parent, false);
}
TextView textViewUserName = convertView.findViewById(R.id.textViewUserName);
textViewUserName.setText(user.getUserName());
return convertView;
}
}
로 이루어져있고
getItem(position)으로 해당 위치의 유저를 판별후
유저의 이름을 표시하여
그 해당 유저와의 채팅방임을 알린다
listViewUsers.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
User selectedUser = userList.get(position);
Intent intent = new Intent(MainActivity.this, ChatActivity.class);
intent.putExtra("selectedUserId", selectedUser.getUserId());
startActivity(intent);
}
});
그리고 해당 유저이름을 클릭시 그 유저와의 채팅방으로 이동을 시켜준다
userId = currentUser.getUid();
selectedUserId = getIntent().getStringExtra("selectedUserId");
receiverId = selectedUserId;
현재 로그인한 나의 아이디를 가져오고
상대의 아이디도 가져온다
messagesList = new ArrayList<>();
adapter = new MessageAdapter(this, messagesList, userId);
recyclerViewMessages.setLayoutManager(new LinearLayoutManager(this));
recyclerViewMessages.setAdapter(adapter);
'messages'의 레퍼런스 초기화를 해준뒤
메세지 목록을 저장할 ArrayList 초기화,
그 다음은 리사이클러뷰를 통해 어댑터와 연결을 해준다
해당 어댑터에서 몇가지
void bind(Message message) {
messageTextView.setText(message.getText());
// 상대방의 이름 가져오기
DatabaseReference userRef = FirebaseDatabase.getInstance().getReference("users").child(message.getSenderId());
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user != null) {
senderNameTextView.setText(user.getUserName());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
// Error handling
}
});
}
상대방의 이름을 가져와 메세지와 함께 이름을 띄워주도록 한다
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
if (viewType == VIEW_TYPE_MESSAGE_SENT) {
view = LayoutInflater.from(context).inflate(R.layout.message_item_right, parent, false);
return new SentMessageHolder(view);
} else {
view = LayoutInflater.from(context).inflate(R.layout.message_item_left, parent, false);
return new ReceivedMessageHolder(view);
}
}
로 설정하여
나의 메세지는 오른쪽에 상대의 메세지는 왼쪽에 오게끔 해준다
R.layout.message_item_left
R.layout.message_item_right
는
메세지가 왼쪽과 오른쪽으로 오게끔 설정되어있다
그래서 채팅방의 화면은
이렇게 설정 되어있는데
채팅방 목록과 똑같이 메세지 리스트들이 쌓이게 되며
아래의 메세지입력칸에 메세지를 입력하고
보내기 버튼을 클릭하면 내 메세지와 상대의 메세지가 실시간 업데이트가 되는 화면
databaseMessages.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
messagesList.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Message message = postSnapshot.getValue(Message.class);
if (message != null && message.getSenderId() != null && message.getReceiverId() != null) {
if ((message.getSenderId().equals(userId) && message.getReceiverId().equals(receiverId)) ||
(message.getSenderId().equals(receiverId) && message.getReceiverId().equals(userId))) {
messagesList.add(message);
}
}
}
adapter.notifyDataSetChanged();
// 스크롤을 맨 아래로 이동하려면 필요한 코드를 여기에 추가할 수 있습니다.
recyclerViewMessages.smoothScrollToPosition(messagesList.size() - 1);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(ChatActivity.this, "Failed to load messages.", Toast.LENGTH_SHORT).show();
}
});
를 통해서 메세지목록을 실시간으로 업데이트 하게 만들어주는데
시작할때
messagesList.clear( ) 를 통하여
기존 메시지 목록 초기화를 해주고
if (message != null && message.getSenderId() != null && message.getReceiverId() != null) { if ((message.getSenderId().equals(userId) && message.getReceiverId().equals(receiverId)) || (message.getSenderId().equals(receiverId) && message.getReceiverId().equals(userId)))
부분을 통해 현재 사용자와 선택한 사용자 간의 메시지만 목록에 추가
listViewMessages.smoothScrollToPosition(messagesList.size() - 1)
를 통해 새 메시지가 추가되면 자동으로
목록의 마지막으로 스크롤을 내려준다
즉, 새로운 메세지가 올라오면
메세지목록들이 위로 올라가면서
새로운 메세지가 텍스트 입력칸 위쪽으로 한칸 한칸 쌓이게되는것
buttonSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMessage();
}
});
그리고 메세지 보내기 버튼 온클릭이벤트를 만들어
메세지보내기 함수로 처리
private void sendMessage() {
String message = editText.getText().toString().trim();
if (!TextUtils.isEmpty(message)) {
// Firebase Database에 메시지를 보내는 코드
String messageId = databaseMessages.push().getKey();
Message newMessage = new Message(message, userId, receiverId);
if (messageId != null) {
databaseMessages.child(messageId).setValue(newMessage);
editText.setText("");
}
} else {
Toast.makeText(this, "Enter a message", Toast.LENGTH_SHORT).show();
}
}
입력한 메세지를 가져오고
메세지가 비어있지않다면
새로운 메세지의 ID와 새로운 메세지의 객체 생성
그리고 데이터베이스에 저장후
텍스트 입력칸을 초기화(공백) 시켜준다
메세지가 비어있다면 메세지를 입력하라는 토스트메세지를 남겨주자
바로바로 실시간 채팅이 가능해졌다
'Java > AndroidStudio' 카테고리의 다른 글
Android - FireBase 사용 설정 (0) | 2024.06.20 |
---|---|
Android - 구글맵 이용 주변검색 (0) | 2024.06.19 |
Android - 구글맵 마커 표시 (0) | 2024.06.19 |
Android - 이메일 형식 체크 (0) | 2024.06.19 |
Android - GPS 사용 (0) | 2024.06.18 |