hyeals study
인스타그램 클론 (사용자 페이지3) 본문
- 유저 페이지에서 프로필 사진 변경 기능 추가, 팔로우&팔로윙 카운트 기능
<유저 페이지 프로필 사진 변경 기능>
[1] UserFragment.kt에 버튼 이벤트 추가
fragmentView?.account_iv_profile?.setOnClickListener {
//앨범 오픈
var photoPickerIntent = Intent(Intent.ACTION_PICK)
photoPickerIntent.type = "image/*"
activity?.startActivityForResult(photoPickerIntent, PICK_PROFILE_FROM_ALBUM)
}
* 여기서 PICK_PROFILE_FROM_ALBUM을 아래와 같이 선언 (static으로 선언하는 것이라고 생각하면 됨)
companion object{
var PICK_PROFILE_FROM_ALBUM = 10
}
[2] MainActivity.kt로 이동해서 onActivityResult메소드를 아래와 같이 만듦
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// 앨범에서 Profile Image 사진 선택시 호출 되는 부분
if (requestCode == UserFragment.PICK_PROFILE_FROM_ALBUM && resultCode == Activity.RESULT_OK) {
var imageUri = data?.data
var uid = FirebaseAuth.getInstance().currentUser!!.uid //파일 업로드
var storageRef = FirebaseStorage.getInstance().reference.child("userProfileImages").child(uid!!)
//사진을 업로드 하는 부분 userProfileImages 폴더에 uid에 파일을 업로드함
storageRef.putFile(imageUri!!).continueWithTask { task: com.google.android.gms.tasks.Task<UploadTask.TaskSnapshot> ->
return@continueWithTask storageRef.downloadUrl
}.addOnSuccessListener { uri ->
var map = HashMap<String,Any>()
map["image"] = uri.toString()
FirebaseFirestore.getInstance().collection("profileImages").document(uid).set(map)
}
}
}
[ 코드 설명 ]
- requestCode가 [1]에서 만든 UserFragment.kt안에 있는 PICK_PROFILE_FROM_ALBUM이고, resultCode가 OK일 경우 처리해주는 부분 (= 사진을 선택했을 경우 처리하는 부분)
- userProfileImages: 이미지를 저장할 폴더 명
- uid: 파일 명
- 이미지 다운로드 주소를 받아오기 위해서 continueWithTask를 사용
- continueWithTask의 리턴 값이 addOnSuccessListener로 넘어옴
- 이 값을 HashMap에 담아줌
- map["image"]부분: 이미지 주소값을 담음
[3] UserFragment.kt로 이동해서 프로필 이미지를 다운로드하는 기능을 추가함
- getProfileImage라는 메소드를 만듦
fun getProfileImage() {
firestore?.collection("profileImages")?.document(uid!!)?.addSnapshotListener { documentSnapshot, firebaseFirestoreException ->
if (documentSnapshot == null) return@addSnapshotListener
if (documentSnapshot?.data != null) {
val url = documentSnapshot?.data!!["image"]
Glide.with(activity!!).load(url).apply(RequestOptions().circleCrop()).into(fragmentView!!.account_iv_profile)
}
}
}
- firestore에서 profileImages라는 컬렉션으로부터 내 uid의 document를 읽어옴
- 프로필 사진이 실시간으로 변하는 것을 받아오기 위해서 Snapshot이용
- Glide로 이미지를 다운로드 받아옴
- circleCrop: 이미지를 원형(circle)으로 받아오기 위함
[4] 프로젝트를 실행해서 유저 페이지 선택 → 프로필 이미지를 눌러 프로필 사진을 변경하면 아래와 같이 firebase에 값이 저장됨
< 팔로우, 팔로윙 카운트 기능>
[5] model 패키지에 FollowDTO라는 데이터 모델을 만듦 (코틀린 파일)
data class FollowDTO(
var followerCount: Int = 0,
var followers: MutableMap<String, Boolean> = HashMap(),
var followingCount: Int = 0,
var followings: MutableMap<String, Boolean> = HashMap()
)
- followerCount: 팔로워의 수
- followers: 팔로워 하는 유저들 (중복 팔로워를 방지하기 위함)
- followingCount: 팔로윙의 수
- followings: 팔로윙 하는 유저들 (중복 팔로윙을 방지하기 위함)
[6] UserFragment.kt로 이동해서 requestFollow라는 메소드를 만듦
◎ 이 메소드에는 두 가지 기능이 있음
- 내 계정이 누구를 팔로우하는지
- 상대방 계정에는 누가 팔로우를 하는지
fun requestFollow() {
// Save data to my account
var tsDocFollowing = firestore!!.collection("users").document(currentUserUid!!)
firestore?.runTransaction { transaction ->
var followDTO = transaction.get(tsDocFollowing!!).toObject(FollowDTO::class.java)
if (followDTO == null) {
followDTO = FollowDTO()
followDTO.followingCount = 1
followDTO.followings[uid!!] = true
transaction.set(tsDocFollowing, followDTO)
return@runTransaction
}
if (followDTO?.followings?.containsKey(uid)!!) {
// It remove following third person when a third person follow me
followDTO?.followingCount = followDTO?.followingCount - 1
followDTO?.followings.remove(uid)
} else {
// It remove following third person when a third person not follow me
followDTO?.followingCount = followDTO?.followingCount + 1
followDTO?.followings[uid!!] = true
}
transaction.set(tsDocFollowing, followDTO)
return@runTransaction
}
// Save data to third person
var tsDocFollower = firestore!!.collection("users").document(uid!!)
firestore?.runTransaction { transaction ->
var followDTO = transaction.get(tsDocFollower!!).toObject(FollowDTO::class.java)
if (followDTO == null) {
followDTO = FollowDTO()
followDTO!!.followerCount = 1
followDTO!!.followers[currentUserUid!!] = true
transaction.set(tsDocFollower, followDTO!!)
return@runTransaction
}
if (followDTO!!.followers.containsKey(currentUserUid!!)) {
// It cancel my follower when I follow a third person
followDTO!!.followerCount = followDTO!!.followerCount - 1
followDTO!!.followers.remove(currentUserUid!!)
} else {
// It cancel my follower when I don't follow a third person
followDTO!!.followerCount = followDTO!!.followerCount + 1
followDTO!!.followers[currentUserUid!!] = true
}
transaction.set(tsDocFollower, followDTO!!)
return@runTransaction
}
}
[ 코드 설명 ]
- 내 계정이 누군가를 팔로우하는 과정이 담긴 트랜젝션을 만듦
- followDTO에 아무 값이 없을 때 처리하는 부분
- 여기서 uid는 상대방의 uid. (중복 팔로윙을 방지하기 위함)
- transaction.set(tsDocFollowing, followDTO): 데이터가 데이터 베이스에 담기게 됨.
- if식: 내가 이미 상대방을 팔로윙하고 있는 경우 (여기서 uid값은 상대방 uid)
- else: 내가 상대방을 팔로윙하고 있지 않는 경우
[7] UserFragment.kt의 OncreatView에 아래와 같은 버튼 클릭 이벤트를 만들어줌
[8] UserFragment.kt에 getFollowerAndFollowing 메소드를 만듦
fun getFolloerAndFollowing(){
firestore?.collection("users")?.document(uid!!)?.addSnapshotListener { documentSnapshot, firebaseFirestoreException ->
if (documentSnapshot==null) return@addSnapshotListener
var followDTO = documentSnapshot.toObject(FollowDTO::class.java)
if(followDTO?.followingCount != null){
fragmentView?.account_tv_following_count?.text = followDTO?.followingCount?.toString()
}
if(followDTO?.followerCount != null){
fragmentView?.account_tv_follower_count?.text = followDTO?.followerCount?.toString()
if(followDTO?.followers?.containsKey(currentUserUid!!)) {
fragmentView?.account_btn_follow_signout?.text = getString(R.string.follow_cancel)
fragmentView?.account_btn_follow_signout?.background?.setColorFilter(ContextCompat.getColor(activity!!,R.color.colorLightGray),PorterDuff.Mode.MULTIPLY)
}else{
if (uid != currentUserUid) {
fragmentView?.account_btn_follow_signout?.text = getString(R.string.follow)
fragmentView?.account_btn_follow_signout?.background?.colorFilter = null
}
}
}
}
}
[ 코드 설명 ]
- 여기서 uid는 내 페이지를 클릭했을 때는 내 uid값이고, 상대방 페이지를 클릭했을 때는 상대방 uid값임.
- 스냅샷을 이용해서 값을 실시간으로 불러옴
[9] UserFragment.kt의 OncreateView메소드에 아래와 같이 getFollowerAndFollowing메소드를 넣어줌
[10] 프로젝트를 실행해보면 아래와 같이 팔로우 하기 전과 후의 차이를 볼 수 있음
'안드로이드' 카테고리의 다른 글
인스타그램 클론 (댓글 페이지) (0) | 2020.04.13 |
---|---|
인스타그램 클론 (사진 페이지) (0) | 2020.04.10 |
인스타그램 클론 (사용자 페이지2) (0) | 2020.04.09 |
인스타그램 클론 (사용자 페이지 1) (0) | 2020.04.08 |
인스타그램 클론 (좋아요 버튼) (0) | 2020.04.06 |