public class BounceListView extends ListView implements AbsListView.OnScrollListener {
/**
* the header view
*/
View mHeaderView;
/**
* the footer view
*/
View mFooterView;
/**
* current scroll state
*/
int mCurrentScrollState;
/**
* the y coordinate of last motion event
*/
int mLastY;
// create the HeaderView
mHeaderView = LayoutInflater.from(context).inflate(R.layout.item_bounce_header, this, false);
// and add it into the header
addHeaderView(mHeaderView);
// create the FooterView
mFooterView = LayoutInflater.from(context).inflate(R.layout.item_bounce_footer, this, false);
// and add it into the footer
addFooterView(mFooterView);
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
// the new y position
int y = (int) event.getY();
switch (event.getAction()) {
// the gesture is released
case MotionEvent.ACTION_UP:
// the first item is visible and the header view is not entire visible
if (getFirstVisiblePosition() == 0 &&
(mHeaderView.getBottom() < 0 || mHeaderView.getTop() <= 0)) {
resetHeaderPadding();
}
break;
case MotionEvent.ACTION_DOWN:
// record the initial y position
mLastY = y;
break;
case MotionEvent.ACTION_MOVE:
changeHeaderPadding(event);
break;
}
return super.onTouchEvent(event);
}
在写安卓应用中, 有时不得不抄一抄iOS中的Bounces效果, 也就是说在上拉或下拉时能过超过原来的大小限制.
解决这个问题的思路是给
ListView
添加Header和Footer, 然后实现自己的onTouchEvent
, 在需要时增加Header和Footer的padding.首先我们继承
ListView
并添加相关属性:我们添加了对Header View和Footer View的引用, 还存有当前的滑动状态, 以及最后点击屏幕时的y坐标.
由于只需要Bounces效果, Header View以及Footer View都可以用最简单的View.
代码中提到的
R.layout.item_bounce_header
和R.layout.item_bounce_footer
都是一个非常简单的布局文件, 仅是一个空的LinearLayout
, 直接用View
也是可以的.由于顶部的Bounces和底部的Bounces实现很类似, 我只描述顶部Bounces的效果如何实现. 首先我们得自己实现
onTouchEvent
方法.首先我们在开始滑动动作时记录y坐标, 即
MotionEvent.ACTION_DOWN
, 在滑动结束(MotionEvent.ACTION_UP
)时, 如果Header View并不可见, 就要将其的padding重新设置为0, 由于是顶部的Bounces效果, 修改topPadding即可. 还在滑动过程中(MotionEvent.ACTION_MOVE
)时, 就要时刻改变Header View的topPadding.改变padding的方法实现如下:
也很简单, 就是取出所有的点左边, 一下一下移动padding.
看这行代码:
int topPadding = ((histY - mLastY)) / 2
, 这里的2是硬编码的一个数值, 表示下滑的位移与顶部padding增加的数量之间的比例, 越大表示padding增加的越慢.另外, 关于重设padding, 因为要动画效果, 这个时候就要动画了,
ValueAnimator
就起了作用:嗯, 要实现Bounces效果看懂上面这些代码就OK了.