Android中常见的实现位移滑动效果的方式有:
layoutParam
offsetTopAndBottom\offsetLeftAndRight
layout
scrollTo/scrollBy
scroller
viewDragHelper
对于常见滑动效果通过两篇文章说明。本节将说明layout
\ offset
\ layoutParam
。

1、layout()方式实现位移滑动
public void layout(int l, int t, int r, int b)
看一下实现随手指移动核心代码
bindView {
var layoutLastX = 0
var layoutLastY = 0
var originLeft = 0
var originTop = 0
var originRight = 0
var originBottom = 0
vLayoutMove.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
layoutLastX = event.x.toInt()
layoutLastY = event.y.toInt()
originLeft = v.left
originTop = v.top
originRight = v.right
originBottom = v.bottom
}
MotionEvent.ACTION_MOVE -> {
val offsetX = event.x - layoutLastX
val offsetY = event.y - layoutLastY
v.layout(
(originLeft + offsetX).toInt(),
(originTop + offsetY).toInt(),
(originRight + offsetX).toInt(),
(originBottom + offsetY).toInt()
)
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
//将位置恢复到初始位置
v.layout(
originLeft, originTop, originRight, originBottom
)
}
}
true
}
2、offset方式实现位移滑动
public void offsetLeftAndRight(int offset)
public void offsetTopAndBottom(int offset)
由于比较简单,直接看核心代码实现
var offsetLastX = 0F
var offsetLastY = 0F
var offsetOriginX = 0F
var offsetOriginY = 0F
vOffsetMove.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
offsetLastX = event.x
offsetLastY = event.y
offsetOriginX = v.left.toFloat()
offsetOriginY = v.top.toFloat()
}
MotionEvent.ACTION_MOVE -> {
val offsetX = event.x - offsetLastX
val offsetY = event.y - offsetLastY
v.offsetLeftAndRight(offsetX.toInt())
v.offsetTopAndBottom(offsetY.toInt())
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
v.layout(
offsetOriginX.toInt(),
offsetOriginY.toInt(),
offsetOriginX.toInt() + v.width,
offsetOriginY.toInt() + v.height
)
}
}
true
}
3、layoutParam方式实现位移滑动
v.layoutParams = layoutParam
直接看核心代码
var paramLastX = 0F
var paramLastY = 0F
var paramOriginX = 0F
var paramOriginY = 0F
vLayoutParamMove.setOnTouchListener { v, event ->
val layoutParam: ViewGroup.MarginLayoutParams =
v.layoutParams as ViewGroup.MarginLayoutParams
when (event.action) {
MotionEvent.ACTION_DOWN -> {
paramLastX = event.x
paramLastY = event.y
paramOriginX = layoutParam.leftMargin.toFloat()
paramOriginY = layoutParam.topMargin.toFloat()
}
MotionEvent.ACTION_MOVE -> {
val offsetX = event.x - paramLastX
val offsetY = event.y - paramLastY
layoutParam.leftMargin = (layoutParam.leftMargin + offsetX).toInt()
layoutParam.topMargin = (layoutParam.topMargin + offsetY).toInt()
v.layoutParams = layoutParam
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
layoutParam.leftMargin = paramOriginX.toInt()
layoutParam.topMargin = paramOriginY.toInt()
v.layoutParams = layoutParam
}
}
true
}
}