fix: btnTop scroll didn't work in replies

This commit is contained in:
Nikita 2024-03-11 21:36:27 +03:00 committed by Bnyro
parent 8c55f30b02
commit 64829dc198
3 changed files with 83 additions and 9 deletions

View File

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
@ -25,6 +26,8 @@ class CommentsMainFragment : Fragment() {
private val binding get() = _binding!! private val binding get() = _binding!!
private val viewModel: CommentsViewModel by activityViewModels() private val viewModel: CommentsViewModel by activityViewModels()
private var scrollListener: ViewTreeObserver.OnScrollChangedListener? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@ -45,17 +48,19 @@ class CommentsMainFragment : Fragment() {
val commentsSheet = parentFragment as? CommentsSheet val commentsSheet = parentFragment as? CommentsSheet
commentsSheet?.binding?.btnScrollToTop?.setOnClickListener { commentsSheet?.binding?.btnScrollToTop?.setOnClickListener {
// scroll back to the top / first comment // scroll back to the top / first comment
_binding?.commentsRV?.smoothScrollToPosition(0) _binding?.commentsRV?.smoothScrollToPosition(POSITION_START)
viewModel.currentCommentsPosition = 0 viewModel.setCommentsPosition(POSITION_START)
} }
binding.commentsRV.viewTreeObserver.addOnScrollChangedListener { scrollListener = ViewTreeObserver.OnScrollChangedListener {
// save the last scroll position to become used next time when the sheet is opened // save the last scroll position to become used next time when the sheet is opened
viewModel.currentCommentsPosition = layoutManager.findFirstVisibleItemPosition() viewModel.setCommentsPosition(layoutManager.findFirstVisibleItemPosition())
// hide or show the scroll to top button // hide or show the scroll to top button
commentsSheet?.binding?.btnScrollToTop?.isVisible = viewModel.currentCommentsPosition != 0 commentsSheet?.binding?.btnScrollToTop?.isVisible =
viewModel.currentCommentsPosition.value != 0
} }
binding.commentsRV.viewTreeObserver.addOnScrollChangedListener(scrollListener)
commentsSheet?.updateFragmentInfo(false, getString(R.string.comments)) commentsSheet?.updateFragmentInfo(false, getString(R.string.comments))
val commentPagingAdapter = CommentPagingAdapter( val commentPagingAdapter = CommentPagingAdapter(
@ -97,8 +102,18 @@ class CommentsMainFragment : Fragment() {
} }
} }
override fun onPause() {
super.onPause()
binding.commentsRV.viewTreeObserver.removeOnScrollChangedListener(scrollListener)
scrollListener = null
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null
} }
companion object {
private const val POSITION_START = 0
}
} }

View File

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
@ -31,6 +32,8 @@ class CommentsRepliesFragment : Fragment() {
private val viewModel: CommentsViewModel by activityViewModels() private val viewModel: CommentsViewModel by activityViewModels()
private var scrollListener: ViewTreeObserver.OnScrollChangedListener? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@ -66,9 +69,37 @@ class CommentsRepliesFragment : Fragment() {
) )
binding.commentsRV.updatePadding(top = 0) binding.commentsRV.updatePadding(top = 0)
binding.commentsRV.layoutManager = LinearLayoutManager(context)
val layoutManager = LinearLayoutManager(context)
binding.commentsRV.layoutManager = layoutManager
binding.commentsRV.adapter = repliesAdapter binding.commentsRV.adapter = repliesAdapter
// init scroll position
if (viewModel.currentRepliesPosition.value != null) {
if (viewModel.currentRepliesPosition.value!! > POSITION_START) {
layoutManager.scrollToPosition(viewModel.currentRepliesPosition.value!!)
} else {
layoutManager.scrollToPosition(POSITION_START)
}
}
commentsSheet?.binding?.btnScrollToTop?.setOnClickListener {
// scroll back to the top / first comment
layoutManager.scrollToPosition(POSITION_START)
viewModel.setRepliesPosition(POSITION_START)
}
scrollListener = ViewTreeObserver.OnScrollChangedListener {
// save the last scroll position to become used next time when the sheet is opened
viewModel.setRepliesPosition(layoutManager.findFirstVisibleItemPosition())
// hide or show the scroll to top button
commentsSheet?.binding?.btnScrollToTop?.isVisible =
viewModel.currentRepliesPosition.value != 0
}
binding.commentsRV.viewTreeObserver.addOnScrollChangedListener(scrollListener)
viewModel.selectedCommentLiveData.postValue(comment.repliesPage) viewModel.selectedCommentLiveData.postValue(comment.repliesPage)
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.lifecycleScope.launch {
@ -88,8 +119,18 @@ class CommentsRepliesFragment : Fragment() {
} }
} }
override fun onPause() {
super.onPause()
binding.commentsRV.viewTreeObserver.removeOnScrollChangedListener(scrollListener)
scrollListener = null
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null
} }
companion object {
const val POSITION_START = 0
}
} }

View File

@ -1,5 +1,6 @@
package com.github.libretube.ui.models package com.github.libretube.ui.models
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.asFlow import androidx.lifecycle.asFlow
@ -41,7 +42,12 @@ class CommentsViewModel : ViewModel() {
var channelAvatar: String? = null var channelAvatar: String? = null
var handleLink: ((url: String) -> Unit)? = null var handleLink: ((url: String) -> Unit)? = null
var currentCommentsPosition = 0 private val _currentCommentsPosition = MutableLiveData(0)
val currentCommentsPosition: LiveData<Int> = _currentCommentsPosition
private val _currentRepliesPosition = MutableLiveData(0)
val currentRepliesPosition: LiveData<Int> = _currentRepliesPosition
var commentsSheetDismiss: (() -> Unit)? = null var commentsSheetDismiss: (() -> Unit)? = null
fun setCommentSheetExpand(value: Boolean?) { fun setCommentSheetExpand(value: Boolean?) {
@ -52,6 +58,18 @@ class CommentsViewModel : ViewModel() {
fun reset() { fun reset() {
setCommentSheetExpand(null) setCommentSheetExpand(null)
currentCommentsPosition = 0 _currentCommentsPosition.value = 0
}
fun setCommentsPosition(position: Int) {
if (position != currentCommentsPosition.value) {
_currentCommentsPosition.postValue(position)
}
}
fun setRepliesPosition(position: Int) {
if (position != currentRepliesPosition.value) {
_currentRepliesPosition.postValue(position)
}
} }
} }