我的应用有一个声明为以下内容的Activity
:
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
adjustResize
设置好了,在该活动中,我有一个RecyclerView
和一个EditText
,就像在聊天一样的应用程序中一样。
我面临的问题是,当键盘显示时,布局会按意图调整大小,但它也会向上滚动RecyclerView
内容。
所需的行为是滚动保持原位。
我试过使用LayoutManager#onSaveInstanceState()
,但它LayoutManager#onRestoreInstanceState()
无济于事。
我知道很多人都有类似/相同的问题,但我找不到一个好的解决方案。
好吧,令人惊讶的是,清晰的头脑和突然的思想如何创造奇迹。
我不了解每个人的情况,但我还没有找到这个简单问题的解决方案,它对我有用。共享:
recyclerView.addOnLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom ->
val y = oldBottom - bottom
val firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition()
if (y.absoluteValue > 0 && !(y < 0 && firstVisibleItem == 0)) {
recycler_view.scrollBy(0, y)
}
}
到目前为止唯一的缺点是,当您滚动到第二项并隐藏软键盘时,它会滚动到最后,但对我来说没什么大不了的。
希望它对某人有所帮助。
编辑:这是我现在解决的方法,没有任何缺点:
private var verticalScrollOffset = AtomicInteger(0)
recyclerView.addOnLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom ->
val y = oldBottom - bottom
if (y.absoluteValue > 0) {
// if y is positive the keyboard is up else it's down
recyclerView.post {
if (y > 0 || verticalScrollOffset.get().absoluteValue >= y.absoluteValue) {
recyclerView.scrollBy(0, y)
} else {
recyclerView.scrollBy(0, verticalScrollOffset.get())
}
}
}
}
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
var state = AtomicInteger(RecyclerView.SCROLL_STATE_IDLE)
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
state.compareAndSet(RecyclerView.SCROLL_STATE_IDLE, newState)
when (newState) {
RecyclerView.SCROLL_STATE_IDLE -> {
if (!state.compareAndSet(RecyclerView.SCROLL_STATE_SETTLING, newState)) {
state.compareAndSet(RecyclerView.SCROLL_STATE_DRAGGING, newState)
}
}
RecyclerView.SCROLL_STATE_DRAGGING -> {
state.compareAndSet(RecyclerView.SCROLL_STATE_IDLE, newState)
}
RecyclerView.SCROLL_STATE_SETTLING -> {
state.compareAndSet(RecyclerView.SCROLL_STATE_DRAGGING, newState)
}
}
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (state.get() != RecyclerView.SCROLL_STATE_IDLE) {
verticalScrollOffset.getAndAdd(dy)
}
}
})
EDIT2:如果这是你的毒药,可以很容易地转换为Java。
使用 addOnscrollListener 检查当前回收器视图是否位于底部的天气如果是,请使用接受答案中提供的方法执行此操作,您回收商仅在最后一项可见时滚动,否则它不会滚动
recycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
cannotScrollVertically = !recyclerView.canScrollVertically(1);//use a Boolean variable
}
});