类似滴滴打车司机端滑动开始接单SlideView

开局一张图,先看看是不是想要的效果

没错,今天就要实现这种效果,首先,可以看出来,这个效果是由两部分组成的,滑动的view以及背景view.重点就是滑动的View,并且分两种情况,当滑动距离超过一半时,则顺势滑下去,没有超过一半,则回弹到初始位置。

对于View跟随手势去滑动,当然是ViewDragHelper是比较合适的。我对这个类我也是第一次用,里面还有很多东西没有理解,只是简单的去运用。主要是自定义View继承自LinearLayout.

贴代码,不多BB,看会应该都能懂。

public class SlideRightViewDragHelper extends LinearLayout {

    private ViewDragHelper viewDragHelper;
    private View child;
    private Point childPosition = new Point();
    private Point childEndPosition = new Point();
    private OnReleasedListener onReleasedListener;
    private int oldX;


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

    public void setTouchable(boolean isTouch) {
        if (isTouch) {
            //新建viewDragHelper ,viewGroup, 灵敏度,回调(子view的移动)
            viewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
                @Override
                public boolean tryCaptureView(View child, int pointerId) {
                    oldX = 0;
                    return true;
                }

                @Override
                public int clampViewPositionHorizontal(View child, int left, int dx) {
                    oldX = left;
                    return Math.max(0, left);
                }

                @Override
                public void onViewReleased(View releasedChild, float xvel, float yvel) {
                    if (oldX > getWidth() / 2) {
/*
 *之所以没这么写,是因为在滑到最右边之后,滑动的View就会被释放,我通过layout方法无法将view设置
 *为复原,然后我必须又要把view在移回最左边,但无法实现向右顺势滑动的效果,反正达不到预期的效果,
 *后来就自己写了个位移动画,最终实现了想要的效果。
*/
//                        viewDragHelper.settleCapturedViewAt(childEndPosition.x, childEndPosition.y);
//                        invalidate(); //必须刷新,因为其内部使用的是mScroller.startScroll,所以别忘了需要invalidate()以及结合computeScroll方法一起。
//                        if (onReleasedListener != null) {
//                            child.layout(childPosition.x, childPosition.y, getWidth(), getHeight());
//                            viewDragHelper.settleCapturedViewAt(childPosition.x, childPosition.y); //反弹
//                            onReleasedListener.onReleased();
//                        }
                         TranslateAnimation translateAnimation = 
new TranslateAnimation(0, childEndPosition.x, childPosition.y, childPosition.y);
                        translateAnimation.setDuration(300);
                        child.startAnimation(translateAnimation);
                        translateAnimation.setAnimationListener(new Animation.AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {

                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                Handler handler = new Handler();
                                handler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        onReleasedListener.onReleased(0, 0, getWidth(), getHeight());
                                    }
                                }, 10);

                            }

                            @Override
                            public void onAnimationRepeat(Animation animation) {

                            }
                        });
                    } else {//滑动距离不够一半,回到初始位置
                        viewDragHelper.settleCapturedViewAt(childPosition.x, childPosition.y); //反弹
                        invalidate();//必须调用
                    }


                    super.onViewReleased(releasedChild, xvel, yvel);
                }

                @Override
                public void onViewCaptured(View capturedChild, int activePointerId) {
                    super.onViewCaptured(capturedChild, activePointerId);
                }


                @Override
                public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
                    super.onViewPositionChanged(changedView, left, top, dx, dy);
                }

            });
        } else {
            viewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
                @Override
                public boolean tryCaptureView(View child, int pointerId) {
                    return false;
                }
            });
        }
    }


    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        child = getChildAt(0);
    }

    @Override   //用viewDragHelper拦截-true
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return viewDragHelper.shouldInterceptTouchEvent(ev);
    }


    @Override  //viewDragHelper拦截事件
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        //定位左侧的坐标
        childPosition.x = child.getLeft();
        childPosition.y = child.getTop();

        //定位右侧的坐标
        childEndPosition.x = child.getRight();
        childEndPosition.y = child.getTop();
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (viewDragHelper.continueSettling(true)) {
            invalidate();
        }
    }

    public void setOnReleasedListener(OnReleasedListener onReleasedListener) {
        this.onReleasedListener = onReleasedListener;
    }

    public interface OnReleasedListener {
        void onReleased(int left, int top, int right, int bottom);
    }
}

