Android ScrollView反弹效果的实现

               
/** * ScrollView反弹效果的实现 */public class BounceScrollView extends ScrollView private View inner;// 孩子View private float y;// 点击时y坐标 private Rect normal = new Rect();// 矩形(这里只是个形式,只是用于判断是否需要动画.) private boolean isCount = false;// 是否开始计算 public BounceScrollView(Context context, AttributeSet attrs) {  super(context, attrs); } /***  * 根据 XML 生成视图工作完成.该函数在生成视图的最后调用,在所有子视图添加完之后. 即使子类覆盖了 onFinishInflate  * 方法,也应该调用父类的方法,使该方法得以执行.  */ @Override protected void onFinishInflate() {  if (getChildCount() > 0) {   inner = getChildAt(0);  } } /***  * 监听touch  */ @Override public boolean onTouchEvent(MotionEvent ev) {  if (inner != null) {   commOnTouchEvent(ev);  }  return super.onTouchEvent(ev); } /***  * 触摸事件  *   * @param ev  */ public void commOnTouchEvent(MotionEvent ev) {  int action = ev.getAction();  switch (action) {  case MotionEvent.ACTION_DOWN:   break;  case MotionEvent.ACTION_UP:   // 手指松开.   if (isNeedAnimation()) {    animation();    isCount = false;   }   break;  /***   * 排除出第一次移动计算,因为第一次无法得知y坐标, 在MotionEvent.ACTION_DOWN中获取不到,   * 因为此时是MyScrollView的touch事件传递到到了LIstView的孩子item上面.所以从第二次计算开始.   * 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归0. 之后记录准确了就正常执行.   */  case MotionEvent.ACTION_MOVE:   final float preY = y;// 按下时的y坐标   float nowY = ev.getY();// 时时y坐标   int deltaY = (int) (preY - nowY);// 滑动距离   if (!isCount) {    deltaY = 0; // 在这里要归0.   }   y = nowY;   // 当滚动到最上或者最下时就不会再滚动,这时移动布局   if (isNeedMove()) {    // 初始化头部矩形    if (normal.isEmpty()) {     // 保存正常的布局位置     normal.set(inner.getLeft(), inner.getTop(),       inner.getRight(), inner.getBottom());    }    Log.e("jj", "矩形:" + inner.getLeft() + "," + inner.getTop()      + "," + inner.getRight() + "," + inner.getBottom());    // 移动布局    inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2,      inner.getRight(), inner.getBottom() - deltaY / 2);   }   isCount = true;   break;  default:   break;  } } /***  * 回缩动画  */ public void animation() {  // 开启移动动画  TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),    normal.top);  ta.setDuration(200);  inner.startAnimation(ta);  // 设置回到正常的布局位置  inner.layout(normal.left, normal.top, normal.right, normal.bottom);  Log.e("jj", "回归:" + normal.left + "," + normal.top + "," + normal.right    + "," + normal.bottom);  normal.setEmpty(); } // 是否需要开启动画 public boolean isNeedAnimation() {  return !normal.isEmpty(); } /***  * 是否需要移动布局 inner.getMeasuredHeight():获取的是控件的总高度  *   * getHeight():获取的是屏幕的高度  *   * @return  */ public boolean isNeedMove() {  int offset = inner.getMeasuredHeight() - getHeight();  int scrollY = getScrollY();  Log.e("jj", "scrolly=" + scrollY);  // 0是顶部,后面那个是底部  if (scrollY == 0 || scrollY == offset) {   return true;  }  return false; }}

使用方法

<com.techrare.view.BounceScrollView          android:layout_width="fill_parent"          android:layout_height="fill_parent"          android:background="@color/tab_chart_bg"          android:scrollbars="none" >            <LinearLayout              android:layout_width="fill_parent"              android:layout_height="match_parent"              android:gravity="center_horizontal"              android:orientation="vertical"              android:paddingLeft="20dp"              android:paddingRight="20dp" >  <span style="white-space:pre">      </span><!-- 这里可以尽情的布局 -->          </LinearLayout>  </com.techrare.view.BounceScrollView>  

原文地址http://blog.youkuaiyun.com/h7870181/article/details/8960430

           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值