Как прокрутить в нижней части RecyclerView? scrollToPosition не работает



Я хотел бы прокрутить в нижней части списка 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.

840   15  

15 ответов:

просто набор setStackFromEnd=true или setReverseLayout=true так что LLM будет макет элементов с конца.

разница между этими двумя заключается в том, что setStackFromEnd установит вид, чтобы показать последний элемент, направление компоновки останется прежним. (Таким образом, в горизонтальном представлении Recycler слева направо будет показан последний элемент, а прокрутка влево покажет более ранние элементы)

, тогда как setReverseLayout изменит порядок элементов, добавленных Адаптер. Макет начнется с последнего элемента, который будет самым левым в представлении ltr Recycler, а затем прокрутка вправо покажет более ранние элементы.

пример:

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

посмотреть документация для сведения.

Я смотрел на этот пост, чтобы найти ответ, но... Я думаю, что все на этом посту столкнулись с тем же сценарием, что и я:scrollToPosition() был полностью проигнорирован, по очевидной причине.

что я использовал?

recyclerView.scrollToPosition(items.size());

... что работала?

recyclerView.scrollToPosition(items.size() - 1);

Я знаю, что его поздно отвечать здесь, но если кто-то хочет знать Решение ниже

conversationView.smoothScrollToPosition(conversationView.getAdapter().getItemCount() - 1);

для прокрутки из любой позиции в recyclerview вниз

edittext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                rv_commentList.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                      rv_commentList.scrollToPosition(rv_commentList.getAdapter().getItemCount() - 1);
                    }
                }, 1000);
            }
        });

когда вы называете setAdapter, что не сразу выложат и позиции на экране (что занимает один проход макета), следовательно, ваш scrollToPosition() вызов не имеет фактических элементов для прокрутки при вызове его.

вместо этого, вы должны зарегистрировать ViewTreeObserver.OnGlobalLayoutListener (через addOnGlobalLayoutListner () С ViewTreeObserver создано conversationView.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.
  }
});
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);

выше код работает, но это не гладко и не круто.

если у вас есть адаптер, подключенный с recyclerView, то просто сделайте это.

mRecyclerView.smoothScrollToPosition(mRecyclerView.getAdapter().getItemCount());

Roc ответ является большим подспорьем. Я хотел бы добавить к нему небольшой блок:

mRecyclerView.scrollToPosition(mAdapter.getItemCount() - 1);

Это прекрасно работает для меня:

AdapterChart adapterChart = new AdapterChart(getContext(),messageList);
recyclerView.setAdapter(adapterChart);
recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount()-1);

добавить этот код после отправки сообщения и до получения сообщения с сервера

recyclerView.scrollToPosition(mChatList.size() - 1);

в моем случае, когда представления не имеют одинаковой высоты, вызов scrollToPosition на LayoutManager работал, чтобы действительно прокрутить вниз и полностью увидеть последний пункт:

recycler.getLayoutManager().scrollToPosition(adapter.getItemCount() - 1);

только ответ Яна смог сделать мой RecyclerView прокрутите до указанной позиции. Тем Не Менее,RecyclerView не удалось прокрутить впоследствии, когда я использовал scrollToPosition(). smoothScrollToPosition() работал, но начальная анимация сделала его слишком медленным, когда список был длинным. Причина была в том, что слушатель не был удален. Я использовал код ниже, чтобы удалить текущий ViewTreeObserver и он работал как шарм.

    mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mRecyclerView.scrollToPosition(mPosition);
            mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });

В Котлин:

recyclerView.viewTreeObserver.addOnGlobalLayoutListener { scrollToEnd() }

private fun scrollToEnd() =
        (adapter.itemCount - 1).takeIf { it > 0 }?.let(recyclerView::smoothScrollToPosition)

этот код даст вам последний пост первый, я думаю, что этот ответ полезен.

    mInstaList=(RecyclerView)findViewById(R.id.insta_list);
    mInstaList.setHasFixedSize(true);

    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);

    mInstaList.setLayoutManager(layoutManager);
    layoutManager.setStackFromEnd(true);
    layoutManager.setReverseLayout(true);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setReverseLayout(true);// Scroll to bottom
recyclerView.setLayoutManager(layoutManager);

Comments

    Ничего не найдено.