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

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

【问题讨论】:

  • 我试过了,还是不行。
  • android:windowSoftInputMode="adjustPan" 试试这个。
  • 好吧,我不想滚动到最后一项@HemantParmar
  • 这也不起作用@mehul

标签: android scroll android-recyclerview android-edittext keyboard


【解决方案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_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@id/editText"
            app:layout_constraintTop_toBottomOf="parent" />
        
          <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent" />
        
        </androidx.constraintlayout.widget.ConstraintLayout>
        
        

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

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

        <RelativeLayout>
        
          <RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_above="@id/editText"
            android:layout_height="match_parent" <!-- This is important, with 0dp it still doesnt work  -->
             />
        
          <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            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>
          

          【讨论】:

            猜你喜欢
            • 2016-12-17
            • 2022-10-09
            • 2017-08-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-09
            • 2020-12-06
            • 1970-01-01
            相关资源
            最近更新 更多