您当前的位置: 首页 >  ui

命运之手

暂无认证

  • 2浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【高级UI】【025】手动为ScrollView添加回弹效果

命运之手 发布时间:2022-03-02 17:17:42 ,浏览量:2

效果

ScrollView滚动到最顶端和最底端时,还可以继续拉伸出一片空白区域,手松开后再回弹到正常状态

实现思路

  • 到达顶端和底端后,还想继续拉伸,这个可以通过layout方法对Content重新定位就能实现
  • 回弹效果,可以通过平移动画TranslateAnimation来实现
  • 当内容没到达顶端或底端时,通过ScrollView默认的onTouchEvent处理来正常滚动即可
  • 根据ScrollView的大小,ScrollView的滚动距离,ContentView的大小,可以判断控件是否滚动到顶端

核心代码

    package com.easing.commons.android.ui.control.scroll;

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

    import com.easing.commons.android.R;
    import com.easing.commons.android.manager.Device;
    import com.easing.commons.android.ui.dialog.TipBox;

    //带回弹效果的ScrollView,拉到顶部和底部时,仍可以继续拉出一部分空白区域,松手后回弹至正常状态
    //这个控件没有对padding进行处理,请不要为ScrollView设置padding
    @SuppressWarnings("all")
    public class BounceScrollView extends ScrollView {

        //ScrollView包裹的子View
        View contentView;

        //记录最近一次正常状态下的控件边界,即没有重定位时的状态
        //当控件处于弹性拉伸状态时,最近一次的正常状态,就是刚滑到顶端或底端时的状态
        Rect recentNormalBound = new Rect();

        //上次点击时的Y坐标
        float y;

        //动画是否在进行中
        TranslateAnimation animation;
        boolean isAnimationFinished = true;

        //最大宽高
        int maxWidth = Integer.MAX_VALUE;
        int maxHeight = Integer.MAX_VALUE;

        //让控件宽高,保持是某个值的整数倍
        int widthRadix = 0;
        int heightRadix = 0;

        //宽高占屏幕的最大比例
        float maxScreenRatioX = 0F;
        float maxScreenRatioY = 0F;

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

        public BounceScrollView(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
            init(context, attributeSet);
        }

        //初始化,读取属性
        protected void init(Context context, AttributeSet attributeSet) {
            int screenWidth = Device.screenWidth();
            int screenHeight = Device.screenHeight();
            TypedArray attrs = context.obtainStyledAttributes(attributeSet, R.styleable.BounceScrollView);
            maxWidth = (int) attrs.getDimension(R.styleable.BounceScrollView_maxWidth, Integer.MAX_VALUE);
            maxHeight = (int) attrs.getDimension(R.styleable.BounceScrollView_maxHeight, Integer.MAX_VALUE);
            widthRadix = (int) attrs.getDimension(R.styleable.BounceScrollView_widthDivision, 0);
            heightRadix = (int) attrs.getDimension(R.styleable.BounceScrollView_heightDivision, 0);
            maxScreenRatioX = attrs.getFloat(R.styleable.BounceScrollView_maxScreenRatioX, 0);
            maxScreenRatioY = attrs.getFloat(R.styleable.BounceScrollView_maxScreenRatioY, 0);
            if (maxScreenRatioX > 0)
                if (maxScreenRatioX * screenWidth  0)
                if (maxScreenRatioY * screenHeight  0)
                contentView = getChildAt(0);
            super.onFinishInflate();
        }

        //重写测量方法,以支持最大宽高、整倍宽高功能
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            if (widthMode == MeasureSpec.EXACTLY)
                widthSize = widthSize             
关注
打赏
1654938663
查看更多评论
0.0395s