ScrollView滑动到底部或顶部监听,ScrollView滑动到底部或顶部再继续滑动监听;

ScrollView滑动到底部或顶部后,再继续滑动达到一定距离的监听;

ScrollView滑动到底部或顶部的监听;


/**
 * 监听ScrollView滚动到顶部或者底部做相关事件拦截
 */
public class ContinueSlideScrollView extends ScrollView {

    private boolean isScrolledToTop = true;// 初始化的时候设置一下值
    private boolean isScrolledToBottom = false;
    private Context context;


    private ISmartScrollChangedListener mSmartScrollChangedListener;

    public ContinueSlideScrollView(Context context) {
        super(context);
        this.context = context;
    }

    public ContinueSlideScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    public ContinueSlideScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }

    /**
     * 滑动到顶部或底部的监听接口
     * */
    public interface ISmartScrollChangedListener {
        void onScrolledToBottom();
        void onScrolledToTop();
    }

    public void setScanScrollChangedListener(ISmartScrollChangedListener smartScrollChangedListener) {
        mSmartScrollChangedListener = smartScrollChangedListener;
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        if (scrollY == 0) {
            isScrolledToTop = clampedY;
            isScrolledToBottom = false;
        } else {
            isScrolledToTop = false;
            isScrolledToBottom = clampedY;
        }
        notifyScrollChangedListeners();
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (android.os.Build.VERSION.SDK_INT < 9) {  // API 9及之后走onOverScrolled方法监听
            if (getScrollY() == 0) {
                isScrolledToTop = true;
                isScrolledToBottom = false;
            } else if (getScrollY() + getHeight() - getPaddingTop()-getPaddingBottom() == getChildAt(0).getHeight()) {
                isScrolledToBottom = true;
                isScrolledToTop = false;
            } else {
                isScrolledToTop = false;
                isScrolledToBottom = false;
            }
            notifyScrollChangedListeners();
        }
    }

    private void notifyScrollChangedListeners() {
        if (isScrolledToTop) {
            if (mSmartScrollChangedListener != null) {
                mSmartScrollChangedListener.onScrolledToTop();
            }
        } else if (isScrolledToBottom) {
            if (mSmartScrollChangedListener != null) {
                mSmartScrollChangedListener.onScrolledToBottom();
            }
        }
    }

    public boolean isScrolledToTop() {
        return isScrolledToTop;
    }

    public boolean isScrolledToBottom() {
        return isScrolledToBottom;
    }


    /**
     * 继续滑动的代码
     */
    private float down,move;
    private boolean isExecute = false; //是否要执行
    private int TRIGGER_DISTANCE = 160;  //继续滑动效果触发间距 dp
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                down = ev.getY();
                isExecute = true;
                break;
            case MotionEvent.ACTION_MOVE:
                move = ev.getY();

                if (isExecute && isScrolledToTop() && move - down > dp2px(context,TRIGGER_DISTANCE)){
                    isExecute = false;
                    Log.i("ccb", "onTouchEvent: 回到顶部,继续滑动"+(move - down));
                    if (continueSlide != null)continueSlide.onContinueSlideTop();
                }
                if (isExecute && isScrolledToBottom() && move - down < (-dp2px(context,TRIGGER_DISTANCE))){
                    isExecute = false;
                    Log.i("ccb", "onTouchEvent: 已经到底,继续滑动"+((move - down)));
                    if (continueSlide != null)continueSlide.onContinueSlideBottom();
                }
                break;
                case MotionEvent.ACTION_UP:
                    isExecute = true;
                    move = 0;
                    down = 0 ;
                    break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 滑动到顶部或底部继续滑动到一定距离触发
     */
    public interface onContinueSlide{
        void onContinueSlideTop();
        void onContinueSlideBottom();
    }

    public onContinueSlide continueSlide;

    public void setonContinueSlideListener(onContinueSlide continueSlide){
         this.continueSlide = continueSlide;
    }


    /**
     * dip转换px
     */
    public static int dp2px(Context content, int dip) {
        final float scale = content.getResources().getDisplayMetrics().density;
        return (int) (dip * scale + 0.5f);
    }
}

实现了一下,仿淘宝从商品页继续上拉进入商品详情页的效果:https://github.com/CuiChenbo/DoubleFragmentSwitch

猜你喜欢

转载自blog.csdn.net/qq_35605213/article/details/85257597
今日推荐