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