android 仿ios带弹簧效果的ScrollView

说ios的效果确实不错,今天就参照别人的代码,修改bug一箩筐,优化体验一大堆。

废话不多说,上代码:

/**
 * 仿ios弹簧效果 scrollview 带阻尼
 * @author sunxiaogang
 * Create by sxg on 2016/08/26
 */
public class CustomerScrollView extends ScrollView {
private int MaxY= App.windowHeight;//MerchantAPP.windowHeight
/**
* 阻尼效果 越小 效果越明显
*/
private int damp=2;
/**
* 弹簧动画持续时间
*/
private int ANIMATION_TIME =1000;
/**
* 弹力效果
*/
private float spring=2.0f;
private View mView;
private Rect mRect = new Rect();
private float y;
public CustomerScrollView(Context context) {
super(context);
}


public CustomerScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}


public CustomerScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


@SuppressLint("MissingSuperCall")
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
this.mView = getChildAt(0);
}
}


其实重点是重写onTouchEvent方法

@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mView == null) {
return super.onTouchEvent(ev);
} else {


commOnTouchEvent(ev);


}
return super.onTouchEvent(ev);
}
private boolean canScroll=false;
private void commOnTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
y = ev.getY();
break;
case MotionEvent.ACTION_UP:
if (isNeedAnimation()) {
animation();
}
break;
case MotionEvent.ACTION_MOVE:
final float preY = y;
float nowY = ev.getY();
int deltaY = (int) (preY - nowY);


此处解决许多适配问题,只要是子控件 抢焦点,一点,那个效果啊,是没法看的。
if (Math.abs(deltaY) < Math.abs(nowY) && (Math.abs(deltaY) + 1) > Math.abs(nowY)) {
canScroll= false;
} else {


canScroll=true;
}
y = nowY;
if (isNeedMove()&&canScroll) {
if (mRect.isEmpty()) {
mRect.set(mView.getLeft(), mView.getTop(), mView.getRight(), mView.getBottom());
}
if (mView.getTop() - deltaY/damp < MaxY && mView.getTop() - deltaY/damp > -MaxY) {
mView.layout(mView.getLeft(), mView.getTop() - deltaY/damp, mView.getRight(), mView.getBottom() - deltaY/damp);
}
}
break;
default:
break;
}
}
private boolean isNeedMove() {
int offset = mView.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
if (scrollY == 0 || scrollY == offset) {
return true;
}
return false;
}


private boolean isNeedAnimation() {
return !mRect.isEmpty();
}


private void animation() {
TranslateAnimation ta = new TranslateAnimation(0, 0, mView.getTop(), mRect.top);
ta.setDuration(ANIMATION_TIME);
/**
* 此处是回弹动画设置
* 体验效果更佳
*/
ta.setInterpolator(new DecelerateInterpolator(spring));
mView.startAnimation(ta);
mView.layout(mRect.left, mRect.top, mRect.right, mRect.bottom);
mRect.setEmpty();
y=0;
}


/**
* 以下是各种set 和get方法  设置 阻尼系数等
* @return
*/
public float getSpring() {
return spring;
}


public void setSpring(float spring) {
this.spring = spring;
}


public int getANIMATION_TIME() {
return ANIMATION_TIME;
}


public void setANIMATION_TIME(int ANIMATION_TIME) {
this.ANIMATION_TIME = ANIMATION_TIME;
}


public int getDamp() {
return damp;
}


public void setDamp(int damp) {
this.damp = damp;
}
}


附源码


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值