仿qq写一个可以来回弹的ScrollView.
只需要重写ScrollView:
public class MyScrollView extends ScrollView { // y方向上当前触摸点的前一次记录位置 private int previousY = 0; // y方向上的触摸点的起始记录位置 private int startY = 0; // y方向上的触摸点当前记录位置 private int currentY = 0; // y方向上两次移动间移动的相对距离 private int deltaY = 0; // 第一个子视图 private View childView; // 用于记录childView的初始位置 private Rect topRect = new Rect(); public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public MyScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @SuppressLint("MissingSuperCall") @Override protected void onFinishInflate() { if (getChildCount() > 0) { childView = getChildAt(0); } } @Override public boolean dispatchTouchEvent(MotionEvent event) { if (null == childView) { return super.dispatchTouchEvent(event); } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startY = (int) event.getY(); previousY = startY; break; case MotionEvent.ACTION_MOVE: currentY = (int) event.getY(); deltaY = previousY - currentY; previousY = currentY; if (0 == getScrollY() || childView.getMeasuredHeight() - getHeight() <= getScrollY()) { // 记录childView的初始位置 if (topRect.isEmpty()) { topRect.set(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom()); } // 更新childView的位置 childView.layout(childView.getLeft(), childView.getTop() - deltaY / 3, childView.getRight(), childView.getBottom() - deltaY / 3); } break; case MotionEvent.ACTION_UP: if (!topRect.isEmpty()) { upDownMoveAnimation(); // 子控件回到初始位置 childView.layout(topRect.left, topRect.top, topRect.right, topRect.bottom); } startY = 0; currentY = 0; topRect.setEmpty(); break; default: break; } return super.dispatchTouchEvent(event); } // 初始化上下回弹的动画效果 private void upDownMoveAnimation() { TranslateAnimation animation = new TranslateAnimation(0.0f, 0.0f, childView.getTop(), topRect.top); animation.setDuration(100); animation.setInterpolator(new AccelerateInterpolator()); childView.setAnimation(animation); } }
然后想在哪用直接布局就行了。这种重写方法是不会和子控件的点击事件起冲突的。
本文出自 “Android开发专栏” 博客,请务必保留此出处http://liuyvhao.blog.51cto.com/11690759/1836527
原文地址:http://liuyvhao.blog.51cto.com/11690759/1836527