码迷,mamicode.com
首页 > 移动开发 > 详细

Android仿qq回弹阻尼ScrollView

时间:2016-08-10 23:14:48      阅读:448      评论:0      收藏:0      [点我收藏+]

标签:android   scrollview   

仿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

Android仿qq回弹阻尼ScrollView

标签:android   scrollview   

原文地址:http://liuyvhao.blog.51cto.com/11690759/1836527

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!