Android自定义ScrollView实现拉伸效果

ScrollView在项目中使用的特别多但如果想实现那种下拉或者上滑时带有拉伸感的就需要自己继承ScrollView去重写里面的方法了,今天就实现一下自定义ScrollView。
定义一个名为DefinitionScrollView的类代码如下

package com.ranlegeran.leranfinancial.view;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;

/**
 * 创建日期:2019/01/20 on 14:10
 * 作 者: RANLEGERAN RANLEGERAN
 * 类 名: DefinitionScrollView
 * 简 述:自定义ScrollView实现拉伸效果
 */
public class DefinitionScrollView extends ScrollView {

    private View mView;

    private int mLastY; //上一次y轴方向操作的坐标位置

    private Rect mRect = new Rect(); // 用来记录临界状态的左上右下

    private boolean isFinishAnimation = true; //判断是否结束动画

    public DefinitionScrollView(Context context) {
        super(context);
    }

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

    public DefinitionScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 获取子视图
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if (getChildCount() > 0) {
            mView = getChildAt(0);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mView == null || !isFinishAnimation) {
            return super.onTouchEvent(event);
        }
        int eventY = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastY = eventY;
                break;
            case MotionEvent.ACTION_MOVE:
                int dy = eventY - mLastY; // 微小的偏移量
                if (isNeedMove()) {
                   if (mRect.isEmpty()) {
                       mRect.set(mView.getLeft(),mView.getTop(),mView.getRight(),mView.getBottom()); //记录临界状态的左上右下
                   }
                    mView.layout(mView.getLeft(),mView.getTop() + dy / 2, mView.getRight(),mView.getBottom() + dy / 2);
                }
                mLastY = eventY;
                break;
            case MotionEvent.ACTION_UP:
                //使用平移动画
                int translateY = mView.getBottom() - mRect.bottom;
                TranslateAnimation translateAnimation = new TranslateAnimation(0, 0, 0, -translateY);
                translateAnimation.setDuration(200);
                translateAnimation.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                        isFinishAnimation = false;
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        isFinishAnimation = true;
                        mView.clearAnimation(); //清除动画
                        mView.layout(mRect.left,mRect.top,mRect.right,mRect.bottom);
                        mRect.setEmpty();
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });
                //启动动画
                mView.startAnimation(translateAnimation);
                break;
        }

        return super.onTouchEvent(event);
    }

    private boolean isNeedMove() {
        int measuredHeight = mView.getMeasuredHeight(); //获取子视图的高度
        int scrollViewMeasuredHeight = this.getMeasuredHeight(); //获取布局的高度
        Log.e("TAG","measuredHeight" + measuredHeight);
        Log.e("TAG","scrollViewMeasuredHeight" + scrollViewMeasuredHeight);
        int dy = measuredHeight - scrollViewMeasuredHeight; //dy>= 0的
        int scrollY = this.getScrollY(); //获取用户在y轴方向上的偏移量往上滑+ 往下滑-
        if (scrollY <= 0 || scrollY >= dy) {
            return true; //按照自定义的DefinitionScrollView方式处理
        }
        //其他处在临界范围内的返回false 表示仍按照ScrollView的方式处理
        return false;
    }
}

然后在布局中使用即可

  <com.ranlegeran.leranfinancial.view.DefinitionScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none">
    </com.ranlegeran.leranfinancial.view.DefinitionScrollView>
```


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值