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




android-recyclerview