我的应用已声明Activity
:
android:windowSoftInputMode="adjustResize|stateAlwaysHidden"
adjustResize
已设置,在该活动中,我有一个RecyclerView
和EditText
,就像聊天应用一样。
我遇到的问题是,当键盘显示时,布局会按照意图调整大小,但它也会向上滚动RecyclerView
内容。
所需的行为是滚动保持不变。
我已尝试使用LayoutManager#onSaveInstanceState()
及其对手LayoutManager#onRestoreInstanceState()
但无济于事。
我知道很多人有类似/相同的问题,但我无法找到一个好的解决方案。
答案 0 :(得分:0)
好的,令人惊讶的是,清醒的头脑和突然的思想一瞥可以创造奇迹。
我不知道每个人,但我没有找到这种简单问题的解决方案,这对我有用。共享:
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。
答案 1 :(得分:0)
使用addOnscrollListener检查当前的天气recyclerview是否在底部 如果是,则使用接受的答案中提供的方法,使回收站仅在可见最后一项时滚动,否则它将不会滚动
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
}
});