当softkeyboard显示adjustResize设置时,如何防止RecyclerView滚动?

时间:2018-03-21 00:55:44

标签: android android-recyclerview

我的应用已声明Activity

android:windowSoftInputMode="adjustResize|stateAlwaysHidden"

adjustResize已设置,在该活动中,我有一个RecyclerViewEditText,就像聊天应用一样。

我遇到的问题是,当键盘显示时,布局会按照意图调整大小,但它也会向上滚动RecyclerView内容。

所需的行为是滚动保持不变。

我已尝试使用LayoutManager#onSaveInstanceState()及其对手LayoutManager#onRestoreInstanceState()但无济于事。

我知道很多人有类似/相同的问题,但我无法找到一个好的解决方案。

2 个答案:

答案 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
        }
    });