1. 程式人生 > >自定義帶滑動距離監控和仿iOS回彈效果的NestedScrollView

自定義帶滑動距離監控和仿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); } }