参考自博文:http://my.oschina.net/u/816576/blog/345774
目的: 仅仅回弹阻尼效果而已,在顶部底部继续拉动有空白区域,松手后回弹。
代码一: XListViewSimple自定义
public class XListViewSimple extends ListView implements OnScrollListener {
private int paddingLeft = 0;
private int paddingRight = 0;
private int paddingTop = 0;
private int paddingBottom = 0;
private float lastY = 0;
private boolean isPull = true;// 是否下拉/上拉//true下拉、false上拉
private boolean isTop = true;// 是否滚动到第一行
private boolean isBottom = false;// 是否滚动到最后一行
private int scrollState = 0;
private Handler mHandler = new Handler();
public XListViewSimple(Context context) {
super(context);
init(context);
}
public XListViewSimple(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public XListViewSimple(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
// 初始化padding的值
paddingLeft = getPaddingLeft();
paddingRight = getPaddingRight();
paddingTop = getPaddingTop();
paddingBottom = getPaddingBottom();
//
setOnScrollListener(this);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
float y = ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = y;
break;
case MotionEvent.ACTION_MOVE:
float historicalY = ev.getY();
int dy = (int) (historicalY - lastY) / 3;
isPull = dy > 0;
if (isPull) {// 下拉
if (isTop && scrollState != SCROLL_STATE_FLING) {
//##scrollState!=SCROLL_STATE_FLING##
dy += paddingTop;
setPadding(paddingLeft, dy, paddingRight, paddingBottom);
setSelection(0);// 选中第一个item,不然没有下拉效果
//上面setSelection(0)我注释后貌似也没什么问题==、
}
} else {// 上拉
if (isBottom && scrollState != SCROLL_STATE_FLING) {
dy -= paddingBottom;
setPadding(paddingLeft, paddingTop, paddingRight, -dy);
setSelection(getCount());// 选中最后一个item,不然没有上拉效果
}
}
break;
case MotionEvent.ACTION_UP:// 回弹
if (isPull) {
int top = getPaddingTop();
int duration = 0;
while (top > paddingTop) {
top -= 10;
duration += 10;
final int t = top;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
setPadding(paddingLeft, t, paddingRight,
paddingBottom);
}
}, duration);
}
} else {
int bottom = getPaddingBottom();
int duration = 0;
while (bottom > paddingTop) {
bottom -= 10;
duration += 10;
final int b = bottom;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
setPadding(paddingLeft, paddingTop, paddingRight, b);
}
}, duration);
}
}
break;
}
return super.onTouchEvent(ev);
}
@Override
public void onScroll(AbsListView lv, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
isTop = firstVisibleItem == 0;//判断顶部或底部
isBottom = firstVisibleItem + visibleItemCount == totalItemCount;
}
@Override
public void onScrollStateChanged(AbsListView lv, int scrollState) {
this.scrollState = scrollState;//判断非FLING
}
代码二: activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<com.example.head.XListViewSimple
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mListView" />
</RelativeLayout>
代码三:MainActivity.java
public class MainActivity extends Activity {
private XListViewSimple mListView;
private ArrayList<String>arrayStr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView=(XListViewSimple)findViewById(R.id.mListView);
getArrayStr();
mListView.setAdapter(new ArrayAdapter(this,
android.R.layout.simple_list_item_1, arrayStr));
}
private void getArrayStr() {
arrayStr=new ArrayList<String>();
for(int i=0;i<20;i++){
arrayStr.add("item --->>"+i);
}
}
}
截图: