구현할 Fragment 및 화면 구조
내가 구성한 화면은 친구목록이라는 Fragment 안에 Tablayout 을 사용하고,
내부는 Viewpager2 를 이용해 찜한 친구와 지난 추천 친구라는 Fragment 를 배치한 구조이다.
친구목록[Fragment]
- 찜한 친구[Fragment]
- 지난 추천 친구[Fragment]
로 구성된 구조이다.
찜한 친구는 recyclerview 로 구현했는데,
친구를 삭제할 때마다 (adapter listener 를 통해) 친구 목록 Fragment 의 Tab text [ -> 찜한 친구(8) ]가 동적으로 변하는 것을 구현해야 했다.
원래 구현하려 했던 방법 (기본 방법)
- 찜한 친구 Fragment 에서 adapter listener 를 통해 친구목록에 변화가 감지되면, MainActivity 에 인터페이스 함수를 구현하고, 그 함수 내부에서 친구 목록 Fragment 의 함수를 호출해서, 친구 목록 Fragment 함수 내부에서 tab text 를 변경해주는 로직이다.
- 그러나, MainActivity 에서 interface 를 구현하고 불필요한 함수를 만드는 것이 비효율적이라고 생각해서
- 이참에 사용해보고 싶었지만 진입장벽이 높게 느껴져 시도해 보지 못했던 ViewModel 을 사용해 보기로 했다.
- ViewModel 안에 있는 LiveData 객체를 DataBinding을 통해 UI에서 관찰만 한다면 (observe 사용) , 액티비티나 프래그먼트에서 일일히 데이터를 갱신할 필요 없이 알아서 UI에 최신 데이터가 보이는 것이 매우 효율적으로 느껴졌기 때문이다.
ViewModel Class 생성
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class FriendListCountViewModel : ViewModel() {
// 내부에서 설정하는 자료형은 Mutable 로 변경가능하도록 설정
private val _currentCount = MutableLiveData<Int>()
// 데이터를 직접 접근하지 않고 뷰모델을 통해 가져올 수 있도록 설정
val currentCount: LiveData<Int>
get() = _currentCount
// 초기값 설정
init {
_currentCount.value = 0
}
fun updateValue(count: Int){
_currentCount.value = count
}
}
찜한 친구 목록 Fragment
starredFriendListRVAdapter.setMyItemClickListener(object : StarredFriendListRVAdapter.MyItemClickListener{
override fun onDeleteFriend(friendId: String) {
// 찜한친구 목록에서 삭제
}
override fun onGetFriendCount() {
// 뷰 모델 프로바이더를 통해 뷰모델 가져오기
sharedViewModel = ViewModelProvider(requireActivity()).get(FriendListCountViewModel::class.java)
// 라이브 데이터 값 변경
sharedViewModel.updateValue(starredFriendListRVAdapter.itemCount)
}
})
binding.starredFriendListRecyclerviewRc.adapter = starredFriendListRVAdapter
adapter 에서 친구 삭제 이벤트가 발생하면, 뷰 모델의 라이브 데이터 값을 변경한다.
친구 목록 Fragment
override fun initAfterBinding() {
var friendCount : Int // 서버에서 친구 수 받아오기
val friendListViewpagerAdapter = FriendListViewpagerAdapter(this)
binding.friendListContentVp.adapter = friendListViewpagerAdapter
val child = binding.friendListContentVp.getChildAt(0)
(child as RecyclerView)?.overScrollMode = View.OVER_SCROLL_NEVER
sharedViewModel = ViewModelProvider(requireActivity()).get(FriendListCountViewModel::class.java)
sharedViewModel.currentCount.observe(this, Observer {
friendCount = it
TabLayoutMediator(binding.friendListContentTb, binding.friendListContentVp){
tab, position -> tab.text = arrayListOf("찜한 친구($friendCount)", "지난 추천 친구")[position]
}.attach()
})
}
뷰모델을 통해 ui 를 관찰하면서 변경된 라이브 데이터 값을 tab text 에 설정하였다.
'안드로이드개발' 카테고리의 다른 글
Kotlin) Failed to find GeneratedAppGlideModule (0) | 2022.01.20 |
---|---|
git 오류 정리 (0) | 2022.01.11 |
Navigation Graph 로 BottomBar 설정하기 (0) | 2022.01.08 |
BottomNavigationView setOnNavigationItemSelectedListener is deprecated (0) | 2022.01.08 |
Retrofit2으로 API 서버와 통신 (0) | 2022.01.02 |
댓글