오늘은 회원들의 정보를
카드뷰를 통해 확인하여, 맘에 드는 사람들끼리 매칭을 해주는 app을 만들어본다.
(간단한 기능의 App입니다!)
언어 : Kotlin (100%)
환경 : Android Studio
Database : Firebase Realtime Database
그 외 : Facebook API, View Binding, Glide, CardView, yuyakaido - CardStackView, ArthurHub-ImageCropper
이 기능들은 예전 포스팅에서 따로 정리를 해두어서 동일한 방법으로 구현하였다.
👉 Facebook 로그인 & 이메일 로그인
추가된 점이 있다면, 조금 더 간결해진 코드가 되었다는 것!?
아래 와 같이 새로 가입하는 회원인 경우
메인화면(회원 리스트)을 보여주기 전에, 이름과 프로필 사진을 입력 받는다.
새로 가입하는 회원인지의 유무는 Database에 해당 uid가 존재하는지로 확인했다.
userDB = Firebase.database.reference.child("Users")
val currentUserDB = userDB.child(getCurrentUserID())
currentUserDB.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.child("name").value == null) {
showNameInputPopUp() // 사진과 이름 받기
return
}
// 유저정보 갱신하기!
getUnSelectedUsers()
}
override fun onCancelled(error: DatabaseError) {
}
})
사진을 갤러리에서 불러오고 crop하는 과정은 저번 포스팅에서 정리했었다.
회원가입이 완료된 회원이라면 다음과 같이 선택한적 없는 회원의 정보를 가져온다.
// getUnSelectedUsers()
userDB.addChildEventListener(object : ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
if (snapshot.child("userID").value != getCurrentUserID()
&& snapshot.child("likeBy").child("like").hasChild(getCurrentUserID()).not()
&& snapshot.child("likeBy").child("dislike")
.hasChild(getCurrentUserID()).not()
) {
val userID = snapshot.child("userID").value.toString()
var name = snapshot.child("name").value.toString()
val imageUrl = snapshot.child("imageUrl").value.toString()
cardItems.add(CardItem(userID, name, imageUrl))
adapter.submitList(cardItems)
adapter.notifyDataSetChanged()
}
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {
cardItems.find { it.userID == snapshot.key }?.let {
it.name = snapshot.child("name").value.toString()
}
adapter.submitList(cardItems)
adapter.notifyDataSetChanged()
}
override fun onChildRemoved(snapshot: DataSnapshot) {}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onCancelled(error: DatabaseError) {}
})
카드 넘김 효과는 오픈소스 라이브러리 yuyakaido/CardStackView를 사용하여 구현하였다.
Swipe 효과를 줄 수 있어 유용하다.
카드를 왼쪽으로 Swipe 하는 경우 DisLike, 오른쪽의 경우 Like 처리를 한다.
override fun onCardSwiped(direction: Direction?) {
when (direction) {
Direction.Right -> {
like()
}
Direction.Left -> {
dislike()
}
else -> {
}
}
}
// 좋아요를 한 경우
// like()
private fun like() {
val card = cardItems[manager.topPosition - 1]
cardItems.removeFirst() // 옆으로 보내면 카드 없애기 ! 안하면 아래로 쌓임
userDB.child(card.userID).child("likeBy").child("like").child(getCurrentUserID())
.setValue(true)
saveMatchIfOtherUserLikeME(card.userID) // 서로 좋아한다면 Match리스트에 저장
Toast.makeText(this, "${card.name}님을 Like 합니다", Toast.LENGTH_SHORT).show()
}
위 like() 함수가 실행될 때 아래 함수가 실행된다.
그 후, '매치 리스트 보기' 버튼을 눌러 저장된 List를 가져와 보여준다.
// 서로 좋아요 했니??
// saveMatchIfOtherUserLikeME()
val otherUserDB = userDB.child(getCurrentUserID()).child("likeBy").child("like").child(otherUserID)
// true라면 상대방도 나를 좋아요 한 것!
otherUserDB.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot.value == true) {
userDB.child(getCurrentUserID())
.child("likeBy")
.child("match")
.child(otherUserID)
.setValue(true)
userDB.child(otherUserID).child("likeBy").child("match")
.child(getCurrentUserID()).setValue(true)
}
}
override fun onCancelled(error: DatabaseError) {
}
})