Подтвердить что ты не робот

Как узнать, прокручивается ли ListView в верхней части позиции?

У меня есть ListView, сначала его прокрутка вниз, теперь, когда мы прокручиваем вверх, он достигает наибольшей точки. Я хочу обнаружить это. Есть ли способ? Я разрабатываю приложение с помощью api level 8.Pls help.

4b9b3361

Ответ 1

изменить

См. комментарии ниже о том, почему, особенно в разных версиях API (более поздние версии), это не надежный способ увидеть, есть ли список наверху (дополнение и т.д.). Тем не менее, это дает вам начало для решения на устройствах ниже API 14:

private boolean listIsAtTop()   {   
    if(listView.getChildCount() == 0) return true;
    return listView.getChildAt(0).getTop() == 0;
}

Что касается моей реализации много лет назад - это отлично работало в то время.

Ответ 2

Я знаю, что этот вопрос старый, но он отображается в результатах поиска Google. В API-интерфейс 14 появился новый метод, который дает именно то, что нам нужно:

http://developer.android.com/reference/android/view/View.html#canScrollVertically%28int%29

Для старых платформ в библиотеке поддержки v4 можно использовать аналогичные статические методы ViewCompat. См. править ниже.

В отличие от метода Грэм, этот метод не защищен от проблем, вызванных повторным использованием внутреннего представления ListView и/или смещением заголовка.

Изменить: окончательное решение

Я нашел метод в исходном коде SwipeRefreshLayout, который обрабатывает это. Его можно переписать как:

public boolean canScrollUp(View view) {
  if (android.os.Build.VERSION.SDK_INT < 14) {
    if (view instanceof AbsListView) {
      final AbsListView absListView = (AbsListView) view;
      return absListView.getChildCount() > 0
          && (absListView.getFirstVisiblePosition() > 0 || absListView
              .getChildAt(0).getTop() < absListView.getPaddingTop());
    } else {
      return view.getScrollY() > 0;
    }
  } else {
    return ViewCompat.canScrollVertically(view, -1);
  }
}

Вам может потребоваться добавить пользовательскую логику, если представление с включенным представлением является настраиваемым.

Ответ 3

Мои друзья, комбинируя Graeme ответ с помощью метода onScroll...

listView.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {

    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if(firstVisibleItem == 0 && listIsAtTop()){
            swipeRefreshLayout.setEnabled(true);
        }else{
            swipeRefreshLayout.setEnabled(false);
        }
    }
});


private boolean listIsAtTop()   {
    if(listView.getChildCount() == 0) return true;
    return listView.getChildAt(0).getTop() == 0;
}

Ответ 4

Вам нужно будет проверить, что является первой видимой позицией, а затем применить решение Graeme, чтобы увидеть, находится ли первый видимый элемент списка в верхней позиции.

Что-то вроде lv.getFirstVisiblePosition() == 0 && & (lv.getChildCount() == 0 || lv.getChildAt(0).getTop() == 0)

Ответ 5

Вы можете использовать OnScrollListener, чтобы получать уведомление о том, что теперь отображается позиция 0. Используйте метод onScroll.

Ответ 6

Этот вопрос старый, но у меня есть решение, которое отлично работает, и возможно, что это работает для тех, кто ищет решение.

int limitRowsBDshow = 10; //size limit your list
listViewMessages.setOnScrollListener(new AbsListView.OnScrollListener() {
        int counter = 1;
        int currentScrollState;
        int currentFirstVisibleItem;
        int currentVisibleItemCount;
        int currentTotalItemCount;


        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            this.currentScrollState = scrollState;
            this.isScrollCompleted();
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

            this.currentFirstVisibleItem = firstVisibleItem;
            this.currentVisibleItemCount = visibleItemCount;
            this.currentTotalItemCount = totalItemCount;
        }

        private void isScrollCompleted() {
            if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
                /*** detect if there been a scroll which has completed ***/

                counter++;
                if (currentFirstVisibleItem == 0 && currentTotalItemCount > limitRowsBDshow - 1) {
                     linearLay20msgMas.setVisibility(View.VISIBLE);
                }
            }
        }
    });

Этот код найден некогда (здесь StackOverflow). Но я не могу найти это, чтобы упомянуть

Ответ 7

Ответ Graeme близок, но отсутствует то, что добавил user2036198, чек для getFirstVisiblePosition(). getChildAt (0) не возвращает самый первый вид для самого первого элемента в списке. Реализации AbsListView не создают единого представления для каждой позиции и не сохраняют их в памяти. Вместо этого просмотр вторсырья вступает в силу, чтобы ограничить количество создаваемых представлений в любой момент времени.

Исправление довольно просто:

public boolean canScrollVertically(AbsListView view) {
    boolean canScroll = false;

    if (view != null && view.getChildCount() > 0) {
        // First item can be partially visible, top must be 0 for the item
        canScroll = view.getFirstVisiblePosition() != 0 || view.getChildAt(0).getTop() != 0;
    }

    return canScroll;
}

Для получения наилучших результатов в ICS или выше, всегда используйте ViewCompat из библиотеки поддержки v4 или View.canScrollVertically(). Используйте вышеуказанный метод на более низких уровнях API, поскольку ViewCompat всегда возвращает false для canScrollVertically() и canScrollHorizontally() ниже ICS.

Ответ 8

Если вы можете расширить ListView напрямую, вы можете использовать защищенный метод, называемый "computeVerticalScrollOffset()" внутри метода переопределения "onScrollChanged()".

С защищенным методом return 0, означает, что ваш ListView теперь достиг вершины.

Фрагмент кода

        listView = new ListView(this){
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);

            if( computeVerticalScrollOffset() == 0 ){
                // Reach top
            }
        }

Ответ 9

Слишком поздно, но попробуйте этот, он хорошо работает в RecyclerView. -1, чтобы проверить, может ли он прокрутить вверх, в то время как 1, чтобы проверить, может ли он прокрутить вниз

if (listView.canScrollVertically(-1))
   listView.smoothScrollToPosition(0);
else
   onBackPressed();

Ответ 10

lstView.setOnScrollListener(new AbsListView.OnScrollListener() {

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                //To change body of implemented methods use File | Settings | File Templates.
                if (0 == firstVisibleItem){
                    Toast.makeText(MyActivity.this, "Scroll to Top ", Toast.LENGTH_SHORT).show();
                }
            }
        });