博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android -- 自定义ScrollView实现放大回弹效果
阅读量:6192 次
发布时间:2019-06-21

本文共 3505 字,大约阅读时间需要 11 分钟。

1,刚刚在别人开源的项目中看到了一个挺不错的用户体验,效果图如下:

2,那下面我们就来实现一下,首先看一下布局,由于一般只是我们包含头像的那部分方法,所以这里我们要把布局分成两部分,对应的布局文件效果图如下:

3,自定义ScrollView

  第一步:创建一个类,继承自ScrollView,重写相应的构造函数

public class ZoomInScrollView extends ScrollView { public ZoomInScrollView(Context context) {        this(context, null);    }    public ZoomInScrollView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public ZoomInScrollView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }}

  第二步:重写OnFinishInflate()方法,并记录第一个子view,即我们的head_fragment

@Override    protected void onFinishInflate() {        super.onFinishInflate();        //设置不可过度滚动,否则上移后下拉会出现部分空白的情况        setOverScrollMode(OVER_SCROLL_NEVER);        View child = getChildAt(0);        if (child != null && child instanceof ViewGroup) {            //获取默认第一个子View            mHeaderView = ((ViewGroup) child).getChildAt(0);        }    }

  第三步:重写OnTouchEvent()方法,在Action_Move方法中拿到下滑的距离,通过设置head_view的属性参数来改变它的大小,在UP的时候还原head_view

@Override    public boolean onTouchEvent(MotionEvent ev) {        if (mHeaderView == null)            return super.onTouchEvent(ev);        switch (ev.getAction()) {            case MotionEvent.ACTION_MOVE:                if (!mIsPulling) {                    //第一次下拉                    if (getScrollY() == 0) {                        //在顶部的时候,记录顶部位置                        mLastY = (int) ev.getY();                    } else {                        break;                    }                }                if (ev.getY() - mLastY < 0)                    return super.onTouchEvent(ev);                int distance = (int) ((ev.getY() - mLastY) * mScaleRatio);                mIsPulling = true;                setZoom(distance);                return true;            case MotionEvent.ACTION_UP:                mIsPulling = false;                replyView();                break;        }        return super.onTouchEvent(ev);    }

    在回弹view的时候通过属性动画动态的改变head_view的值,并重写onSizeChange()方法,实时的记录head_view的宽高

**     * 放大view     */    private void setZoom(float s) {        float scaleTimes = (float) ((mHeaderWidth + s) / (mHeaderWidth * 1.0));//        如超过最大放大倍数,直接返回        if (scaleTimes > mScaleTimes) return;        ViewGroup.LayoutParams layoutParams = mHeaderView.getLayoutParams();        layoutParams.width = (int) (mHeaderWidth + s);        layoutParams.height = (int) (mHeaderHeight * ((mHeaderWidth + s) / mHeaderWidth));//        设置控件水平居中        ((MarginLayoutParams) layoutParams).setMargins(-(layoutParams.width - mHeaderWidth) / 2, 0, 0, 0);        mHeaderView.setLayoutParams(layoutParams);    }    /**     * 回弹     */    private void replyView() {        final float distance = mHeaderView.getMeasuredWidth() - mHeaderWidth;        // 设置动画        ValueAnimator anim = ObjectAnimator.ofFloat(distance, 0.0F).setDuration((long) (distance * mReplyRatio));        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                setZoom((Float) animation.getAnimatedValue());            }        });        anim.start();    }@Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mHeaderWidth = mHeaderView.getMeasuredWidth();        mHeaderHeight = mHeaderView.getMeasuredHeight();    }

  这样就实现了我们的效果了,看一下我们自己实现的效果:

   github(还没有传上去,网速差,骚等一下),有需要源码的同学可以去下载一下。See You Next Time ......

转载地址:http://rheda.baihongyu.com/

你可能感兴趣的文章
Atitit. visual studio vs2003 vs2005 vs2008 VS2010 vs2012 vs2015新特性 新功能.doc
查看>>
php : 基础(6)
查看>>
js获取网页屏幕可见区域高度
查看>>
使用pm2常见问题
查看>>
CentOS下Zabbix安装部署及汉化
查看>>
移动端浏览器和微信浏览器上禁止body的滚动条
查看>>
Linux fdisk
查看>>
JavaScript获取当前url根目录(路径)
查看>>
sql server系统表详细说明
查看>>
C语言 · Interval · 求矩阵元素和
查看>>
libsvm的数据格式及制作
查看>>
MySQL 安装 5.0
查看>>
python wsgi 简介
查看>>
2016年Esri技术公开课全年资料分享
查看>>
mysql基础篇 - SELECT 语句详解
查看>>
SQL Server-索引故事的遥远由来,原来是这样的?(二十八)
查看>>
Linux知识积累(3)$()和${}和$(())和(())
查看>>
Ansible 插件 之 【CMDB】【转】
查看>>
解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)
查看>>
Golang 版本发布 与 TIOBE 排名
查看>>