代码之家  ›  专栏  ›  技术社区  ›  Rapunzel Van Winkle

使用折叠工具栏滚动到RecyclerView的最后一项

  •  5
  • Rapunzel Van Winkle  · 技术社区  · 6 年前

    我有一个 CoordinatorLayout 其中包含 CollapsingToolbarLayout 和A RecyclerView . 所有东西看起来都像它应该的样子,除了当我尝试以编程方式滚动到最后一个项目时,它不会一直向下滚动。而是这样做:

    enter image description here

    我不认为这是一个剪辑问题,因为如果向下滚动,底部的项目将完全存在:

    enter image description here

    主要布局如下:

    <?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>
    

    下面是上面的代码:

    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)
        }
    }
    

    附加说明:

    • 如果我摆脱了 折叠工具栏布局 然后它 显示整个最后一项。

    • 我在上面的代码中留下了一些其他尝试(注释掉)。他们都没用。

    • 这个例子只涉及一个简短的静态列表,并且总是滚动到同一个项目,但是我正在处理的代码有点复杂。

    • 设计师真的希望所有的东西看起来都和设计的一模一样,我不能随意改变视觉设计。

    如何滚动到 回收视图 在有折叠工具栏的布局中?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Vishal Arora    6 年前

    问题是NestedScrollingChildHelper DispatchNestedScroll中的GetNestedScrollingParentForType(Type)对于非触摸滚动返回空值,因此当以编程方式完成滚动时,不会调度滚动。

    所以我们需要在以编程方式滚动之前启用它:

    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. 
    
        2
  •  2
  •   B. Plüster    6 年前

    解决这个问题的方法是在滚动到给定位置之前折叠工具栏。这可以通过添加 app_bar_layout.setExpanded(false) 在ScrollToposition之前。