180

アクティビティを読み込んだ後、RecyclerView リストの一番下までスクロールしたいと思います。

GENERIC_MESSAGE_LIST = (ArrayList) intent.getExtras().getParcelableArrayList(ConversationsAdapter.EXTRA_MESSAGE);
conversationView = (RecyclerView) findViewById(R.id.list_messages);
conversationView.setHasFixedSize(true);
conversationViewLayoutManager = new LinearLayoutManager(this);
conversationView.setLayoutManager(conversationViewLayoutManager);
conversationViewAdapter = new ConversationAdapter(GENERIC_MESSAGE_LIST, this);
conversationView.setAdapter(conversationViewAdapter);

conversationView.scrollTo(...)RecyclerView でサポートされていないという例外をスローし、conversationView.scrollToPosition(...)何もしていないようです。

上記のコードブロックの後に、追加しました

conversationView.scrollToPosition(GENERIC_MESSAGE_LIST.size() + 1)

これは機能しません。には 30 個の要素がありますGENERIC_MESSAGE_LIST

4

27 に答える 27

221

LLMがアイテムを最後からレイアウトするように設定setStackFromEnd=trueするだけです。setReverseLayout=true

これら 2 つの違いはsetStackFromEnd、最後の要素を表示するようにビューを設定し、レイアウトの方向は同じままであることです。(したがって、左から右への水平のリサイクラー ビューでは、最後の要素が表示され、左にスクロールすると前の要素が表示されます)

一方setReverseLayout、アダプターによって追加された要素の順序を変更します。レイアウトは、LTR Recycler ビューの一番左にある最後の要素から開始され、右にスクロールすると前の要素が表示されます。

サンプル:

final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setReverseLayout(true);
_listView.setLayoutManager(linearLayoutManager);

詳細については、ドキュメントを参照してください。

于 2014-11-21T20:32:44.637 に答える
35

リサイクラービューの任意の位置から下にスクロールダウンするには

コトリン

editText.setOnClickListener {
    rv.postDelayed({                 
        rv.scrollToPosition(rv.adapter.itemCount - 1)
    }, 1000)
}

ジャワ

edittext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                rv.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                      rv.scrollToPosition(rv.getAdapter().getItemCount() - 1);
                    }
                }, 1000);
            }
        });
于 2015-11-04T07:33:54.303 に答える
17

メッセージを送信した後、サーバーからメッセージを取得する前に、このコードを追加します

recyclerView.scrollToPosition(mChatList.size() - 1);
于 2018-07-06T11:11:55.540 に答える
11

を呼び出すとsetAdapter、画面上にアイテムがすぐにレイアウトおよび配置されないため (単一のレイアウト パスが必要です)、scrollToPosition()呼び出し時にスクロールする実際の要素がありません。

代わりに、 ViewTreeObserver.OnGlobalLayoutListener を ( created byからaddOnGlobalLayoutListner ()を介して) 登録する必要があります。これにより、最初のレイアウト パスの後まで遅延が発生します。ViewTreeObserverconversationView.getViewTreeObserver()scrollToPosition()

conversationView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  public void onGlobalLayout() {
    conversationView.scrollToPosition(GENERIC_MESSAGE_LIST.size();
    // Unregister the listener to only call scrollToPosition once
    conversationView.getViewTreeObserver().removeGlobalOnLayoutListener(this);

    // Use vto.removeOnGlobalLayoutListener(this) on API16+ devices as 
    // removeGlobalOnLayoutListener is deprecated.
    // They do the same thing, just a rename so your choice.
  }
});
于 2014-10-27T05:54:10.083 に答える
7

Kotlinのソリューション:

「recyclerView.adapter」を設定した後、または「recyclerView.adapter.notifyDataSetChanged()」の後に以下のコードを適用します

recyclerView.scrollToPosition(recyclerView.adapter.itemCount - 1)
于 2018-10-31T08:13:24.250 に答える
5
class MyLayoutManager extends LinearLayoutManager {

  public MyLayoutManager(Context context) {
    super(context, LinearLayoutManager.VERTICAL, false);
  }

  @Override public void smoothScrollToPosition(RecyclerView recyclerView,
      final RecyclerView.State state, final int position) {

    int fcvip = findFirstCompletelyVisibleItemPosition();
    int lcvip = findLastCompletelyVisibleItemPosition();

    if (position < fcvip || lcvip < position) {
      // scrolling to invisible position

      float fcviY = findViewByPosition(fcvip).getY();
      float lcviY = findViewByPosition(lcvip).getY();

      recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {

        int currentState = RecyclerView.SCROLL_STATE_IDLE;

        @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

          if (currentState == RecyclerView.SCROLL_STATE_SETTLING
              && newState == RecyclerView.SCROLL_STATE_IDLE) {

            // recursive scrolling
            smoothScrollToPosition(recyclerView, state, position);
          }

          currentState = newState;
        }

        @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

          int fcvip = findFirstCompletelyVisibleItemPosition();
          int lcvip = findLastCompletelyVisibleItemPosition();

          if ((dy < 0 && fcvip == position) || (dy > 0 && lcvip == position)) {
            // stop scrolling
            recyclerView.setOnScrollListener(null);
          }
        }
      });

      if (position < fcvip) {
        // scroll up

        recyclerView.smoothScrollBy(0, (int) (fcviY - lcviY));
      } else {
        // scroll down

        recyclerView.smoothScrollBy(0, (int) (lcviY - fcviY));
      }
    } else {
      // scrolling to visible position

      float fromY = findViewByPosition(fcvip).getY();
      float targetY = findViewByPosition(position).getY();

      recyclerView.smoothScrollBy(0, (int) (targetY - fromY));
    }
  }
}

MyLayoutManager layoutManager = new MyLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);

RecyclerView.Adapter adapter = new YourAdapter();
recyclerView.setAdapter(adapter);

recyclerView.smoothScrollToPosition(adapter.getItemCount() - 1);

上記のコードは機能しますが、スムーズではなく、クールでもありません。

于 2014-10-28T13:45:49.297 に答える
0

これらのいずれも機能しなかった場合、

あなたは使用しようとする必要があります:

ConstraintLayout targetView = (ConstraintLayout) recyclerView.findViewHolderForAdapterPosition(adapter.getItemCount()-1).itemView;
targetView.getParent().requestChildFocus(targetView, targetView);

これを行うことで、特定の ConstraintLayout (またはあなたが持っているもの) を表示するように要求しています。スクロールは一瞬です。

キーボードが表示されていても動作します。

于 2020-06-22T00:55:17.357 に答える