温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android仿qq回弹阻尼ScrollView

发布时间:2020-03-24 11:31:32 来源:网络 阅读:2453 作者:liuyvhao 栏目:移动开发

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

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI