使用stackFromEnd = true将项目加载到RecyclerView中不会滚动到底部

时间:2019-08-10 01:52:38

标签: android android-recyclerview

我有一个聊天应用程序,我试图确保当用户打开屏幕时,项目从底部开始显示,最新显示在输入区域的正上方。我已经为输入区域使用了自定义视图,并且回收者和自定义视图都在ConstraintLayout中。

我的问题是,当我将项目加载到列表中时,如果项目数大于回收站的大小,它将无法完全显示最后一个项目。当我使输入区域的可见性=消失时,项目将正确显示在底部。这几乎就像回收站的LinearLineManager认为回收站的高度等于没有输入字段的屏幕。我已经手动打印了视图的大小,并使用了布局检查器来确保将回收站确实绘制在正确的位置(在输入上方和导航栏下方)。

是什么原因导致此类问题?我应该注意,每当您在聊天气泡中单击链接化的文本时,列表将滚动少量,等于打开屏幕时不正确的偏移量。显然,这里没有什么衡量标准,也不确定从哪里开始。

我还应该注意,如果我尝试使用smoothScroll添加帖子,它将转到列表的末尾,但是每当列表中出现新项目并发送邮件时,最新添加的项目似乎就会消失。用不必要的动画跳一点。就像列表中的最后一项处于某种特殊状态?

如果您好奇,这是我的滚动功能:

private fun scrollToFirstItem(dueToKeyboard: Boolean = false) {
    val stackingFromEnd = (recyclerView.layoutManager as LinearLayoutManager).stackFromEnd

    if (stackingFromEnd) {
        val firstPosition = recyclerView.adapter?.itemCount?: 0 - 1
        if (dueToKeyboard ) {
            recyclerView.scrollBy(0, Integer.MAX_VALUE)
        } else {
            recyclerView.scrollToPosition(firstPosition)
        }
        recyclerView.post { recyclerView.smoothScrollToPosition(firstPosition) }
    } else {
        recyclerView.scrollToPosition(0)
    }
}

还有我的xml片段:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<include
        android:id="@+id/searchView"
        layout="@layout/compose_new_message_include"/>

<com.airbnb.epoxy.EpoxyRecyclerView
        android:id="@+id/conversationEpoxyRV"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:scrollbars="vertical"
        app:layout_constraintTop_toBottomOf="@id/searchView"
        app:layout_constraintBottom_toTopOf="@id/composeView"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        tools:listitem="@layout/conversation_item_inbound"/>

<include layout="@layout/conversation_pip_view"
 android:id="@+id/selectedMediaContainer"/>

<****.ComposeView
        android:id="@+id/composeView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

感谢任何帮助,我很迷失。.

4 个答案:

答案 0 :(得分:0)

对我来说,这似乎比布局功能更重要,而不是滚动功能。我希望如果您使用相对布局而不是线性布局,可以轻松解决此问题。因此,如果可能有帮助,我将在下面使用相对布局添加我的解决方案。

<RelativeLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycle_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/input_field">
        </androidx.recyclerview.widget.RecyclerView>

        <EditText
            android:id="@+id/input_field"
            android:layout_width="match_parent"
            android:layout_height="50dp" 
            android:layout_alignParentBottom="true"/>
</RelativeLayout>

因此,如果不清楚我所做的工作,将 EditText 元素设置为与父级的底部对齐,这是相对布局。然后添加 RecyclerView ,以使 RecylerView 始终约束在 EditText 之上,但不重叠。

答案 1 :(得分:0)

除了您在recycleview设计中添加的限制之外,所有内容看起来都不错,我看到您将{{1}设置为recycleview searchView的顶部,而{{1 }}视图不受限制。

最好使用app:layout_constraintTop_toBottomOf="@id/searchView"来限制每个视图以免发生意外行为,因为每个视图与其他视图都有关系将受到其他视图(x,y)的影响,因此您的searchView应该如下所示:

ConstraintLayout

答案 2 :(得分:0)

将数据的arraylist大小设置为smoothScrollToPosition

var linearLayoutManager = LinearLayoutManager(context)
recyclerView.layoutManager=linearLayoutManager
recyclerView.adapter=adapter
linearLayoutManager.setStackFromEnd(true)
adapter.notifyDataSetChanged()
recyclerView.smoothScrollToPosition(dataMsgs.size())

答案 3 :(得分:0)

几年前,我遇到了类似的问题,并通过 scrollToPositionWithOffset (支持库)解决了这个问题。当然,这是在使用约束之前。...

我也将较新的物品放在底部。我插入项目后用于滚动的代码是:

 Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 300

在删除项目后要滚动并调整尴尬的位置,我使用了:

((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(getItemCount() - 1, 0);

getDecoratedTop 可以帮助“反弹”和最终定位,也可以考虑垂直边距。

我希望这会有所帮助(至少是您的问题的一部分)!就像我说的那样,这是旧代码(当我同时学习编程Android和Java时),因此,如果我遗漏了一些东西,请告诉我,我将更详细地检查应用程序的代码(尽管我我必须找到时间)。

祝你好运!