Как прокручивать дно 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) 

Который не работает. В GENERIC_MESSAGE_LIST имеется 30 элементов.

Solutions Collecting From Web of "Как прокручивать дно RecyclerView? ScrollToPosition не работает"

Просто установите setStackFromEnd=true или setReverseLayout=true чтобы LLM закончила элементы макета.

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

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

Образец:

 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()); 

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

Вместо этого вы должны зарегистрировать ViewTreeObserver.OnGlobalLayoutListener (через addOnGlobalLayoutListner () из ViewTreeObserver созданный conversationView.getViewTreeObserver() ViewTreeObserver conversationView.getViewTreeObserver() ), который задерживает ваш scrollToPosition() до тех пор, пока не пройдет первый переход макета:

 final ViewTreeObserver vto = conversationView.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { public void onGlobalLayout() { conversationView.scrollToPosition(GENERIC_MESSAGE_LIST.size(); if (vto.isAlive()) { // Unregister the listener to only call scrollToPosition once vto.removeGlobalOnLayoutListener(this); // Use vto.removeOnGlobalLayoutListener(this) on API16+ devices as // removeGlobalOnLayoutListener is deprecated. // They do the same thing, just a rename so your choice. } } }); 

Скроллинг от любой позиции в 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); } }); 
 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());

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

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

Ответ Рока – отличная помощь. Я хотел бы добавить к нему небольшой блок:

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

Это отлично работает для меня:

 AdapterChart adapterChart = new AdapterChart(getContext(),messageList); recyclerView.setAdapter(adapterChart); recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount()-1); 
 recyclerView.setHasFixedSize(true); LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); layoutManager.setReverseLayout(true);// Scroll to bottom recyclerView.setLayoutManager(layoutManager);