自定义SwipeLayout--仿QQ侧滑条目

来源:互联网 发布:知乎问题怎么删除 编辑:程序博客网 时间:2024/05/18 03:33

自定义SwipeLayout–仿QQ侧滑条目

先看动图
这里写图片描述

看布局文件

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="www.weshared.qqcehua.MainActivity">    <include layout="@layout/swipelayout" /></RelativeLayout>

swipelayout.xml

<?xml version="1.0" encoding="utf-8"?><www.weshared.qqcehua.SwipeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/swipelayout"    android:layout_width="match_parent"    android:layout_height="72dp">    <!--0   左边后布局-->    <TextView        android:id="@+id/back_left_tv_mark"        android:layout_width="84dp"        android:layout_height="match_parent"        android:background="@android:color/holo_blue_dark"        android:gravity="center"        android:text="Mark"        android:textColor="@android:color/white"        android:textSize="20sp" />    <!--1   右边后布局-->    <LinearLayout        android:id="@+id/back_right_ll"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_gravity="right"        android:orientation="horizontal">        <TextView            android:id="@+id/back_right_tv_call"            android:layout_width="84dp"            android:layout_height="match_parent"            android:background="@android:color/holo_orange_dark"            android:gravity="center"            android:text="Call"            android:textColor="@android:color/white"            android:textSize="20sp" />        <TextView            android:id="@+id/back_right_tv_delete"            android:layout_width="84dp"            android:layout_height="match_parent"            android:background="@android:color/holo_red_dark"            android:gravity="center"            android:text="Delete"            android:textColor="@android:color/white"            android:textSize="20sp" />    </LinearLayout>    <!--2   前布局 content-->    <TextView        android:id="@+id/front_tv_content"        android:layout_width="match_parent"        android:layout_gravity="center"        android:gravity="center"        android:layout_height="match_parent"        android:background="#666666" /></www.weshared.qqcehua.SwipeLayout>

在MainActivity中

public class MainActivity extends AppCompatActivity {    private SwipeLayout mSwipeLayout;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        init();    }    private void init() {        mSwipeLayout = (SwipeLayout) findViewById(R.id.swipelayout);        mSwipeLayout.setOnClickListener(new SwipeLayout.OnClickListener() {            @Override            public void onClick(View view) {                switch (view.getId()) {                    case R.id.back_left_tv_mark:                        toast("mark");                        break;                    case R.id.front_tv_content:                        toast("content");                        break;                    case R.id.back_right_tv_call:                        toast("call");                        break;                    case R.id.back_right_tv_delete:                        toast("delete");                        break;                }            }        });    }    public void toast(String message) {        Toast toast = Toast.makeText(this, "", Toast.LENGTH_SHORT);        if (!TextUtils.isEmpty(message) && toast != null) {            toast.setText(message);            toast.show();        }    }}

自定义SwipeLayout控件

