java - كيفية التمرير إلى الجزء السفلي من RecyclerView؟ لا يعمل scrollToPosition
android android-recyclerview (10)
Roc الجواب هو مساعدة كبيرة. أود إضافة جزء صغير إليه:
mRecyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
أرغب في التمرير إلى أسفل قائمة 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
.
أعرف أن تأخر الرد هنا ، لا يزال إذا كان أي شخص يريد أن يعرف الحل أدناه
conversationView.smoothScrollToPosition(conversationView.getAdapter().getItemCount() - 1);
تمكنت إجابة Ian فقط من جعل RecyclerView
بي التمرير إلى موضع محدد. ومع ذلك ، RecyclerView
لم يكن قادراً على التمرير فيما بعد عندما استخدمت scrollToPosition()
. عملت smoothScrollToPosition()
ولكن الرسوم المتحركة الأولية جعلها بطيئة للغاية عندما كانت القائمة طويلة. كان السبب لم يتم إزالة المستمع. لقد استخدمت الرمز أدناه لإزالة ViewTreeObserver
الحالي وعمل كسحر.
mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mRecyclerView.scrollToPosition(mPosition);
mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
سيعطيك هذا الرمز أحدث مشاركة أولاً ، وأعتقد أن هذه الإجابة مفيدة.
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);
في حالتي التي لا يكون فيها الارتفاع في نفس المشاهدات ، يعمل scrollToPosition على LayoutManager على التمرير حقًا إلى الأسفل ومشاهدة العنصر الأخير بالكامل:
recycler.getLayoutManager().scrollToPosition(adapter.getItemCount() - 1);
في كوتلين:
recyclerView.viewTreeObserver.addOnGlobalLayoutListener { scrollToEnd() }
private fun scrollToEnd() =
(adapter.itemCount - 1).takeIf { it > 0 }?.let(recyclerView::smoothScrollToPosition)
للتمرير من أي موضع في 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);
}
});
ما عليك setStackFromEnd=true
تعيين setStackFromEnd=true
أو setReverseLayout=true
حتى تقوم LLM setReverseLayout=true
العناصر من النهاية.
الفرق بين هذين هو أن setStackFromEnd
سيحدد العرض لإظهار العنصر الأخير ، سيبقى اتجاه التخطيط على حاله. (لذا ، في عرض Recycler الأفقي من اليسار إلى اليمين ، سيتم عرض العنصر الأخير وسيعرض التمرير إلى اليسار العناصر السابقة)
في حين أن setReverseLayout
سيغير ترتيب العناصر التي أضافها المحول. سيبدأ التخطيط من العنصر الأخير ، والذي سيكون أقصى اليسار في عرض LTR Recycler ومن ثم ، سيظهر التمرير إلى اليمين العناصر السابقة.
عينة:
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setReverseLayout(true);
_listView.setLayoutManager(linearLayoutManager);
انظر documentation للحصول على التفاصيل.
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.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setReverseLayout(true);// Scroll to bottom
recyclerView.setLayoutManager(layoutManager);