吴小龙同學

Android之滑动view

效果预览

获取坐标值方法


如图,要实现滑动效果,需要先了解以下方法。

  • View提供获取坐标方法
    getTop():获取View自身顶边到其父布局顶边的距离
    getLeft():获取View自身左边到其父布局左边的距离
    getRight():获取View自身右边到其父布局右边的距离
    getBottom():获取View自身底边到其父布局底边的距离

  • MotionEvent提供的方法
    getX():获取点击点距离自身控件左边距离,即视图坐标
    getY():获取点击点距离自身控件顶边距离,即视图坐标
    getRawX():获取点击点距离整个屏幕左边距离,即绝对坐标
    getRawY():获取点击点距离整个屏幕顶边距离,即绝对坐标

实现DragView

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class DragView extends View {
private int x, y;
public DragView(Context context) {
super(context);
}
public DragView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int getX = (int) event.getX();
int getY = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 记录触摸点坐标
x = (int) event.getX();
y = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
//计算偏移量
int offsetX = getX - x;
int offsetY = getY - y;
//在当前left、top、right、bottom的基础上加上偏移量
layout(getLeft() + offsetX,
getTop() + offsetY,
getRight() + offsetX,
getBottom() + offsetY);
break;
}
return true;
}
}

方法二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class DragView extends View {
private int x, y;
//这里省略构造方法
@Override
public boolean onTouchEvent(MotionEvent event) {
int getX = (int) event.getX();
int getY = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 记录触摸点坐标
x = (int) event.getX();
y = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
//计算偏移量
int offsetX = getX - x;
int offsetY = getY - y;
offsetLeftAndRight(offsetX);//同时对left和right偏移
offsetTopAndBottom(offsetY);//同时对top和bottom偏移
break;
}
return true;
}
}

方法三

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
```java
public class DragView extends View {
private int x, y;
//这里省略构造方法
@Override
public boolean onTouchEvent(MotionEvent event) {
int getX = (int) event.getX();
int getY = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 记录触摸点坐标
x = (int) event.getX();
y = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
//计算偏移量
int offsetX = getX - x;
int offsetY = getY - y;
ViewGroup.MarginLayoutParams marginLayoutParams =
(ViewGroup.MarginLayoutParams) getLayoutParams();
marginLayoutParams.leftMargin = getLeft() + offsetX;
marginLayoutParams.topMargin = getTop() + offsetY;
setLayoutParams(marginLayoutParams);
break;
}
return true;
}
}

方法四

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class DragView extends View {
private int x, y;
private Scroller mScroller;
public DragView(Context context) {
super(context);
initScroller(context);
}
public DragView(Context context, AttributeSet attrs) {
super(context, attrs);
initScroller(context);
}
public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initScroller(context);
}
private void initScroller(Context context) {
setBackgroundColor(Color.RED);
mScroller = new Scroller(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int getRawX = (int) event.getRawX();
int getRawY = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 记录触摸点坐标
x = (int) event.getRawX();
y = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
//计算偏移量
int offsetX = getRawX - x;
int offsetY = getRawY - y;
((View) getParent()).scrollBy(-offsetX, -offsetY);
//重新设置初始坐标
x = getRawX;
y = getRawY;
break;
case MotionEvent.ACTION_UP:
/**
* 实现拖动回弹回去,需配合方法一、二、四中任一方法
*/
View viewGroup = (View) getParent();
mScroller.startScroll(viewGroup.getScrollX(),
viewGroup.getScrollY(),
-viewGroup.getScrollX(),
-viewGroup.getScrollY()
);
invalidate();
break;
}
return true;
}
@Override
public void computeScroll() {
super.computeScroll();
//判断Scroller是否执行完毕
if (mScroller.computeScrollOffset()) {
((View) getParent()).scrollTo(
mScroller.getCurrX(),
mScroller.getCurrY());
invalidate();
}
}
}

xml调用

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.wuxiaolong.apksample.DragView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@android:color/holo_red_light"/>
</LinearLayout>

方法五

属性动画

方法六

ViewDragHelper

以上内容来自《Android群英传》

剩者为王

我的Android技术交流群,群名寓意很简单,经过时间洗礼,最终剩下的才是王者,欢迎“剩友”。
剩者为王③群:370527306 剩者为王③群



联系我

我的微信公众号:吴小龙同学,欢迎关注交流~

赞助商:躲角落的猫咪