主要重写了ViewDragHelper的三个方法

tryCaptureView()试图要捕捉的View 当返回true时,可对当前View进行操作,返回false,则不可操作

clampViewPositionHorizontal()  在水平滑动过程中,可以得到当前View的left值

onViewReleased() 当手指抬起的时候回走这个方法,但我总觉得当我滑到最右边的时候,就会把我的View给释放掉,这个方法还不是很懂

当View滑动到最右边时,就会通过接口告知Activity当前view已经滑到最右边,实现这个接口,并作出对应的操作。

dragHelper.setOnReleasedListener(new SlideRightViewDragHelper.OnReleasedListener() {
            @Override
            public void onReleased(final int left, final int top, final int right, final int bottom) {
                //自己的操作
            }
});

把所有代码都贴一下

布局代码

 

<RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true">

        <Button
            android:id="@+id/slide_view_bt"
            android:layout_width="@dimen/x80"
            android:layout_height="@dimen/x60"
            android:text="上线" />


        <com.gengchao.test_slideView.SlideRightViewDragHelper
            android:id="@+id/slide_view_drag_helper"
            android:layout_width="match_parent"
            android:layout_height="@dimen/x60"
            android:layout_marginRight="@dimen/x10"
            android:layout_toRightOf="@+id/slide_view_bt"
            android:background="@color/colorPrimary"
            android:orientation="horizontal">

            <LinearLayout
                android:id="@+id/slide_view_ll"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/gray"
                android:orientation="horizontal">

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="20dp"
                    android:src="@mipmap/ic_launcher"
                    android:visibility="gone" />

                <TextView
                    android:id="@+id/slide_view_tv"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginLeft="10dp"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:text=">>滑动开始听单"
                    android:textColor="@color/white"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/get_order_tv_left_time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_marginRight="15dp"
                    android:text="确认(30s)"
                    android:textColor="@color/white"
                    android:textStyle="bold"
                    android:visibility="gone" />

            </LinearLayout>

        </com.gengchao.test_slideView.SlideRightViewDragHelper>
</RelativeLayout>

Activity代码

public class SlideViewActivity extends AppCompatActivity implements View.OnClickListener {
    SlideRightViewDragHelper dragHelper;
    LinearLayout llSlideBg;
    TextView tv;
    Button bt;

    boolean onLine = false;//false为离线  true为在线
    boolean orderState = false; //false为未接单  true为接单

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_slide_view);
        initView();
        dragHelper.setOnReleasedListener(new SlideRightViewDragHelper.OnReleasedListener() {
            @Override
            public void onReleased(final int left, final int top, final int right, final int bottom) {
                if (orderState == true) {//可接单状态——>不可接单状态
                    orderState = !orderState;
                    llSlideBg.setBackgroundColor(getResources().getColor(R.color.red));
                } else {//不可接单状态——>可接单状态
                    orderState = !orderState;
                    llSlideBg.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                }
                tv.setText(orderState == true ? ">>滑动结束听单" : ">>滑动开始听单");
                dragHelper.setBackgroundColor(orderState == true ? getResources().getColor(R.color.red) : getResources().getColor(R.color.colorPrimary));
                llSlideBg.layout(left, top, right, bottom);
            }
        });
    }

    private void initView() {
        llSlideBg = findViewById(R.id.slide_view_ll);
        tv = findViewById(R.id.slide_view_tv);
        bt = findViewById(R.id.slide_view_bt);
        dragHelper = findViewById(R.id.slide_view_drag_helper);
        bt.setOnClickListener(this);
        dragHelper.setTouchable(false);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.slide_view_bt:
                if (onLine) {//当前为上线  去下线
                    onLine = !onLine;
                    llSlideBg.setBackgroundColor(getResources().getColor(R.color.gray));
                    dragHelper.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                    bt.setText("上线");
                    dragHelper.setTouchable(false);
                    tv.setText(">>滑动开始听单");
                    dragHelper.recovery(llSlideBg);
                } else {//当前为下线 去上线
                    onLine = !onLine;
                    llSlideBg.setBackgroundColor(getResources().getColor(R.color.red));
                    dragHelper.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                    bt.setText("下线");
                    dragHelper.setTouchable(true);
                }
                break;
        }
    }
}

 

到这里就结束了,这种功能也不是很难,前提是一定要多实践才行。加油

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值