键盘打开时相应向上滚动 RecyclerView

Posted

技术标签:

【中文标题】键盘打开时相应向上滚动 RecyclerView【英文标题】:Scroll RecyclerView up accordingly when keyboard opens 【发布时间】:2018-05-08 11:11:21 【问题描述】:

我创建了一个聊天活动,就像 facebook messenger,底部有一个 EditText,上面是消息的 RecyclerView。当键盘打开时,我想向上滚动 RecyclerView 到底应该向上滚动多少。更具体地说,假设 RecyclerView 中有 5 条消息,当前第三条消息就在 EditText 的上方。因此,当键盘打开时,我想像以前一样将第三条消息保留在 EditText 上方。我已经搜索但找不到。如果这是一个重复的问题,如果有人可以提供链接,我将不胜感激。

【问题讨论】:

我试过了,还是不行。 android:windowSoftInputMode="adjustPan" 试试这个。 ***.com/questions/34102741/…的可能重复 好吧,我不想滚动到最后一项@HemantParmar 这也不起作用@mehul 【参考方案1】:
recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() 
        @Override
        public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) 
            if ( bottom < oldBottom) 
                recyclerView.postDelayed(new Runnable() 
                    @Override
                    public void run() 
                        recyclerView.scrollToPosition(adapter.getItemCount());
                    
                , 100);
            
        
    );

如果它不起作用使用 smoothScrollToPosition 而不是 scrollToPosition

这对我有用。

【讨论】:

【参考方案2】:

迟到的答案,但也许有人会觉得它有用。

如果它是一个聊天应用程序,那么我想你想从底部开始构建列表。例如,有一个空聊天,在您添加几条消息后,您希望它们位于列表的底部。稍后,随着消息越来越多,旧消息会上升,新消息会在底部,EditText 的正上方。

假设最新消息在您的列表/数组中排在第一位,您只需将 LinearLayoutManager 设置为反向布局。

layoutManager.reverseLayout = true

我无法解释原因,但看起来RecyclerView 总是试图保留上边框的滚动位置。因此,当显示键盘时,可用的垂直空间会缩小,RecyclerView 只会尝试保持其顶部与以前相同。通过使其反向布局,您可以实现所需的行为。

【讨论】:

【参考方案3】:

我有同样的问题,我不想设置 windowSoftInputMode 为“adjustResize”。以上答案对我不起作用。

editText.clearFocused();
hideKeyboard();

// update your adapter ... 

parent.requestLayout();

重置父布局的焦点,recyclerView 将正确更新。

【讨论】:

【参考方案4】:

我一直在寻找正确的解决方案,我想我找到了。

当您将 recyclerview 放置在 ConstraintLayout 中时,您认为您可以轻松地将 recyclerview 与其他视图(在您的情况下为 edittext)相关联地正确放置,它将不起作用。

这曾经是我的布局 xml,但它不起作用(我的 LinearLayoutManager 上有 reverseLayout=true):

<androidx.constraintlayout.widget.ConstraintLayout>

  <RecyclerView
    android:id="@+id/recyclerView"
    android:layout_
    android:layout_
    app:layout_constraintBottom_toTopOf="@id/editText"
    app:layout_constraintTop_toBottomOf="parent" />

  <EditText
    android:id="@+id/editText"
    android:layout_
    android:layout_
    app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

使用这种布局,每次我通过按 EditText 打开或关闭键盘时,滚动位置都会略微向上移动。

我通过不使用 ConstraintLayout 来修复它,而是将其替换为像这样的旧式 RelativeLayout:

<RelativeLayout>

  <RecyclerView
    android:id="@+id/recyclerView"
    android:layout_
    android:layout_above="@id/editText"
    android:layout_ <!-- This is important, with 0dp it still doesnt work  -->
     />

  <EditText
    android:id="@+id/editText"
    android:layout_
    android:layout_
    android:layout_alignParentBottom="true" />

</RelativeLayout>

将 RecyclerView 高度设置为 match_parent 时,它将起作用。 (我们使用RelativeLayout的原因是在ConstraintLayout上,你不能将layouth_height设置为子视图的match_parent,否则将无法正常工作。)

【讨论】:

我在 RelativeLayout 中有一个 recyclerView,高度为 0dp,位于两个视图之间。奇怪的是,将高度设置为 matchParent 就可以了。 (我也设置了“adjustPan”)【参考方案5】:

试试这个

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.scrollToPosition(yourPosition);

【讨论】:

【参考方案6】:

我遇到了同样的问题,我所做的是当键盘打开时,我将 recyclerView 滚动到 recyclerView 中的最后一项,所以不会隐藏任何项目。我认为这比您提出的方式要容易得多。 所以代码如下:

  recyclerView.postDelayed(new Runnable() 
            @Override
            public void run() 
                recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount() - 1);
            
        , 300);

【讨论】:

我已经做到了。我知道这很容易,但我不想要。我需要向上滚动它应该如何向上滚动。【参考方案7】:

将此写在您的清单中

    <activity
        android:name=".yourActivity"
        android:windowSoftInputMode="adjustResize" >
    </activity>

【讨论】:

以上是关于键盘打开时相应向上滚动 RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章

在android中打开键盘时设置滚动屏幕向上移动

移动 Safari 滚动页面键盘关闭

在键盘打开时将项目添加到 RecyclerView 时向下滚动

java 键盘打开时使内容可滚动

当键盘打开时,Popover 中的 UITableView 滚动出界

Android:回收站视图没有滚动到最后一个位置