public class SwipeLayout extends FrameLayout {    private View mBackLeftView;    private ViewGroup mBackRightView;    private View mFrontView;    private int mWidth;    private int mHeight;    private int mLeftRange;    private int mRightRange;    private int status;    public final int NORMAL = 0;//关闭状态    public final int LEFT_OPEN = 1;//左边打开状态    public final int RIGHT_OPEN = 2;//右边打开状态    public final int LEFT_OPENING = 3;//左边正打开状态    public final int LEFT_CLOSING = 4;//左边正关闭状态    public final int RIGHT_OPENING = 5;//右边正打开状态    public final int RIGHT_CLOSING = 6;//右边正关闭状态    private ViewDragHelper mViewDrawHelper;    private final int V = 300;//限制速度    private OnSwipeListener mOnSwipeListener;    private OnClickListener mOnClickListener;    private View mBackRightCall;    private View mBackRightDelete;    private int x;    private boolean isClick;    private final int DX = 10;    public interface OnSwipeListener {        void onLeftOpen(SwipeLayout swipeLayout);        void onLeftClose(SwipeLayout swipeLayout);        void onRightOpen(SwipeLayout swipeLayout);        void onRightClose(SwipeLayout swipeLayout);    }    public interface OnClickListener {        void onClick(View view);    }    public SwipeLayout(Context context) {        super(context);        init();    }    public SwipeLayout(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public SwipeLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    public SwipeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        init();    }    private void init() {        status = NORMAL;//默认是NORMAL        mViewDrawHelper = ViewDragHelper.create(this, callback);    }    public void setOnSwipeListener(OnSwipeListener mOnSwipeListener) {        this.mOnSwipeListener = mOnSwipeListener;    }    public void setOnClickListener(OnClickListener mOnClickListener) {        this.mOnClickListener = mOnClickListener;    }    private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {        /**是否试图拖拽子view*/        @Override        public boolean tryCaptureView(View child, int pointerId) {            if (child == mBackLeftView) {                return false;            }            return true;        }        /** 水平方向上的限制*/        @Override        public int clampViewPositionHorizontal(View child, int left, int dx) {            if (child == mFrontView) {                if (left < -mRightRange) {                    left = -mRightRange;                } else if (left > mLeftRange) {                    left = mLeftRange;                }            } else if (child == mBackRightView) {                if (left < mWidth - mRightRange) {                    left = mWidth - mRightRange;                } else if (left > mWidth) {                    left = mWidth;                }            }            return left;        }        /**这是系统定义的状态*/        @Override        public void onViewDragStateChanged(int state) {            super.onViewDragStateChanged(state);            if (state == ViewDragHelper.STATE_IDLE) {//ViewDrawHelper处于空闲状态            } else if (state == ViewDragHelper.STATE_DRAGGING) {//ViewDrawHelper处于正在拖拽状态                //拖拽状态,可设置滑动事件            } else if (state == ViewDragHelper.STATE_SETTLING) {//ViewDrawHelper处于飞翔状态                //飞翔状态设置,可设置滚动事件            }        }        @Override        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {            super.onViewPositionChanged(changedView, left, top, dx, dy);            if (mFrontView == changedView) {                mBackRightView.offsetLeftAndRight(dx);            } else if (mBackRightView == changedView) {                mFrontView.offsetLeftAndRight(dx);            }            status = updateStatus();//更新控件的状态            invalidate();//重绘界面        }        @Override        public void onViewReleased(View releasedChild, float xvel, float yvel) {            super.onViewReleased(releasedChild, xvel, yvel);            int left = mFrontView.getLeft();            if (left < -mRightRange * 0.5f) {                if (xvel > V) {                    normalClose();                } else {                    rightOpen();                }            } else if (left >= -mRightRange * 0.5f && left <= 0) {                if (xvel < -V) {//向左滑动                    rightOpen();//打开右边前布局                } else {                    normalClose();                }            } else if (left > 0 && left <= mLeftRange * 0.5f) {                if (xvel > V) {                    leftOpen();                } else {                    normalClose();                }            } else if (left > mLeftRange * 0.5f && left <= mLeftRange) {                if (xvel < -V) {//向左滑动                    normalClose();                } else {                    leftOpen();                }            }        }    };    public void dispatchClickListener() {        //设置点击事件        if (status == LEFT_OPEN) {            //mark的点击事件和Content点击事件            if (mOnClickListener != null) {                if (x > 0 && x < mLeftRange) {                    mOnClickListener.onClick(mBackLeftView);                }            }        } else if (status == RIGHT_OPEN) {            //call 和 Delete的点击事件 和Content点击事件            if (mOnClickListener != null) {                if (x > mWidth - mRightRange && x < mWidth - mRightRange * 0.5f) {                    mOnClickListener.onClick(mBackRightCall);                } else if (x >= mWidth - mRightRange * 0.5f && x <= mWidth) {                    mOnClickListener.onClick(mBackRightDelete);                }            }        } else if (status == NORMAL) {            //content的点击事件            if (mOnClickListener != null) {                mOnClickListener.onClick(mFrontView);            }        }    }    private int updateStatus() {        int left = mFrontView.getLeft();        if (left == -mRightRange) {            status = RIGHT_OPEN;        } else if (left == 0) {            status = NORMAL;        } else if (left == mLeftRange) {            status = LEFT_OPEN;        }        return status;    }    public void leftOpen() {        leftOpen(true);    }    public void leftOpen(boolean isSmooth) {        int finalLeft = mLeftRange;        int finalTop = 0;        if (isSmooth) {            if (mViewDrawHelper.smoothSlideViewTo(mFrontView, finalLeft, finalTop)) {                ViewCompat.postInvalidateOnAnimation(this);            }        } else {            layoutContent(LEFT_OPEN);        }    }    public void normalClose() {        normalClose(true);    }    public void normalClose(boolean isSmooth) {        int finalLeft = 0;        int finalTop = 0;        if (isSmooth) {            if (mViewDrawHelper.smoothSlideViewTo(mFrontView, finalLeft, finalTop)) {                ViewCompat.postInvalidateOnAnimation(this);            }        } else {            layoutContent(NORMAL);        }    }    public void rightOpen() {        rightOpen(true);    }    public void rightOpen(boolean isSmooth) {        int finalLeft = -mRightRange;        int finalTop = 0;        if (isSmooth) {            if (mViewDrawHelper.smoothSlideViewTo(mFrontView, finalLeft, finalTop)) {                ViewCompat.postInvalidateOnAnimation(this);            }        } else {            layoutContent(RIGHT_OPEN);        }    }    @Override    public void computeScroll() {        super.computeScroll();        if (mViewDrawHelper.continueSettling(true)) {            ViewCompat.postInvalidateOnAnimation(this);        }    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        return mViewDrawHelper.shouldInterceptTouchEvent(ev);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        dispatchOnTouchEvent(event);//分发触摸的事件        try {            mViewDrawHelper.processTouchEvent(event);//将触摸事件传递给ViewDrawHelper        } catch (Exception e) {        }        return true;    }    public void dispatchOnTouchEvent(MotionEvent event) {        if (event.getAction() == MotionEvent.ACTION_DOWN) {            x = (int) event.getX();            isClick = true;        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {            int movex = (int) event.getX();            if (Math.abs(movex - x) > DX) {//防止点击事件,会稍微手指抖动                isClick = false;            }        } else if (event.getAction() == MotionEvent.ACTION_UP) {            if (isClick) {                dispatchClickListener();            }        }    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        //获取控件中的子控件        mBackLeftView = getChildAt(0);        mBackRightView = (ViewGroup) getChildAt(1);        mFrontView = getChildAt(2);        mBackRightCall = mBackRightView.getChildAt(0);        mBackRightDelete = mBackRightView.getChildAt(1);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();        mLeftRange = mBackLeftView.getMeasuredWidth();        mRightRange = mBackRightView.getMeasuredWidth();    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);        //摆放布局        layoutContent(NORMAL);    }    public void layoutContent(int status) {        Rect frontRect = computeFrontRect(status);//根据状态,摆放前布局        mFrontView.layout(frontRect.left, frontRect.top, frontRect.right, frontRect.bottom);        Rect rightBackRect = computeRightBackRect(frontRect);//根据前布局,摆放右边后布局        mBackRightView.layout(rightBackRect.left, rightBackRect.top, rightBackRect.right, rightBackRect.bottom);    }    public Rect computeFrontRect(int status) {        int left = 0;        int top = 0;        if (status == LEFT_OPEN) {            left = mLeftRange;        } else if (status == RIGHT_OPEN) {            left = -mRightRange;        }        return new Rect(left, top, left + mWidth, top + mHeight);    }    public Rect computeRightBackRect(Rect frontRect) {        int left = 0;        int top = 0;        if (frontRect != null) {            left = frontRect.right;        }        return new Rect(left, top, left + mRightRange, top + mHeight);    }}

现在控件耦合程度太高,以后慢慢优化,写成一个库。

0 0
原创粉丝点击