ListView滚动监听

先展示效果:
ListView滚动监听 - 阿里云
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none"/>

代码:

package com.eg.lyx.listviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import static android.R.attr.data;
import static android.R.attr.y;
public class MainActivity extends AppCompatActivity {
private TextView tv;
private ListView lv;
private List data = new ArrayList<>();
private int lastVisibleItemPosition = 0;
private int mLastFirstPostion = 0;
private int mLastFirstTop;
private int touchSlop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
lv = (ListView) findViewById(R.id.lv);
initData();
lv.setAdapter(new MyAdapter(MainActivity.this, data));
// 还有一种方法,直接给ListView设置onTouchListener,在MOVE事件去判断这一次的y坐
// 标和上一次的y坐标大小关系从而进行判断,但是这样有个缺陷就是,当我们手指快速滑
// 动然后抬起的情况下,这时候ListView并没有马上停止仍会自动滑一段距离,而此时回调
// 却因为MOVE事件的不再产生无法继续执行回调。
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case SCROLL_STATE_IDLE://停止滑动时
break;
case SCROLL_STATE_TOUCH_SCROLL://正在滚动
break;
case SCROLL_STATE_FLING:
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int currentTop;
View firstChildView = view.getChildAt(0);
if (firstChildView != null) {
currentTop = view.getChildAt(0).getTop();
} else {
//ListView初始化的时候会回调onScroll方法,此时getChildAt(0)仍是为空的
return;
}
//判断上次可见的第一个位置和这次可见的第一个位置
if (firstVisibleItem != mLastFirstPostion) {
//不是同一个位置
if (firstVisibleItem > mLastFirstPostion) {
//TODO do down
// Log.i("cs", "—>down");
int firstVisiblePosition = view.getFirstVisiblePosition();
Log.i("cs", "firstVisiblePosition—>" + firstVisiblePosition);
tv.setText(data.get(firstVisiblePosition) + "DOWN");
} else {
//TODO do up
// Log.i("cs", "—>up");
int firstVisiblePosition = view.getFirstVisiblePosition();
Log.i("cs", "firstVisiblePosition—>" + firstVisiblePosition);
tv.setText(data.get(firstVisiblePosition) + "UP");
}
mLastFirstTop = currentTop;
} else {
//是同一个位置
int firstVisiblePosition = view.getFirstVisiblePosition();
Log.i("cs", "firstVisiblePosition—>" + firstVisiblePosition);
if (Math.abs(currentTop – mLastFirstTop) > touchSlop) {
//避免动作执行太频繁或误触,加入touchSlop判断,具体值可进行调整
if (currentTop > mLastFirstTop) {
//TODO :do up
//Log.i("cs", "equals—>up");
} else if (currentTop < mLastFirstTop) {
//TODO :do down
//Log.i("cs", "equals—>down");
}
mLastFirstTop = currentTop;
}
}
mLastFirstPostion = firstVisibleItem;
}
});
}
private void initData() {
for (int i = 0; i < 20; i++) {
data.add("卡片" + i);
}
}
}