自定义带滑动距离监控和仿iOS回弹效果的NestedScrollView

  在最近的Support Library更新中(25.3.0),新增或者修复了许多东西,具体可以看revisions,其中有一个新增的动画效果:SpringAnimation 即弹簧动画,SpringAnimation是一个受SpringForce驱动的动画。弹簧力限定了弹簧的刚度,阻尼比以及静止位置。一旦弹簧动画开始,在每一帧上,弹簧力将更新动画的值和速度。动画一直运行,直到弹力达到平衡。如果在动画中使用了无阻尼的弹簧,动画将永远不会达到平衡,永远振荡下去。。。

上代码


import android.content.Context;
import android.support.animation.SpringAnimation;
import android.support.annotation.Nullable;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by xuxl on 2017/5/3.
 */

public class SpringScrollView extends NestedScrollView {

    private float startDragY;
    private SpringAnimation springAnim;
    private ScrollViewListener scrollViewListener = null;
    private View view = null;


    public SpringScrollView(Context context) {
        this(context, null);
    }

    public SpringScrollView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SpringScrollView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        springAnim = new SpringAnimation(this, SpringAnimation.TRANSLATION_Y, 0);
        //刚度 默认1200 值越大回弹的速度越快
        springAnim.getSpring().setStiffness(1000.0f);
        //阻尼 默认0.5 值越小,回弹之后来回的次数越多
        springAnim.getSpring().setDampingRatio(2f);
    }
//传view过来 我们的UI要做一个滑动渐变的背景,你们可以看着办
    public void setView(View view) {
        this.view = view;
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {

        switch (e.getAction()) {
            case MotionEvent.ACTION_MOVE:
                if (getScrollY() <= 0) {
                    //顶部下拉
                    if (startDragY == 0) {
                        startDragY = e.getRawY();
                    }
                    if (e.getRawY() - startDragY >= 0) {
                        setTranslationY((e.getRawY() - startDragY) / 3);
                        if (view != null) {
                            float alpha = (float) (e.getRawY() - startDragY) / 3 / DpAndPx.dip2px(150);
                            if (alpha < 0.6) {
                                view.setAlpha(alpha);
                            } else {
                                view.setAlpha((float) 0.6);
                            }
                        }
                        return true;
                    } else {
                        startDragY = 0;
                        springAnim.cancel();
                        setTranslationY(0);
                    }

                } else if ((getScrollY() + getHeight()) >= getChildAt(0).getMeasuredHeight()) {
                    //底部上拉
                    if (startDragY == 0) {
                        startDragY = e.getRawY();
                    }
                    if (e.getRawY() - startDragY <= 0) {
                        setTranslationY((e.getRawY() - startDragY) / 3);
                        return true;
                    } else {
                        startDragY = 0;
                        springAnim.cancel();
                        setTranslationY(0);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (getTranslationY() != 0) {
                    springAnim.start();
                }
                startDragY = 0;
                break;
        }

        return super.onTouchEvent(e);

    }
//定义一个滑动接口,监听滑动距离
    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }


    public interface ScrollViewListener {
        void onScrollChanged(SpringScrollView scrollView, int x, int y, int oldx, int oldy);
    }


}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值