当在ConstraintLayout中时,RecyclerView会更改其滚动位置

时间:2018-09-24 20:40:59

标签: android android-recyclerview android-constraintlayout

RecyclerViewConstraintLayout的子代时,我遇到了问题。最初,RecyclerView位于Relative-Frame-LinearLeayout的视图层次结构的深处,并且一切正常,直到我决定使用ConstraintLayout展平视图树。我注意到,每次由于任何原因(窗口大小调整,数据集更改通知等)引起布局更改时,RecyclerView的滚动位置都会更改。

例如,每次我显示和隐藏软键盘时,内容回收器视图都会偏移一定数量的像素。

我能够在非常简单的布局上重现此行为:

ConstraintLayout
|---RecyclerView
|---Button
|---EditText

如果我设置约束以使RecyclerView放置在ConstraintLayout的任何其他子元素上上方(这意味着RecyclerView具有底部约束),并且如果我使用{{1} }和LinearLayoutManager一起,可以重现上述行为。

我该如何解决(我不想改变滚动位置)?也许RecyclerView和/或ConstraintLayout上有一些我不知道的标志...

这是我的reverseLayout = true

layout.xml

这是在<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@+id/button" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Notify Items Changed" app:layout_constraintBottom_toTopOf="@+id/edit_text" app:layout_constraintEnd_toStartOf="parent" app:layout_constraintStart_toEndOf="parent" /> <EditText android:id="@+id/edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" /> </android.support.constraint.ConstraintLayout> 中设置RecyclerView的代码:

Activity.onCreate()

这是调试日志的一部分,这些调试日志是在单击按钮几次后收集的:

setContentView(R.layout.activity_main)

val adapter = Adapter()

val layoutManager = LinearLayoutManager(this)
layoutManager.orientation = LinearLayoutManager.VERTICAL
layoutManager.reverseLayout = true

val recycler = findViewById<RecyclerView>(R.id.recycler)
recycler.layoutManager = layoutManager
recycler.adapter = adapter

recycler.addOnLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom ->
    Log.d("TEST", "bottom=$bottom, oldBottom=$oldBottom")
}

recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
        Log.d("TEST", "Scrolled: dx=$dx, dy=$dy")
        Log.d("TEST", "offset = " + recycler.computeVerticalScrollOffset())
    }
})

findViewById<Button>(R.id.button)
        .setOnClickListener {
            adapter.notifyDataSetChanged()
        }

滚动位置正在缓慢变化,内容正在向上滚动。这种变化大致等于D/TEST: Scrolled: dx=0, dy=0 D/TEST: offset = 4167 D/TEST: bottom=1253, oldBottom=1253 D/TEST: Scrolled: dx=0, dy=0 D/TEST: offset = 3887 D/TEST: bottom=1253, oldBottom=1253 D/TEST: Scrolled: dx=0, dy=0 D/TEST: offset = 3607 D/TEST: bottom=1253, oldBottom=1253 D/TEST: Scrolled: dx=0, dy=0 D/TEST: offset = 3327 D/TEST: bottom=1253, oldBottom=1253 以下的小部件的总高度。

仅当满足所有条件时,我才能重现此行为:

  • RecyclerView位于RecyclerView
  • ConstraintLayout下还有其他同级小工具
  • RecyclerView与标志LinearLayoutManagerreverseLayout中的任何一个设置为stackFromBottom一起使用。

我使用的true版本是ConstraintLayout

0 个答案:

没有答案