android - studio - onscrollstatechanged new state



Внедрение onScrollListener для обнаружения конца прокрутки в ListView (6)

У меня есть ListView отображающий некоторые элементы. Я хотел бы выполнить некоторую операцию над элементами, которые в настоящее время отображаются в видимой части ListView , в зависимости от того, как прокручивается ListView ; поэтому я решил реализовать OnScrollListener из ListView . В соответствии с ссылкой на api для Android, метод onScroll будет вызван после завершения прокрутки. Мне это кажется правильным, поскольку, как только прокрутка завершена, я выполняю свои действия в ListView (метод onScroll возвращает индекс первого отображаемого элемента и количество отображаемых элементов).

Но после реализации я вижу из LogCat что метод onScroll не просто запускается после завершения прокрутки, но запускается для каждого нового элемента, который входит в представление отображения, от начала до конца прокрутки. Это не то поведение, которое я ожидаю, и мне не нужно. Другой метод прослушивателя (onScrollStateChanged) вместо этого не предоставляет информацию о элементах, отображаемых в настоящее время в ListView .

Итак, кто-нибудь знает, как использовать эту пару методов для обнаружения окончания прокрутки и получения информации об отображаемых элементах? Несоосность между ссылкой api и фактическим поведением метода немного смутила меня. Заранее спасибо.

PS: Я видел некоторые похожие темы, но ничто не помогает мне понять, как все это работает.!

https://src-bin.com


Answer #1

Анализируя предыдущие ответы, нашел свое:

В onViewCreated, onCreate или где бы вы не захватили ваш список:

ListView list = (ListView) view.findViewById(R.id.[your id]);
    list.setOnScrollListener(this);

Затем заполните методы слушателя:

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
 // yes, just leave it empty
}

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

private void isScrollCompleted(AbsListView view, int scrollState) {
    if (!view.canScrollVertically(1) && this.currentScrollState == SCROLL_STATE_IDLE) {
        // do work
    }
}

Кажется, он должен: обнаружить конец списка без тонны кода и модификаций адаптера.


Answer #2

В конце концов я достиг решения, которое не так элегантно, но это сработало для меня; выяснив, что метод onScroll вызывается для каждого шага прокрутки вместо того, чтобы просто вызываться в конце прокрутки, и что onScrollStateChanged фактически вызывается только при завершении прокрутки, я делаю что-то вроде этого:

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    this.currentFirstVisibleItem = firstVisibleItem;
    this.currentVisibleItemCount = visibleItemCount;
}

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

private void isScrollCompleted() {
    if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE) {
        /*** In this way I detect if there's been a scroll which has completed ***/
        /*** do the work! ***/
    }
}

Практически каждый раз, когда прокручивается ListView, я сохраняю данные о первом видимом элементе и счету видимого элемента (метод onScroll); когда состояние прокрутки изменяется (onScrollStateChanged), я сохраняю состояние, и я вызываю другой метод, который на самом деле понимает, был ли прокруток и завершен ли он. Таким образом, у меня также есть данные о видимых элементах, которые мне нужны. Может быть, не чисто, но работает!

С уважением


Answer #3

Просто более полезное представление ответа e-cal

Реализация прослушивателя:

public abstract class OnScrollFinishListener implements AbsListView.OnScrollListener {

    int mCurrentScrollState;
    int mCurrentVisibleItemCount;

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        mCurrentScrollState = scrollState;
        if (isScrollCompleted()) {
            onScrollFinished();
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        mCurrentVisibleItemCount = visibleItemCount;
    }

    private boolean isScrollCompleted() {
        return mCurrentVisibleItemCount > 0 && mCurrentScrollState == SCROLL_STATE_IDLE;
    }

    protected abstract void onScrollFinished();
}

Применение:

    listView.setOnScrollListener(new OnScrollFinishListener() {
         @Override
         protected void onScrollFinished() {
             // do whatever you need here!
         }
    });

Answer #4

Существует еще одно простое решение. Поместите прослушиватель в Adapter of listview и в getview проверьте, будет ли отображаться (position == totalItemCount элементов в массиве), если да, я вызываю своего слушателя из адаптера и в Listener. Запустите свою работу независимо от того,


Answer #5

Я столкнулся с множеством проблем, пытаясь выяснить, находится ли List в нижней части OnScrollListener, лучшим решением, которое я нашел, является проверка с помощью метода getView адаптера, если я не показываю последнюю строку:

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ActivityView view;
        if (convertView==null)
            view = (ActivityView)inflater.inflate(R.layout.activity_item, null);
        else
            view = (ActivityView)convertView;

       view.showRow(activitiesList.get(position),position,controller,this);
        if(position == activitiesList.size() - 1)
        {
            Log.i("BOTTOM","reached");
        }
        return view;
    }

там я могу легко создать интерфейс для уведомления Фрагмента / Действия, который я достиг дна.

веселит.


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

            if((firstVisibleItem + visibleItemCount) ==  totalItemCount)
            {
                Log.i("Info", "Scroll Bottom" );
            }
        }});




onscroll