nto*_*rnl 8 android android-recyclerview android-constraintlayout
我遇到了一个问题,RecyclerView当它是ConstraintLayout. 最初,它RecyclerView位于Relative-、Frame-和LinearLeayouts的视图层次结构深处,并且一切正常,直到我决定使用 ConstraintLayout 扁平化视图树。我注意到每次由于任何原因(窗口调整大小、数据集更改通知等)导致布局更改时, 的滚动位置RecyclerView都会更改。
例如,每次我显示和隐藏软键盘时,内容回收器视图都会漂移一定的像素。
我能够在一个非常简单的布局上重现这种行为:
ConstraintLayout
|---RecyclerView
|---Button
|---EditText
Run Code Online (Sandbox Code Playgroud)
如果我将约束设置RecyclerView为放置在 的任何其他子项之上ConstraintLayout(意味着 RecyclerView 具有底部约束),并且如果我使用LinearLayoutManagerwith reverseLayout = true,我可以重现上述行为。
我应该如何解决这个问题(我不想改变滚动位置)?也许 RecyclerView 和/或 ConstraintLayout 上有一些我不知道的标志......
这是我的layout.xml:
ConstraintLayout
|---RecyclerView
|---Button
|---EditText
Run Code Online (Sandbox Code Playgroud)
这里是代码设置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()
}
Run Code Online (Sandbox Code Playgroud)
下面是调试日志的片段,这是在多次点击按钮后收集的:
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
Run Code Online (Sandbox Code Playgroud)
滚动位置正在缓慢变化,内容正在向顶部滚动。偏移量大致等于下方小部件的总高度RecyclerView。
只有在满足所有条件时,我才能重现此行为:
RecyclerView 位于一个 ConstraintLayoutRecyclerViewLinearLayoutManager与任一标志一起使用reverseLayout或stackFromBottom设置为true.我使用的ConstraintLayout版本是1.1.2.