6

我有一个列表视图,可以根据请求添加其他视图,由 BaseAdapter 维护。更新后如何保持滚动位置?

我知道这已经被问过几次了,但是每次都提出了相同的解决方案,我已经尝试过,即adapter.notifyDataSetChanged();在更新包含列表内容的 ArrayList 后调用。

如何确保保持滚动位置?

4

5 回答 5

12

在您的活动类中实现一个OnScrollListener,然后使用以下代码:

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

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

private void isScrollCompleted() {

    if (currentFirstVisibleItem + currentVisibleItemCount >= currentTotalItemCount) {
        if (this.currentVisibleItemCount > 0
                && this.currentScrollState == SCROLL_STATE_IDLE) {

            //Do your work
        }
    }
}

如果您AsyncTask用于更新数据,则可以在您的中包含以下内容PostExecute()以保持滚动位置:

list.setAdapter(adapter);
list.setSelectionFromTop(currentFirstVisibleItem, 0);

我希望这有帮助。

于 2012-08-13T10:29:39.057 回答
5

我采取的方法是在更新后调用ListView.setSelection(position)以滚动到所需的位置position

根据您从哪里调用它,您可能需要在调用requestFocusFromTouch之前先调用它setSelection,以确保该项目得到适当的定位。

于 2012-08-09T06:35:36.607 回答
4

这段代码可以帮助你......

// get position of listview
int index = listView.getFirstVisiblePosition();
View v = listView.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();

// notify dataset changed or re-assign adapter here

//re-assign the position of listview after setting the adapter again
listView.setSelectionFromTop(index, top);

干杯:)

于 2015-01-13T05:29:37.210 回答
2

你可以试试这个:

//Get the top position from the first visible element
int fVisible = list.getFirstVisiblePosition();
View vFirst = list.getChildAt(0);
int pos = 0;
if (vFirst != null) pos = vFirst.getTop();

//Restore the position
list.setSelectionFromTop(fVisible, pos);
于 2012-08-09T06:40:57.537 回答
0

您可以执行以下操作。如果你想通过滚动到底部加载更多数据,它会有一些变化。

int currentFirstVisibleItem, currentScrollState;
int countChange = 0;
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
    Log.d("Scroll", "Scrolling");
    this.currentFirstVisibleItem = firstVisibleItem;
    countChange = 0;//during touching you can decide not to refresh by scroll
}

public void onScrollStateChanged(AbsListView view, int scrollState) {
    Log.d("Scroll", "Changed");
    this.currentScrollState = scrollState;
    if (scrollState == SCROLL_STATE_TOUCH_SCROLL) {
        countChange = 0;
    }
    if (++countChange > 1) {
        //scroll to top and release touch change=2. Simple scroll and release touch change=1
        this.isScrollCompleted();
        countChange = 0;
    }
}

private void isScrollCompleted() {
    Log.d("Load", "Reload");
    if (currentFirstVisibleItem == 0) {
        //Your loading go here
    }
}
于 2017-04-26T06:50:26.627 回答