Как передать до конца списка RecyclerView при добавлении нового элемента? [Дубликат]

php7:

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php7.0-fpm
sudo service apache2 restart
105
задан waylaidwanderer 27 October 2014 в 04:17
поделиться

16 ответов

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

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

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

Образец:

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

Подробности см. в документации .

156
ответ дан IcyFlame 21 August 2018 в 06:53
поделиться
  • 1
    Это может быть что-то полезное, но, похоже, оно не отвечает на заданный вопрос. – joseph 19 May 2015 в 10:47
  • 2
    recyclerView.setStackFromEnd (true) работал для меня – Ultimo_m 10 September 2015 в 20:16
  • 3
    Если вы установите как stackFromEnd = true, так и setReverseLayout = true, это не сработает. Кто-нибудь знает об обходном пути? – Luccas Correa 22 January 2016 в 17:55
  • 4
    Для просмотра чата работает linearLayoutManager.setStackFromEnd (true). – Muneeb Mirza 19 May 2016 в 11:37
  • 5
    Это вообще не затрагивает вопрос. – Orbit 23 June 2016 в 03:39

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

mRecyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
2
ответ дан abedfar 21 August 2018 в 06:53
поделиться

Для прокрутки вниз от любой позиции в 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);
            }
        });
7
ответ дан Anirudh Sharma 21 August 2018 в 06:53
поделиться

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

    mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mRecyclerView.scrollToPosition(mPosition);
            mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });
0
ответ дан Anky An 21 August 2018 в 06:53
поделиться

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

AdapterChart adapterChart = new AdapterChart(getContext(),messageList);
recyclerView.setAdapter(adapterChart);
recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount()-1);
2
ответ дан fantaghirocco 21 August 2018 в 06:53
поделиться

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

recycler.getLayoutManager().scrollToPosition(adapter.getItemCount() - 1);
1
ответ дан galex 21 August 2018 в 06:53
поделиться

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

    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);
0
ответ дан hasanga lakdinu 21 August 2018 в 06:53
поделиться
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.setReverseLayout(true);// Scroll to bottom
recyclerView.setLayoutManager(layoutManager);
-2
ответ дан LongLv 21 August 2018 в 06:53
поделиться
  • 1
    Пожалуйста, объясните, почему ваш ответ работает. – Rohit Gupta 24 December 2015 в 10:41

ЕСЛИ у вас есть адаптер, подключенный с помощью recyclerView, тогда просто сделайте это.

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

4
ответ дан Robert 21 August 2018 в 06:53
поделиться

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

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

recyclerView.scrollToPosition(items.size());

... что РАБОТАЕТ?

recyclerView.scrollToPosition(items.size() - 1);
263
ответ дан Roc Boronat 21 August 2018 в 06:53
поделиться
  • 1
    recyclerView.scrollToPosition(messages.size()-1); действительно работает для меня, мне просто интересно, почему. – Engine Bai 6 March 2015 в 11:01
  • 2
    Это сработало для меня. Это действительно имеет смысл, потому что списки Java основаны на нуле. Например. list [0,1,2] имеет размер 3, но последняя позиция равна 2, так как она начинается с 0. – Calvin 20 March 2015 в 08:46
  • 3
    FYI, для гладкой прокрутки есть smoothScrollToPosition(...). – Ivan Morgillo 17 July 2015 в 08:17
  • 4
    @Ivan Morgilo smoothScrollToPosition не работает вообще: S – cesards 30 July 2015 в 07:59
  • 5
    @IvanMorgillo - ваш ответ, похоже, лучше работает как с желаемым результатом, так и с более плавным = D. кажется, что прокрутка к позиции для меня немного багги (я предполагаю, что существует небольшая задержка между вызываемой функцией и созданием представления, так или иначе она не работает должным образом) – Roee 4 July 2016 в 15:42

Когда вы вызываете 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.
  }
});
8
ответ дан Saket 21 August 2018 в 06:53
поделиться
  • 1
    Спасибо, но это не сработает. Он ломает прокрутку, останавливаясь, отказываясь от работы, и, если вы перетаскиваете ее, она прокручивается странно быстро. – waylaidwanderer 27 October 2014 в 09:22
  • 2
    Похоже, вы не удаляете слушателя. Его следует вызывать только один раз (сразу после того, как элементы сначала выложены), а не во время прокрутки. – ianhanniballake 27 October 2014 в 14:47
  • 3
    OnGlobalLayoutListener, вероятно, не удаляется, потому что вы проверяете vto.isAlive(). Я не знаю причину, но ViewTreeObserver иногда изменяется для View, поэтому вместо проверки на isAlive вам лучше всего получить текущий ViewTreeObserver с conversationView.getViewTreeObserver().removeGlobalOnLayoutListener – Dmitry Zaytsev 12 January 2015 в 12:29
  • 4
    @ianhanniballake Я предложил редактирование, чтобы исправить эту проблему. – Saket 3 December 2017 в 15:01

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

recyclerView.scrollToPosition(mChatList.size() - 1);
1
ответ дан Shubham Agrawal 21 August 2018 в 06:53
поделиться

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

conversationView.smoothScrollToPosition(conversationView.getAdapter().getItemCount() - 1);
40
ответ дан Stan Kurilin 21 August 2018 в 06:53
поделиться
  • 1
    Это должно быть conversationView.smoothScrollToPosition(conversationView.getAdapter().getItemCount() **-1**);, поскольку позиции в списках основаны на нуле. – Berťák 1 December 2016 в 10:20
  • 2
    Это не поможет, если высота последней строки больше высоты экрана. – Anuj Jindal 16 January 2017 в 07:21

В Котлине:

recyclerView.viewTreeObserver.addOnGlobalLayoutListener { scrollToEnd() }

private fun scrollToEnd() =
        (adapter.itemCount - 1).takeIf { it > 0 }?.let(recyclerView::smoothScrollToPosition)
0
ответ дан yanchenko 21 August 2018 в 06:53
поделиться
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);

работает над кодом, но он не гладкий и не крутой.

4
ответ дан Yuki Yoshida 21 August 2018 в 06:53
поделиться
0
ответ дан chinnuabhi 1 November 2018 в 02:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: