【发布时间】:2011-11-11 05:08:30
【问题描述】:
我有一个 ListView,首先它向下滚动,现在当我们向上滚动时,它到达最高点。我想检测到。有什么办法吗?我正在使用 api 级别 8 开发应用程序。请帮助..
【问题讨论】:
标签: android
我有一个 ListView,首先它向下滚动,现在当我们向上滚动时,它到达最高点。我想检测到。有什么办法吗?我正在使用 api 级别 8 开发应用程序。请帮助..
【问题讨论】:
标签: android
编辑
请参阅下面的 cmets 了解原因,尤其是在不同的 API 版本(尤其是更高版本)上,这不是查看列表是否位于顶部(填充等)的万无一失的方法。但是,它确实为您在 API 14 以下的设备上提供了一个解决方案:
private boolean listIsAtTop() {
if(listView.getChildCount() == 0) return true;
return listView.getChildAt(0).getTop() == 0;
}
就我几年前的实施而言 - 这在当时非常有效。
【讨论】:
我知道这个问题很老,但它显示在 Google 搜索结果的顶部。 API 级别 14 中引入了一种新方法,它提供了我们所需要的:
http://developer.android.com/reference/android/view/View.html#canScrollVertically%28int%29
对于旧平台,可以在 v4 支持库中使用类似的静态方法 请参阅下面的编辑。ViewCompat。
与 Graeme 的方法不同,此方法不会因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);
}
}
如果传入的视图是自定义视图,您可能需要添加自定义逻辑。
【讨论】:
朋友们,将 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;
}
【讨论】:
您需要检查第一个可见位置是什么,然后应用 Graeme 的解决方案来查看第一个可见列表视图项是否位于顶部位置。
类似的东西 lv.getFirstVisiblePosition() == 0 && (lv.getChildCount() == 0 || lv.getChildAt(0).getTop() == 0)
【讨论】:
您可以使用OnScrollListener 来通知位置 0 现在可见。使用onScroll方法。
【讨论】:
这个问题很老,但我有一个完美的解决方案,它可能适用于寻找解决方案的人。
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's been a scroll which has completed ***/
counter++;
if (currentFirstVisibleItem == 0 && currentTotalItemCount > limitRowsBDshow - 1) {
linearLay20msgMas.setVisibility(View.VISIBLE);
}
}
}
});
这段代码是很久以前找到的(这里是 StackOverflow)。但是我找不到这个要提
【讨论】:
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 或更高版本上获得最佳效果,请始终使用 v4 支持库中的 ViewCompat 或 View.canScrollVertically()。在较低的 API 级别上使用上述方法,因为 ViewCompat 总是为 ICS 下的 canScrollVertically() 和 canScrollHorizontally() 返回 false。
【讨论】:
如果你可以直接扩展 ListView,那么你可以在覆盖方法“onScrollChanged()”中使用名为“computeVerticalScrollOffset()”的受保护方法。
使用受保护的方法返回 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
}
}
【讨论】:
为时已晚,但试试这个,它在 RecyclerView 中运行良好。 -1 检查是否可以滚动到顶部,而 1 是检查是否可以滚动到底部
if (listView.canScrollVertically(-1))
listView.smoothScrollToPosition(0);
else
onBackPressed();
【讨论】:
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();
}
}
});
【讨论】: