unblindpost를 한 다음 뷰에서 어댑터 리프레시 하는 부분이 없지만, 제 추측으로는 unblindpost를 하고 나서 리사이클러뷰에 변경된 로우만 업데이트가 되어야하는데, 현재는 변수를 공유하고 있어서 내가 변경한 로우가 아니라 다른 로우에도 변경이 발생하는 것 처럼 보입니다. 리사이클러뷰이므로 각 로우마다 링크취소에 대한 정보를 가지고 있어야 합니다.
구현방법은 여러가지이지만 이미 PostResult 클래스에 blinded 속성이 있기 때문에, 그걸 이용하시면 됩니다.
뷰모델에서는 아래처럼, unblind 했을 때, 해당 아이템의 blinded속성만 변경하고 리스트를 다시 뷰로 알려주는 방식이 되어야 합니다. 어댑터에서는 받은 아이템을 화면에 갱신하기만 합니다. 성능을 고려한다면 어댑터에 DiffUtil이나 ListAdapter를 사용하시구요.
// PostResult 리스트를 뷰에 통보하는 LiveData. 화면에 보이는 리스트를 가져와서 여기를 통해 뷰에 알려주세요.
private _postResultsLiveData = MutableLiveData<List<PostResult>>(emptyList())
val postResults: LiveData get() = _postResultsLiveData
fun unblindPost(boardType: String, postId: Int) {
_loading.postValue(Event(true))
viewModelScope.launch(Dispatchers.IO) {
,,,
req.let { response ->
if (response.isSuccessful) {
..
when (response.body()!!.code) {
OK -> {
// 해당 아이템만 변경하고 업데이트 된 리스트를 뷰에 통보
val updatedPostResults = postResults.map { postResult ->
if (postResult.id == id)
postResult.copy(blinded = false)
else
postResult
}
_postResultsLiveData.postValue(updatedPostResults)
..
}
}
} else {
...
}
}
}
}
그리고 뷰홀더에서 데이터바인딩을 사용하므로, 굳이 추가적으로 뷰의 상태를 코딩하기 보다는, BindingAdapter같은 걸 만드시거나 PostResult의 blinded 속성을 Int값으로 처리하면 아래처럼 뷰의 Visibility를 직접 설정하는 부분은 필요가 없을 것 같습니다.
fun bind(postResult: PostResult, position: Int) {
..
if (postResult.blinded) {
binding.likeimg.visibility = View.INVISIBLE
binding.commentimg.visibility = View.INVISIBLE
binding.photo.visibility = View.INVISIBLE
binding.contenttext.visibility = View.INVISIBLE
...}
굳이 필요하다면 아래처럼, 간단하게 할 수있구요.
// Kotlin ktx 이용. invisible하면 화면에서 보이지는 않지만 자리는 차지하고 있고 클릭도 됩니다.
val blinded = postResult.blinded
binding.likeimg.invisibile = blinded
binding.commentimg.invisible = blinded
binding.photo.invisibile = blinded
binding.contenttext.invisible = blinded
// 또는 ConstraintLayout의 ViewGroup를 사용하시면 한번에 여러뷰의 보임 속성을 설정할 수가 있습니다.