我有一个聊天应用程序,我试图确保当用户打开屏幕时,项目从底部开始显示,最新显示在输入区域的正上方。我已经为输入区域使用了自定义视图,并且回收者和自定义视图都在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>
感谢任何帮助,我很迷失。.
答案 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时),因此,如果我遗漏了一些东西,请告诉我,我将更详细地检查应用程序的代码(尽管我我必须找到时间)。
祝你好运!