热门IT资讯网

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);    }}

然后想在哪用直接布局就行了。这种重写方法是不会和子控件的点击事件起冲突的。

0