自定义View 下拉刷新效果

文章目录

效果

在这里插入图片描述
在这里插入图片描述

代码

/**
 * 自定义控件
 */
public class RefreshView extends FrameLayout {

    /**
     * 拖出来的头布局高度
     */
    private int headHeight = 300;
    private PointF startPoint;
    private float startX;
    private float startY;
    private LinearLayout contentView; //内容页面
    private LinearLayout headView; //头布局页面

    public RefreshView(Context context) {
        super(context);
        initView();
    }

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

    /**
     * 添加控件
     */
    private void initView(){

        contentView = new LinearLayout(getContext());
        FrameLayout.LayoutParams paramsContent = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        contentView.setBackgroundColor(Color.GRAY);
        contentView.setLayoutParams(paramsContent);

        headView = new LinearLayout(getContext());
        FrameLayout.LayoutParams paramHead = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,headHeight);
        headView.setBackgroundColor(Color.WHITE);
        headView.setLayoutParams(paramHead);

        ImageView imageView = new ImageView(getContext());
        imageView.setImageResource(R.mipmap.baoxiang);
        imageView.setLayoutParams(paramHead);
        headView.addView(imageView);

        addView(headView);
        addView(contentView);

        startPoint = new PointF(); //起点
    }

    /**
     * 事件分发
     * @param ev
     * @return super.dispatchTouchEvent(ev); 父容器处理
     *         true:不向上也不向下传递
     *         false:向上不向下传递
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        /**
         * 1.判断滑动方向
         * 2.增加内容的marginTop值
         */
        if (ev.getAction() == MotionEvent.ACTION_DOWN){
            //按下事件
            startX = ev.getX();
            startY = ev.getY();
        }
        else if(ev.getAction() == MotionEvent.ACTION_UP){

            FrameLayout.LayoutParams params = (LayoutParams) contentView.getLayoutParams();
            if(params.topMargin < headHeight/2){
                //关闭通过动画实现
//                params.topMargin = 0;
                showAnim(0,params);
            }
            else {
                //打开通过动画实现
//                params.topMargin = headHeight;
                showAnim(headHeight,params);
            }
            contentView.setLayoutParams(params);
        }
        else if(ev.getAction() == MotionEvent.ACTION_MOVE){
            //滑动事件
            float endX = ev.getX();
            float endY = ev.getY();
            float moveY = Math.abs(endY-startY); //滑出的Y轴距离
            float moveX = Math.abs(endX - startX); //滑出的X轴距离
            if(moveX > moveY * 2){
                //横向滑动我们不做处理
                return super.dispatchTouchEvent(ev);
            }

            if(moveY < 5){
                //轻微滑动不做处理
                return super.dispatchTouchEvent(ev);
            }

            /**
             * 以下开始做位移的处理
             */
            FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) contentView.getLayoutParams();
            if(layoutParams.topMargin < 0){
                layoutParams.topMargin = 0;
            }
            else if(layoutParams.topMargin > headHeight){
                layoutParams.topMargin = headHeight;
            }
            else {
                layoutParams.topMargin += endY - startY;
            }
            contentView.setLayoutParams(layoutParams);
            startY = ev.getY();
            startX = ev.getX();
        }
        return true;
    }

    /**
     * 使用属性动画实现平移
     */
    private void showAnim(int value, final FrameLayout.LayoutParams params){
        ValueAnimator animator = ValueAnimator.ofInt(value);
        animator.setDuration(2000);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int margin = (int) animation.getAnimatedValue();
                params.topMargin = margin;
            }
        });
        animator.start();
    }

    /**
     * 事件拦截
     * @param ev
     * @return
     */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev);
    }

    /**
     * 事件处理
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值