拖动销毁图片参考代码

package com.jiayiworld.baselibrary.widgets;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;

import static android.animation.ObjectAnimator.ofFloat;

/**
 * 仿今日头条图片浏览上下滑动退出界面
 */
public class UpDownHideLayout extends FrameLayout {
    private ScrollListener mScrollListener;

    // 最小缩放比例
    private final float MIN_SCALE = 0.2f;
    // 完全不透明的透明度值
    private final int FULL_ALPHA = 255;

    public interface ScrollListener {

        void onScrolling(float percent, float pixDistance);
    }

    public void setScrollListener(ScrollListener scrollListener) {
        mScrollListener = scrollListener;
    }

    public interface OnLayoutCloseListener {
        void OnLayoutClosed();
    }

    enum Direction {
        UP_DOWN,
        LEFT_RIGHT,
        NONE
    }

    private Direction direction = Direction.NONE;
    private int previousFingerPositionY;
    private int previousFingerPositionX;
    private int baseLayoutPosition;
    private boolean isScrollingUp;  //上滑 true  下滑false
    private boolean isLocked = false;//是否拦截事件
    private OnLayoutCloseListener listener;
    private int RootViewHeight = 0;


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

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

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public UpDownHideLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (isLocked) {
            return false;
        } else {
            final int y = (int) ev.getRawY();
            final int x = (int) ev.getRawX();
            if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
                previousFingerPositionX = x;
                previousFingerPositionY = y;
            } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
                int diffY = y - previousFingerPositionY;
                int diffX = x - previousFingerPositionX;
                if (Math.abs(diffX) + 50 < Math.abs(diffY))
                    return true;
                {
                }
            }
            return false;
        }
    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
