android-做一个简单的左滑删除控件


import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.support.v4.view.ViewConfigurationCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;

public class SwipeLayout extends ViewGroup{
    public static String TAG = "SwipeLayout";

    //可以滚动的距离
    int mSwipeWidth;


    PointF firstPoint;
    PointF lastPoint;

    float mTouchSlop;

    ValueAnimator openAnimator;
    ValueAnimator closeAnimator;

    public SwipeLayout(Context context) {
        this(context,null);
    }

    public SwipeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(ViewConfiguration.get(getContext()));
    }



    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left=0;
        int childCount = getChildCount();

        for (int i=0;i<childCount;++i){
            View child = getChildAt(i);

            //按顺序从左往右排
//            if (i==0){
//                child.layout(0,0,child.getMeasuredWidth(),child.getMeasuredHeight());
//            }else {
                child.layout(left,0,left+child.getMeasuredWidth(),child.getMeasuredHeight());
//            }
            left += child.getMeasuredWidth();
        }


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        View mainChild = getChildAt(0);
        int width=0;
        int height=0;
        mSwipeWidth = 0;
//        measureChild(mainChild,widthMeasureSpec,heightMeasureSpec);
        measure(widthMeasureSpec,heightMeasureSpec);

        //滑动距离是 从index开始 所有控件的宽度之和
        if (childCount>1) {
            for (int i = 1; i < childCount; ++i) {
                mSwipeWidth += getChildAt(i).getMeasuredWidth();
            }
        }


        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthValue = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightValue = MeasureSpec.getSize(heightMeasureSpec);

        switch (heightMode){
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                //没有指定大小 按照第一个子控件的大小来设置
                height = mainChild.getMeasuredHeight();
                break;
            case MeasureSpec.EXACTLY:
                height = heightValue;
                break;
        }
        switch (widthMode){
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                //没有指定大小 按照第一个子控件的大小来设置
                width = mainChild.getMeasuredWidth();
                break;
            case MeasureSpec.EXACTLY:
                width = widthValue;
                break;
        }

//        for (int i=1;i<childCount;++i){
//            measureChild(getChildAt(i),widthMeasureSpec,MeasureSpec.makeMeasureSpec(height,MeasureSpec.EXACTLY));
//        }
        setMeasuredDimension(width,height);
    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
               switch (ev.getAction()){
           case MotionEvent.ACTION_DOWN:
               firstPoint = new PointF(ev.getX(),ev.getY());
               lastPoint = new PointF(ev.getX(),ev.getY());
               break;
           case MotionEvent.ACTION_MOVE:
               float moveDistance = ev.getX()-firstPoint.x;

               //移动距离大于制定值   认为进入控件的滑动模式
                if (Math.abs(moveDistance) > mTouchSlop ){
                    //让父控件不拦截我们的事件
                    getParent().requestDisallowInterceptTouchEvent(true);
                    //拦截事件
                    return true;
                }

       }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_MOVE:
                float moveDistance = ev.getX()-lastPoint.x;
                lastPoint = new PointF(ev.getX(),ev.getY());

                // 这里要注意   x大于0的时候 往左滑动  小于0往右滑动
                scrollBy((int) -moveDistance ,0);

                //边界判定 超过了边界  直接设置为边界值
                if (getScrollX()> mSwipeWidth){
                    scrollTo(mSwipeWidth,0);
                }else if (getScrollX()<0){
                    scrollTo(0,0);
                }
                break;
            case MotionEvent.ACTION_UP:
                //没动 不理他
                if (getScrollX()== mSwipeWidth ||getScrollX()==0){
                    return false;
                }
                    float distance = ev.getX()-firstPoint.x;
                //滑动距离超过 可滑动距离指定值 继续完成滑动
                    if (Math.abs(distance) > mSwipeWidth *0.3 ){
                        if (distance>0){
                            smoothClose();
                        }else if (distance<0){
                            smoothOpen();
                        }
                    }else  {
                        if (distance>0){
                            smoothOpen();

                        }else if (distance<0){
                            smoothClose();
                        }
                    }
                    return true;
        }

        return super.onTouchEvent(ev);
    }

    public void smoothOpen(){

        clearAnimator();
        openAnimator = ValueAnimator.ofInt(getScrollX(), mSwipeWidth);
        openAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer integer = (Integer) animation.getAnimatedValue();
                scrollTo(integer,0);
            }
        });
        openAnimator.start();
    }
    public void smoothClose(){
        clearAnimator();
        closeAnimator = ValueAnimator.ofInt(getScrollX(),0);
        closeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer integer = (Integer) animation.getAnimatedValue();
                scrollTo(integer,0);
            }
        });
        closeAnimator.start();

    }

    public void open(){
        scrollTo(mSwipeWidth,0);
    }
    public void close(){
        scrollTo(0,0);

    }
//执行滑动动画必须先清除动画  不然会鬼畜
    private void clearAnimator(){
        if (closeAnimator!=null && closeAnimator.isRunning()){
            closeAnimator.cancel();
            closeAnimator = null;
        }
        if (openAnimator!=null && openAnimator.isRunning()) {
            openAnimator.cancel();
            openAnimator = null;
        }
    }

    public void toggle(){
        if (getScrollX()==0){
            open();
        }else {
            close();
        }
    }

}

使用

            <com.example.chenweiqi.simplerefreshview.widget.SwipeLayout
                android:id="@+id/swipeLayout"
                android:layout_width="200dp"
                android:layout_height="wrap_content"
                android:background="#F3F3F3"
                >
                <Button
                    android:id="@+id/btn"
                    android:text="123"
                    android:layout_width="match_parent"
                    android:layout_height="50dp" />

                <Button
                    android:background="#FF0000"
                    android:text="shanchu"
                    android:layout_width="80dp"
                    android:layout_height="match_parent" />
                <TextView
                    android:gravity="center"
                    android:textAlignment="center"
                    android:background="#0F0"
                    android:text="123"
                    android:layout_width="30dp"
                    android:layout_height="match_parent" />
            </com.example.chenweiqi.simplerefreshview.widget.SwipeLayout>

效果

猜你喜欢

转载自blog.csdn.net/qq_20352713/article/details/85063628