[英]Scrolling to last item of a recyclerview with a collapsing toolbar
I've got a CoordinatorLayout
which contains a CollapsingToolbarLayout
and a RecyclerView
. 我有一个
CoordinatorLayout
,其中包含一个CollapsingToolbarLayout
和RecyclerView
。 Everything looks the way it's supposed to, except that when I try to scroll to the last item programmatically, it doesn't go all the way to the bottom. 一切看起来都应该如此,只是当我尝试以编程方式滚动到最后一项时,并没有一直走到最底端。 Instead, it does this:
而是这样做:
I don't think this is a clipping problem, since the bottom item is fully there if I scroll down: 我不认为这是一个裁剪问题,因为如果我向下滚动,最下面的项目将完全存在:
Here's the main layout: 这是主要布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="16dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:contentInsetStart="72dp"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/recyclerview_bottom_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
And here's the code that goes with the screencaps above: 这是上面的屏幕截图附带的代码:
class TestActivity : AppCompatActivity() {
private val itemNames = listOf("top item", "next item", "yada", "yada yada", "yada yada yada", "second last item", "last item")
private val selectedPosition = itemNames.size - 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.recyclerview_with_collapsing_toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setTitle(R.string.some_title)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.setHasFixedSize(true)
val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.adapter = MyAdapter()
// try to scroll to the initial selected position
recyclerView.scrollToPosition(selectedPosition)
// layoutManager.scrollToPosition(selectedPosition)
// layoutManager.scrollToPositionWithOffset(selectedPosition, resources.getDimensionPixelOffset(R.dimen.item_height))
// recyclerView.post {
// recyclerView.smoothScrollToPosition(selectedPosition)
// }
}
inner class MyAdapter: RecyclerView.Adapter<MyViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, itemType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
return MyViewHolder(view)
}
override fun getItemCount(): Int {
return itemNames.size
}
override fun onBindViewHolder(vh: MyViewHolder, position: Int) {
vh.words.text = itemNames[position]
if (selectedPosition == position) {
vh.parent.setBackgroundColor(Color.MAGENTA)
} else {
vh.parent.setBackgroundColor(Color.BLACK)
}
}
}
inner class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
val parent = itemView
val words: TextView = itemView.findViewById(R.id.some_text)
}
}
Additional notes: 附加条款:
If I get rid of the CollapsingToolbarLayout
then it does show the entire last item. 如果我摆脱了
CollapsingToolbarLayout
那么它会显示整个最后一项。
I've left some of my other attempts in the code above (commented out). 我在上面的代码中留下了一些其他尝试(注释掉了)。 None of them worked.
他们都没有工作。
This example just involves a short static list and always scrolls to the same item, but the code I'm actually working on is a bit more complicated. 这个示例仅涉及一个简短的静态列表,并且始终滚动到同一项目,但是我实际上正在处理的代码要复杂一些。
The designer really wants everything to look exactly as designed, and I'm not free to change the visual design. 设计师真的希望所有东西看起来都完全符合设计,并且我不能随意更改视觉设计。
How can I scroll to the last item in a RecyclerView
that's inside a layout with a collapsing toolbar? 如何滚动到带有折叠工具栏的布局内的
RecyclerView
中的最后一项?
The problem is that getNestedScrollingParentForType(type) in NestedScrollingChildHelper#dispatchNestedScroll returns null for the non-touch scroll, so scrolling is not dispatched when it is done programmatically. 问题是NestedScrollingChildHelper#dispatchNestedScroll中的getNestedScrollingParentForType(type)对于非触摸滚动返回null,因此以编程方式完成滚动时不会分派滚动。
So we need to enable that before scrolling programmatically: 因此,我们需要在以编程方式滚动之前启用该功能:
if (!recyclerView.hasNestedScrollingParent(ViewCompat.TYPE_NON_TOUCH)) {
recyclerView.startNestedScroll(View.SCROLL_AXIS_VERTICAL,ViewCompat.TYPE_NON_TOUCH);
}
// now smooth scroll your recycler view programmatically here.
A fix for this problem would be to collapse the toolbar before scrolling to the given position. 解决此问题的方法是在滚动到给定位置之前折叠工具栏。 This can be done by adding
app_bar_layout.setExpanded(false)
before scrollToPosition. 这可以通过在scrollToPosition之前添加
app_bar_layout.setExpanded(false)
来完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.