您当前的位置: 首页 >  android
  • 0浏览

    0关注

    674博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Android自定义view仿写QQ空间可拉伸头部控件

沙漠一只雕得儿得儿 发布时间:2020-05-04 17:25:46 ,浏览量:0

先来看下仿照QQ空间顶部图片过度下拉时,顶部图片放大回弹的效果,完整项目:https://github.com/buder-cp/CustomView/tree/master/buder_DN_view/buderdn20

业务逻辑包括:顶部图片可以下拉,当过度下拉时会有顶部图片放大的效果,在松手时会有顶部图片回弹效果。

我们看下大致看下需要重写哪些方法才能完成上面的需求。

  1. 首先肯定要有onTouchEvent,因为需要在手指按下去或者离开时处理业务逻辑;
  2. 这里我们继承的是ListView,我们在向下滑动时会触发ListView父类中的onScrollChanged方法,该方法是响应view内部滚动内容的滑动而调用,通常是在触发了scrollBy或者scrollTo后调用的,可以不用像上一篇自定义RecyclerView那样重写很多onTouchEvent、scrollBy滑动和内部item相互处理的细节,因为在ListView中已经实现好了。
  3. overScrollBy方法:以标准行为滚动视图,滚动到正常内容边界之外时会触发。意思就是在滑动到最大滑动距离后还继续向下滑动时触发
public boolean onTouchEvent(MotionEvent ev) 


protected void onScrollChanged(int l, int t, int oldl, int oldt) 



protected boolean overScrollBy(int deltaX, int deltaY, int scroll)
过度滑动时,改变顶部图片高度

根据业务逻辑,在上滑和下拉时需要改变顶部图片的高度:

    /**
     * 上滑下拉时,改变图片的高度
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        Log.i(TAG, "overScrollBy: " + deltaY);
        if (deltaY < 0) {
            //-  下拉
            mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY;
            mImageView.requestLayout();
        } else {
            //+ 上拉
            mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY;
            mImageView.requestLayout();
        }
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }
手指抬起时,触发缩放动画:
    //松手时触发缩放动画
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        if (action == MotionEvent.ACTION_UP) {
            ResetAnimation resetAnimation = new ResetAnimation(mImageViewHeight);
            resetAnimation.setInterpolator(new OvershootInterpolator());
            resetAnimation.setDuration(700);
            mImageView.startAnimation(resetAnimation);
        }
        return super.onTouchEvent(ev);
    }

    public class ResetAnimation extends Animation {

        //需要偏移回去的高度
        private int extraHeight;
        private int currentHeight;

        public ResetAnimation(int targetHeight) {
            currentHeight = mImageView.getHeight();
            extraHeight = mImageView.getHeight() - targetHeight;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            mImageView.getLayoutParams().height = (int) (currentHeight - extraHeight * interpolatedTime);
            mImageView.requestLayout();
            super.applyTransformation(interpolatedTime, t);
        }
    }

QQHeaderScrollView整体代码如下:

import android.content.Context;
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.OvershootInterpolator;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.ListView;

public class QQHeaderScrollView extends ListView {

    private static final String TAG = "david";
    private ImageView mImageView;
    private int mImageViewHeight;//初始高度

    public void setZoomImageView(ImageView iv) {
        mImageView = iv;
    }

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

    public QQHeaderScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mImageViewHeight = context.getResources().getDimensionPixelSize(R.dimen.size_default_height);
    }

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

    //松手时触发缩放动画
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        if (action == MotionEvent.ACTION_UP) {
            ResetAnimation resetAnimation = new ResetAnimation(mImageViewHeight);
            resetAnimation.setInterpolator(new OvershootInterpolator());
            resetAnimation.setDuration(700);
            mImageView.startAnimation(resetAnimation);
        }
        return super.onTouchEvent(ev);
    }

    public class ResetAnimation extends Animation {

        //需要偏移回去的高度
        private int extraHeight;
        private int currentHeight;

        public ResetAnimation(int targetHeight) {
            currentHeight = mImageView.getHeight();
            extraHeight = mImageView.getHeight() - targetHeight;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            mImageView.getLayoutParams().height = (int) (currentHeight - extraHeight * interpolatedTime);
            mImageView.requestLayout();
            super.applyTransformation(interpolatedTime, t);
        }
    }

    /**
     * 上滑下拉时,改变图片的高度
     */
    @Override
    protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
        Log.i(TAG, "overScrollBy: " + deltaY);
        if (deltaY < 0) {
            //-  下拉
            mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY;
            mImageView.requestLayout();
        } else {
            //+ 上拉
            mImageView.getLayoutParams().height = mImageView.getHeight() - deltaY;
            mImageView.requestLayout();
        }
        return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
    }

//    @Override
//    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
//        View header = (View) mImageView.getParent();
//        Log.i(TAG, "onSizeChanged: " + header.getTop());
//        //ListView会滑出去的高度(负数)
//        int deltaY = header.getTop();
//        //只有image的高度大于 原始的高度,那我们就缩小
//        if (mImageView.getHeight() > mImageViewHeight) {
//            mImageView.getLayoutParams().height = mImageView.getHeight() + deltaY;
//            header.layout(header.getLeft(), 0, header.getRight(), header.getHeight());
//            mImageView.requestLayout();
//        }
//        super.onSizeChanged(w, h, oldw, oldh);
//    }
}

完整项目

关注
打赏
1657159701
查看更多评论
立即登录/注册

微信扫码登录

0.0412s