Open komar-tgm opened 3 years ago
Facing the same issue. Have you found any solution for the above issue @komar-tgm?
Hi @Makwana619 This is happening whenever there is any view that updates data dynamically. For ex: We have a timer and every second the text view gets updated, it will scroll to first as it redraws the recycler view to adjust the height with the newly updated text. This is because setText() method internally calls onMeaure.
same issue too(
Same issue in 3.0.0
@Chamana A workaround is to set a fixed size to the TextView that is being updated, like 30dp width 30dp height, and the list won't be reacreated. This is because the TextView won't call onMeasure if it has a fixed size.
You can also set the fixed size dynamically (remember to set the layoutparams you had in your xml) so you can still have the benefits of not setting the fixed dp in the xml, letting the responsability to calculate the size to the views.
private fun setFixedSize() {
binding.tvHours.layoutParams = ConstraintLayout.LayoutParams(
binding.tvHours.width,
binding.tvHours.height
)
binding.tvHours.updateLayoutParams<ConstraintLayout.LayoutParams> {
startToStart = rootView.id
bottomToBottom = rootView.id
}
binding.tvMinutes.layoutParams = ConstraintLayout.LayoutParams(
binding.tvHours.width,
binding.tvHours.height
)
binding.tvMinutes.updateLayoutParams<ConstraintLayout.LayoutParams> {
startToEnd = binding.tvHoursLabel.id
bottomToBottom = rootView.id
marginStart = 16
}
binding.tvSeconds.layoutParams = ConstraintLayout.LayoutParams(
binding.tvHours.width,
binding.tvHours.height
)
binding.tvSeconds.updateLayoutParams<ConstraintLayout.LayoutParams> {
startToEnd = binding.tvMinutesLabel.id
bottomToBottom = rootView.id
marginStart = 16
}
}
Then in a countdown timer, like in my case in the first tick you can set the fixed size:
var hasBeenUpdated = false
countDownTimer = object : CountDownTimer(millisInFuture, ONE_SECOND) {
override fun onTick(millisUntilFinished: Long) {
if (millisUntilFinished < ONE_HOUR) {
setLastMinutesUI()
}
if(!hasBeenUpdated) {
setFixedSize()
hasBeenUpdated = true
}
val values = millisUntilFinished.countdownValues
binding.tvHours.text = values.hours
binding.tvMinutes.text = values.minutes
binding.tvSeconds.text = values.seconds
}
override fun onFinish() {
onFinishListener()
binding.tvHours.text = "00"
binding.tvMinutes.text = "00"
binding.tvSeconds.text = "00"
this.cancel()
}
}.start()
Issues and steps to reproduce
The Recyclerview jumps back to the starting item while or after scrolling
The Recyclerview uses a FlexBoxLayoutManager with: FlexDirection.ROW FlexWrap.NOWRAP JustifyContent.FLEX_START AlignItems.FLEX_END
(maybe when adapter.notifyDataSetChanged() is called, but why?)
Expected behavior
If I scroll the Recyclerview stays on that position and does not jump back to the start
Version of the flexbox library
'com.google.android:flexbox:2.0.1'