//      初始化界面的高度
        RootViewHeight = getMeasuredHeight() + 24;//有状态栏和虚拟键
        super.onLayout(changed, left, top, right, bottom);
    }

    /**
     * 灵巧模式拖拽(类似微信朋友圈)
     */
    private void dragByAgile(float lastX, float lastY, MotionEvent event, View view) {
        // 手指的移动距离
        final float disX = event.getX() - lastX;
        final float disY = event.getY() - lastY;
        // imageView 被拖拽后的坐标
        final float nextX = view.getTranslationX() + disX;
        final float nextY = view.getTranslationY() + disY;


        // 计算缩放比例
        final float scale = Math.min(Math.max(1f - Math.abs(nextY) / getHeight(), MIN_SCALE), 1f);
        view.getLayoutParams().width = (int) (getWidth() * scale);
        view.getLayoutParams().height = (int) (getHeight() * scale);
        view.requestLayout();
        // 变换背景透明度
        transformBgAlpha((int) (scale * FULL_ALPHA));


//        // 向上移动
//        if (nextY <= 0) {
//            if (imageView.getLayoutParams().width != mIfWidth ||
//                    imageView.getLayoutParams().height != mIfHeight) {
//                imageView.getLayoutParams().width = mIfWidth;
//                imageView.getLayoutParams().height = mIfHeight;
//                imageView.requestLayout();
//            }
//            transformBgAlpha(FULL_ALPHA);
//
//        }
//        // 向下移动
//        else {
//            // 计算缩放比例
//            final float scale = Math.min(Math.max(1f - nextY / mIfHeight, MIN_SCALE), 1f);
//            imageView.getLayoutParams().width = (int) (mIfWidth * scale);
//            imageView.getLayoutParams().height = (int) (mIfHeight * scale);
//            imageView.requestLayout();
//            // 变换背景透明度
//            transformBgAlpha((int) (scale * FULL_ALPHA));
//        }
        view.setTranslationX(nextX);
        view.setTranslationY(nextY);
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent ev) {
        if (!isLocked) {
            final int y = (int) ev.getRawY();
            final int x = (int) ev.getRawX();
            if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
                previousFingerPositionX = x;
                previousFingerPositionY = y;
                baseLayoutPosition = (int) this.getY();
            } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
                int diffY = y - previousFingerPositionY;
                int diffX = x - previousFingerPositionX;
                if (direction == Direction.NONE) {
                    if (Math.abs(diffX) > Math.abs(diffY)) {
                        direction = Direction.LEFT_RIGHT;
                    } else if (Math.abs(diffX) < Math.abs(diffY)) {
                        direction = Direction.UP_DOWN;
                    } else {
                        direction = Direction.NONE;
                    }
                }
                if (direction == Direction.UP_DOWN) {
                    isScrollingUp = diffY <= 0;
                    this.setY(baseLayoutPosition + diffY);
                    requestLayout();
                    if (mScrollListener != null) {
                        diffY = Math.abs(diffY);
                        float percent = ((float) diffY / (float) RootViewHeight) > 0.99 ? 1 : ((float) diffY / (float) RootViewHeight);
                        mScrollListener.onScrolling(percent, diffY);
                    }
                    return true;
                }
            } else if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
                if (direction == Direction.UP_DOWN) {
                    if (isScrollingUp) {
                        int height = this.getHeight();
                        if (Math.abs(this.getY()) > (height / 5)) {
//                            上滑退出
                            scrollToHide(true);
//                            dragByAgile()
                        } else {
//                            scrollToBack();
                            downToFinish(mScrollListener);
                        }
                    } else {
                        int height = this.getHeight();
                        if (Math.abs(this.getY()) > (height / 5)) {
                            //下滑退出
                            scrollToHide(false);
                        } else {
                            scrollToBack();
                        }
                    }
                    direction = Direction.NONE;
                    return true;
                }
                direction = Direction.NONE;
            }
            return true;
        }
        return false;
    }


    public void scrollToHide(boolean isScrollingUp) {
        ObjectAnimator positionAnimator = null;
        if (isScrollingUp) {
            positionAnimator = ObjectAnimator.ofFloat(this, "y", this.getY(), -RootViewHeight);
        } else {
            positionAnimator = ofFloat(this, "y", this.getY(), RootViewHeight);
        }
        positionAnimator.addUpdateListener(new ObjectAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                notiyListener(animation);
            }
        });
        positionAnimator.setDuration(100);
        positionAnimator.start();
    }

    public void scrollToBack() {
        ObjectAnimator positionAnimator = ofFloat(this, "y", this.getY(), 0);
        positionAnimator.addUpdateListener(new ObjectAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                notiyListener(animation);
            }
        });
        positionAnimator.setDuration(300);
        positionAnimator.start();
    }

    public void notiyListener(ValueAnimator animation) {
        if (mScrollListener != null) {
            float diffY = Math.abs((float) animation.getAnimatedValue());
            float percent = (diffY / (float) RootViewHeight) > 0.99 ? 1 : (diffY / (float) RootViewHeight);
            mScrollListener.onScrolling(percent, diffY);
        }
    }


    public void setOnLayoutCloseListener(OnLayoutCloseListener closeListener) {
        this.listener = closeListener;
    }

    public void lock() {
        isLocked = true;
    }

    public void unLock() {
        isLocked = false;
    }

    public void downToFinish(final ScrollListener scrollListener) {
        ObjectAnimator positionAnimator = null;
        positionAnimator = ofFloat(this, "y", this.getY(), RootViewHeight);
        positionAnimator.addUpdateListener(new ObjectAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                if (scrollListener != null) {
                    float diffY = Math.abs((float) animation.getAnimatedValue());
                    float percent = (diffY / (float) RootViewHeight) > 0.99 ? 1 : (diffY / (float) RootViewHeight);
                    scrollListener.onScrolling(percent, diffY);
                }
            }
        });
        positionAnimator.setDuration(260);
        positionAnimator.start();
    }


    /**
     * 变换背景透明度
     */
    private void transformBgAlpha(int alpha) {
        if (getBackground() != null && getBackground().getAlpha() != alpha) {
            getBackground().setAlpha(alpha);
        }
    }

}
发布了213 篇原创文章 · 获赞 12 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/a1003434346/article/details/102737335