2019-04-09 弹性滑动NestedScrollView

ios里面所有的scrollview都是弹性滑动,而安卓里面则没有这个效果,但是UE要求和Ios的效果一样,所以只能自己实现。

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.TranslateAnimation;

/**
 * Data:2019/4/3-下午4:49
 * Author:zxf
 **/
public class DemoScrollView extends NestedScrollView {

    private Rect normal = new Rect();// 矩形,保存scrollview原始位置

    private boolean isScrolledToTop = true;
    private boolean isScrolledToBottom;

    float currentY=0;
   float distanceY=0;

    private View mInner;
    public DemoScrollView(@NonNull Context context) {
        super(context);
    }

    public DemoScrollView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public DemoScrollView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (getScrollY() == 0) {    // 小心踩坑1: 这里不能是getScrollY() <= 0
            isScrolledToTop=true;
            isScrolledToBottom=false;
        } else if (getScrollY() + getHeight() - getPaddingTop()-getPaddingBottom() == getChildAt(0).getHeight()) {
            isScrolledToTop=false;
            isScrolledToBottom=true;
        } else {
            isScrolledToTop=false;
            isScrolledToBottom=false;
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (getChildCount()>0)
            mInner= (ViewGroup) getChildAt(0);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                currentY=  ev.getY();
                //finalY=ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                distanceY= currentY-ev.getY();
                if (normal.isEmpty()){
                    normal.set(mInner.getLeft(),  mInner.getTop(),mInner.getRight(),  mInner.getBottom());
                }
                //到达最顶端
                if (isScrolledToTop || isScrolledToBottom){
                    mInner.layout(mInner.getLeft(),  (mInner.getTop()-(int)distanceY/10),mInner.getRight(), (int) (mInner.getBottom()-(int)distanceY/10));
                }
                break;
            case MotionEvent.ACTION_UP:
                distanceY=0;
                //弹性动画恢复到原位置
                TranslateAnimation translateAnimation=new TranslateAnimation(0,0,mInner.getTop(),normal.top);
                translateAnimation.setDuration(100);
                mInner.startAnimation(translateAnimation);
                mInner.layout(normal.left, normal.top, normal.right, normal.bottom);
                normal.setEmpty();
                break;
        }
        return super.dispatchTouchEvent(ev);
    }
}

在dispatchTouchEvent 方法中对事件,滑动位置,view的位置进行处理处理。
在ACTION_UP中使用动画恢复view的位置,将矩形置空。效果和ios的差不多

    原文作者:Android小人
    原文地址: https://www.jianshu.com/p/fca4ccb96c6f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