工作了几年,最开始做的是安卓开发,后面的做了一段时间逆向和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/