SlidingUpLayout

来源:互联网 发布:淘宝宝贝像素 编辑:程序博客网 时间:2024/06/08 05:15

效果如图:

代码如下:

public class SlidingUpLayout extends ViewGroup {    private View mBelowView;    private View mDragView;    private View mAboveView;    private ViewDragHelper mViewDragHelper;    private float mAlpha;    private float mSlideOffset;    private float mAnchorPointer;    private State mState = State.ANCHORED;    private int mSettlePosition;    public enum State {        EXPANDED,        COLLAPSED,        ANCHORED    }    private OnStateChangedListener onStateChangedListener;    public SlidingUpLayout(Context context) {        this(context,null);    }    public SlidingUpLayout(Context context, AttributeSet attrs) {        this(context, attrs,0);    }    public SlidingUpLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.SlidingUpLayout);        mAnchorPointer = mTypedArray.getFloat(R.styleable.SlidingUpLayout_anchorPointer,0.44f);        mTypedArray.recycle();    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        mBelowView = getChildAt(0);        mDragView = getChildAt(1);        mAboveView = getChildAt(2);        mViewDragHelper = ViewDragHelper.create(this,new SlidingUpViewDragHelper());    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int measureHeight = MeasureSpec.getSize(heightMeasureSpec);        int belowHeight = MeasureSpec.makeMeasureSpec(measureHeight,MeasureSpec.EXACTLY);        mBelowView.measure(widthMeasureSpec, belowHeight);        LayoutParams dragViewLayoutParams = mDragView.getLayoutParams();        int dragViewWidth = MeasureSpec.makeMeasureSpec(dragViewLayoutParams.width,MeasureSpec.EXACTLY);        int dragViewHeight = MeasureSpec.makeMeasureSpec(dragViewLayoutParams.height,MeasureSpec.EXACTLY);        mDragView.measure(dragViewWidth,dragViewHeight);        mAboveView.measure(widthMeasureSpec,heightMeasureSpec);        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        switch (mState){            case EXPANDED:                mAlpha = (float) 0.5;                mSlideOffset = 1;                break;            case COLLAPSED:                mAlpha = 0;                mSlideOffset = 0;                break;            case ANCHORED:                mAlpha = (float) (mAnchorPointer*0.5);                mSlideOffset = mAnchorPointer;                break;        }        int belowViewWidth = mBelowView.getMeasuredWidth();        int belowViewHeight = mBelowView.getMeasuredHeight();        mBelowView.layout(0,0,belowViewWidth,belowViewHeight);        int dragViewWidth = mDragView.getMeasuredWidth();        int dragViewHeight = mDragView.getMeasuredHeight();        mDragView.layout(belowViewWidth/2-dragViewWidth/2,                (int) (belowViewHeight-dragViewHeight-mSlideOffset*(belowViewHeight-dragViewHeight)),                belowViewWidth/2+dragViewWidth/2,                (int) (belowViewHeight-mSlideOffset*(belowViewHeight-dragViewHeight)));        int aboveViewWidth = mAboveView.getMeasuredWidth();        int aboveViewHeight = mAboveView.getMeasuredHeight();        mAboveView.layout(0,                (int) (belowViewHeight-mSlideOffset*(belowViewHeight-dragViewHeight)),                aboveViewWidth,                (int) (belowViewHeight+aboveViewHeight-mSlideOffset*(belowViewHeight-dragViewHeight)));    }    @Override    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {        boolean result;        final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);        if (child==mBelowView) {            Rect mTmpRect = new Rect();            canvas.getClipBounds(mTmpRect);            mTmpRect.bottom = mAboveView.getTop();            canvas.clipRect(mTmpRect);            result = super.drawChild(canvas, child, drawingTime);            Paint mCoveredFadePaint = new Paint();            final int baseAlpha = 0xff000000 >>> 24;            final int imag = (int) (baseAlpha * mAlpha);            final int color = imag << 24 ;            mCoveredFadePaint.setColor(color);            canvas.drawRect(mTmpRect, mCoveredFadePaint);        } else {            result = super.drawChild(canvas, child, drawingTime);        }        canvas.restoreToCount(save);        return result;    }    @Override    public void computeScroll() {        if (mViewDragHelper.continueSettling(true)){            invalidate();        }    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        mViewDragHelper.processTouchEvent(ev);        return mViewDragHelper.shouldInterceptTouchEvent(ev);    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        return super.dispatchTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        mViewDragHelper.processTouchEvent(event);        return true;    }    class SlidingUpViewDragHelper extends ViewDragHelper.Callback{        @Override        public boolean tryCaptureView(View child, int pointerId) {            return child==mDragView;        }        @Override        public int clampViewPositionHorizontal(View child, int left, int dx) {            if (child==mDragView){                return mBelowView.getWidth()/2-mDragView.getWidth()/2;            }            return super.clampViewPositionHorizontal(child, left, dx);        }        @Override        public int clampViewPositionVertical(View child, int top, int dy) {            if (top>mBelowView.getMeasuredHeight()-mDragView.getMeasuredHeight()){                mSettlePosition = mBelowView.getMeasuredHeight()-mDragView.getMeasuredHeight();                return mBelowView.getMeasuredHeight()-mDragView.getMeasuredHeight();            }else if (top<0){                mSettlePosition = 0;                return 0;            }else {                mSettlePosition = top-mDragView.getMeasuredHeight();                mAlpha = (float) ((mBelowView.getHeight()-mDragView.getMeasuredHeight()-top)*0.5/(mBelowView.getHeight()                        -mDragView.getMeasuredHeight()));            }            return top;        }        @Override        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {            if (changedView==mDragView){                mAboveView.layout(0,                        top+mDragView.getMeasuredHeight(),                        mAboveView.getMeasuredWidth(),                        mAboveView.getMeasuredHeight()+top+mDragView.getMeasuredHeight());            }            super.onViewPositionChanged(changedView, left, top, dx, dy);        }        @Override        public void onViewReleased(View releasedChild, float xvel, float yvel) {            if (mSettlePosition>mBelowView.getMeasuredHeight()-mAnchorPointer*mBelowView.getMeasuredHeight()/2-mDragView.getMeasuredHeight()){                mDragView.layout(mBelowView.getMeasuredWidth()/2-mDragView.getMeasuredWidth()/2,                        mBelowView.getMeasuredHeight()-mDragView.getMeasuredHeight(),                        mBelowView.getMeasuredWidth()/2+mDragView.getMeasuredWidth()/2,                        mBelowView.getMeasuredHeight());                mAboveView.layout(0,                        mBelowView.getMeasuredHeight(),                        mAboveView.getMeasuredWidth(),                        mBelowView.getMeasuredHeight()+mAboveView.getMeasuredHeight());                mState = State.COLLAPSED;            }else if (mSettlePosition<=mBelowView.getMeasuredHeight()-mAnchorPointer*mBelowView.getMeasuredHeight()/2-mDragView.getMeasuredHeight()                    &&mSettlePosition>mBelowView.getMeasuredHeight()-mAnchorPointer*mBelowView.getMeasuredHeight()*3/2-mDragView.getMeasuredHeight()){                mDragView.layout(mBelowView.getMeasuredWidth()/2-mDragView.getMeasuredWidth()/2,                        (int) (mBelowView.getMeasuredHeight()-mAnchorPointer*mBelowView.getMeasuredHeight()-mDragView.getMeasuredHeight()),                        mBelowView.getMeasuredWidth()/2+mDragView.getMeasuredWidth()/2,                        (int) (mBelowView.getMeasuredHeight()-mAnchorPointer*mBelowView.getMeasuredHeight()));                mAboveView.layout(0,                        (int) (mBelowView.getMeasuredHeight()-mAnchorPointer*mBelowView.getMeasuredHeight()),                        mAboveView.getMeasuredWidth(),                        (int) (mBelowView.getMeasuredHeight()-mAnchorPointer*mBelowView.getMeasuredHeight()+mAboveView.getMeasuredHeight()));                mState = State.ANCHORED;            }else {                mDragView.layout(mBelowView.getMeasuredWidth()/2-mDragView.getMeasuredWidth()/2,                        0,                        mBelowView.getMeasuredWidth()/2+mDragView.getMeasuredWidth()/2,                        mDragView.getMeasuredHeight());                mAboveView.layout(0,                        mDragView.getMeasuredHeight(),                        mAboveView.getMeasuredWidth(),                        mDragView.getMeasuredHeight()+mAboveView.getMeasuredHeight());                mState = State.EXPANDED;            }            super.onViewReleased(releasedChild, xvel, yvel);        }    }    public void setAnchorPointer(float anchorPointer) {        this.mAnchorPointer = anchorPointer;        postInvalidate();    }    public void setState(State state) {        this.mState = state;        postInvalidate();    }    public void setOnStateChangedListener(OnStateChangedListener onStateChangedListener){        this.onStateChangedListener = onStateChangedListener;    }    public interface OnStateChangedListener{        public void onStateChanged(State state);    }}


注意:需要依赖V4包

implementation 'com.android.support:support-v4:26.0.1'
attrs.xml文件

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="SlidingUpLayout">        <attr name="anchorPointer" format="float"/>    </declare-styleable></resources>
布局文件

<?xml version="1.0" encoding="utf-8"?><com.example.a1qu212.myapplication.SlidingUpLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    app:anchorPointer="0.44">    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@android:color/holo_red_dark"/>    <RelativeLayout        android:layout_width="100dp"        android:layout_height="50dp"        android:background="@android:color/holo_green_dark"/>    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@android:color/black"/></com.example.a1qu212.myapplication.SlidingUpLayout>
存在的问题:

计算不够准确;


参考https://github.com/umano/AndroidSlidingUpPanel



原创粉丝点击