Android使用ViewDragHelper实现简单的view拖拽和吸边功能

本文深入探讨了安卓ViewDragHelper的使用方法,包括其创建步骤、核心回调方法及其实现细节。通过实例代码展示了如何利用ViewDragHelper实现自定义View的拖拽效果,包括拖拽范围限制、拖拽过程中视图的位置约束以及释放后的平滑过渡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工作了几年,最开始做的是安卓开发,后面的做了一段时间逆向和sdk开发,一直没有系统的整理自己的知识,打算从本篇博客开始,陆续复习并记录一下自己的安卓知识

一直不知道怎么排版,先凑合着弄下

实现效果,gif上传被压扁了

实现效果

 

ViewDragHelper的用法

viewDragHelper是一个安卓自带的处理拖拽的工具

先看一下viewDragHelper的创建步骤

 public static ViewDragHelper create(@NonNull ViewGroup forParent, @NonNull ViewDragHelper.Callback cb)

ViewGroup传的就是需要操作的View容器,一般我们把代码写在自定义View内,这里也就直接传this

ViewDragHelper.Callback 这个是处理拖动逻辑的核心模块,具体的方法有

public boolean tryCaptureView(@NonNull View view, int i)

这是判定规则,只有return true的时候才会去执行后续的拖动操作

这里的view是容器内被touch到的字view,只有这个view和我们需要拖动的view为同一个的时候我们才认为是匹配的

也就是 return  myView == view;

public int getViewHorizontalDragRange(@NonNull View child);

public int getViewVerticalDragRange(@NonNull View child);

容器内可以拖动的区间,只有大于0的时候才可以执行相应方向的操作,一般没有特殊要求,我们会把这个返回值设为当期容器的宽和高

 public int clampViewPositionHorizontal(@NonNull View child, int left, int dx);

 public int clampViewPositionVertical(@NonNull View child, int top, int dy);

这个返回的是被操作的view在横向或纵向所能滑出的最大距离,或者说,在x或y方向的最左或最右,最上或最下所能达到的位置,这个可以有正负,比如x方向负就直接超出左边屏幕了哈

 public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel);

这个是view被释放时候执行的操作,我们可以操作view回到指定的位置或者保持不变等

在介绍ViewDragHelper的部分方法

public boolean settleCapturedViewAt(int finalLeft, int finalTop)

把我们所操作的view平滑的滑动到指定的位置

public boolean smoothSlideViewTo(@NonNull View child, int finalLeft, int finalTop)

和上面的settleCapturedViewAt效果类似,这个可以传被滑动的指定view

但是单纯用这两个方法会发现view并没有变动,这就需要搭配下面的方法一起使用

public boolean continueSettling(boolean deferCallbacks);

public boolean shouldInterceptTouchEvent(@NonNull MotionEvent ev);

public void processTouchEvent(@NonNull MotionEvent ev);

拖动处理三件套,需要让viewDragHelper处理手势和scroller圆滑过渡

实现

首先我们定义一些扩展的变量

private View dragView;                //被拖拽的view
private ViewDragHelper viewDragHelper;
private int mWidth;                 //容器的宽度
private int mHeight;                //容器的高度
private int mChildWidth;            //拖拽的View宽度
private int mChildHeight;           //拖拽的View高度
private boolean onDrag = true;      //是否正在被拖拽
private boolean dragEnable = true;  //是否是可以拖拽的
private boolean sideEnable = true;  //是否吸边

private final int NONE = -1;

private int topFinalOffset;        //拖拽超出上边界后,释放后回到的top位置
private int bottomFinalOffset;     //拖拽超出下边界后,释放后回到的bottom位置
private int leftFinalOffset;       //拖拽超出左边界后,释放后回到的left位置
private int rightFinalOffset;      //拖拽超出右边界后,释放后回到的right位置
    
private int leftDragOffset = NONE;            //能向左拖拽的最大距离
private int rightDragOffset = NONE;            //能向右拖拽的最大距离
private int topDragOffset = NONE;             //能向上拖拽的最大距离
private int bottomDragOffset = NONE;             //能向下拖拽的最大距离

先初始化并获取一些参数

private void init() {
        viewDragHelper = ViewDragHelper.create(this, new MyDragCallBack());
}

 @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        //获取装载容器的宽高以及拖拽view的宽高
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        mChildHeight = dragView.getMeasuredHeight();
        mChildWidth = dragView.getMeasuredWidth();

        //默认最多可以拖拽1/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值