Android仿qq回弹阻尼ScrollView
发表于:2024-11-24 作者:热门IT资讯网编辑
编辑最后更新 2024年11月24日,仿qq写一个可以来回弹的ScrollView.只需要重写ScrollView:public class MyScrollView extends ScrollView { // y方向上当前触摸
仿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); }}
然后想在哪用直接布局就行了。这种重写方法是不会和子控件的点击事件起冲突的。